annotate DEPENDENCIES/generic/include/boost/interprocess/detail/intersegment_ptr.hpp @ 125:34e428693f5d vext

Vext -> Repoint
author Chris Cannam
date Thu, 14 Jun 2018 11:15:39 +0100
parents c530137014c0
children
rev   line source
Chris@16 1 //////////////////////////////////////////////////////////////////////////////
Chris@16 2 //
Chris@16 3 // (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
Chris@16 4 // Software License, Version 1.0. (See accompanying file
Chris@16 5 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
Chris@16 6 //
Chris@16 7 // See http://www.boost.org/libs/interprocess for documentation.
Chris@16 8 //
Chris@16 9 //////////////////////////////////////////////////////////////////////////////
Chris@16 10
Chris@16 11 #ifndef BOOST_INTERPROCESS_INTERSEGMENT_PTR_HPP
Chris@16 12 #define BOOST_INTERPROCESS_INTERSEGMENT_PTR_HPP
Chris@16 13
Chris@101 14 #ifndef BOOST_CONFIG_HPP
Chris@101 15 # include <boost/config.hpp>
Chris@101 16 #endif
Chris@101 17 #
Chris@101 18 #if defined(BOOST_HAS_PRAGMA_ONCE)
Chris@16 19 # pragma once
Chris@16 20 #endif
Chris@16 21
Chris@16 22 #include <boost/interprocess/detail/config_begin.hpp>
Chris@16 23 #include <boost/interprocess/detail/workaround.hpp>
Chris@101 24 // interprocess
Chris@16 25 #include <boost/interprocess/interprocess_fwd.hpp>
Chris@16 26 #include <boost/interprocess/sync/scoped_lock.hpp>
Chris@16 27 #include <boost/interprocess/sync/interprocess_mutex.hpp>
Chris@16 28 #include <boost/interprocess/containers/flat_map.hpp>
Chris@16 29 #include <boost/interprocess/containers/vector.hpp> //vector
Chris@16 30 #include <boost/interprocess/containers/set.hpp> //set
Chris@101 31 // interprocess/detail
Chris@101 32 #include <boost/interprocess/detail/multi_segment_services.hpp>
Chris@101 33 #include <boost/interprocess/detail/utilities.hpp>
Chris@101 34 #include <boost/interprocess/detail/math_functions.hpp>
Chris@101 35 #include <boost/interprocess/detail/cast_tags.hpp>
Chris@16 36 #include <boost/interprocess/detail/mpl.hpp>
Chris@101 37 // other boost
Chris@101 38 #include <boost/core/no_exceptions_support.hpp>
Chris@16 39 #include <boost/static_assert.hpp> //BOOST_STATIC_ASSERT
Chris@16 40 #include <boost/integer/static_log2.hpp>
Chris@16 41 #include <boost/assert.hpp> //BOOST_ASSERT
Chris@101 42 // std
Chris@101 43 #include <climits> //CHAR_BIT
Chris@16 44
Chris@16 45 //!\file
Chris@16 46 //!
Chris@16 47 namespace boost {
Chris@16 48
Chris@16 49 //Predeclarations
Chris@16 50 template <class T>
Chris@16 51 struct has_trivial_constructor;
Chris@16 52
Chris@16 53 template <class T>
Chris@16 54 struct has_trivial_destructor;
Chris@16 55
Chris@16 56 namespace interprocess {
Chris@16 57
Chris@16 58 template <class T>
Chris@16 59 struct is_multisegment_ptr;
Chris@16 60
Chris@16 61 struct intersegment_base
Chris@16 62 {
Chris@16 63 typedef intersegment_base self_t;
Chris@16 64 BOOST_STATIC_ASSERT((sizeof(std::size_t) == sizeof(void*)));
Chris@16 65 BOOST_STATIC_ASSERT((sizeof(void*)*CHAR_BIT == 32 || sizeof(void*)*CHAR_BIT == 64));
Chris@16 66 static const std::size_t size_t_bits = (sizeof(void*)*CHAR_BIT == 32) ? 32 : 64;
Chris@16 67 static const std::size_t ctrl_bits = 2;
Chris@16 68 static const std::size_t align_bits = 12;
Chris@16 69 static const std::size_t align = std::size_t(1) << align_bits;
Chris@16 70 static const std::size_t max_segment_size_bits = size_t_bits - 2;
Chris@16 71 static const std::size_t max_segment_size = std::size_t(1) << max_segment_size_bits;
Chris@16 72
Chris@16 73 static const std::size_t begin_bits = max_segment_size_bits - align_bits;
Chris@16 74 static const std::size_t pow_size_bits_helper = static_log2<max_segment_size_bits>::value;
Chris@16 75 static const std::size_t pow_size_bits =
Chris@16 76 (max_segment_size_bits == (std::size_t(1) << pow_size_bits_helper)) ?
Chris@16 77 pow_size_bits_helper : pow_size_bits_helper + 1;
Chris@16 78 static const std::size_t frc_size_bits =
Chris@16 79 size_t_bits - ctrl_bits - begin_bits - pow_size_bits;
Chris@16 80
Chris@16 81 BOOST_STATIC_ASSERT(((size_t_bits - pow_size_bits - frc_size_bits) >= ctrl_bits ));
Chris@16 82
Chris@16 83 static const std::size_t relative_size_bits =
Chris@16 84 size_t_bits - max_segment_size_bits - ctrl_bits;
Chris@16 85
Chris@16 86 static const std::size_t is_pointee_outside = 0;
Chris@16 87 static const std::size_t is_in_stack = 1;
Chris@16 88 static const std::size_t is_relative = 2;
Chris@16 89 static const std::size_t is_segmented = 3;
Chris@16 90 static const std::size_t is_max_mode = 4;
Chris@16 91
Chris@16 92 intersegment_base()
Chris@16 93 {
Chris@16 94 this->set_mode(is_pointee_outside);
Chris@16 95 this->set_null();
Chris@16 96 }
Chris@16 97
Chris@16 98 struct relative_addressing
Chris@16 99 {
Chris@16 100 std::size_t ctrl : 2;
Chris@16 101 std::size_t pow : pow_size_bits;
Chris@16 102 std::size_t frc : frc_size_bits;
Chris@16 103 std::size_t beg : begin_bits;
Chris@16 104 std::ptrdiff_t off : sizeof(std::ptrdiff_t)*CHAR_BIT - 2;
Chris@16 105 std::ptrdiff_t bits : 2;
Chris@16 106 };
Chris@16 107
Chris@16 108 struct direct_addressing
Chris@16 109 {
Chris@16 110 std::size_t ctrl : 2;
Chris@16 111 std::size_t dummy : sizeof(std::size_t)*CHAR_BIT - 2;
Chris@16 112 void * addr;
Chris@16 113 };
Chris@16 114
Chris@16 115 struct segmented_addressing
Chris@16 116 {
Chris@16 117 std::size_t ctrl : 2;
Chris@16 118 std::size_t segment : sizeof(std::size_t)*CHAR_BIT - 2;
Chris@16 119 std::size_t off : sizeof(std::size_t)*CHAR_BIT - 2;
Chris@16 120 std::size_t bits : 2;
Chris@16 121 };
Chris@16 122
Chris@16 123 union members_t{
Chris@16 124 relative_addressing relative;
Chris@16 125 direct_addressing direct;
Chris@16 126 segmented_addressing segmented;
Chris@16 127 } members;
Chris@16 128
Chris@16 129 BOOST_STATIC_ASSERT(sizeof(members_t) == 2*sizeof(std::size_t));
Chris@16 130
Chris@16 131 void *relative_calculate_begin_addr() const
Chris@16 132 {
Chris@16 133 const std::size_t mask = ~(align - 1);
Chris@16 134 std::size_t beg = this->members.relative.beg;
Chris@16 135 return reinterpret_cast<void*>((((std::size_t)this) & mask) - (beg << align_bits));
Chris@16 136 }
Chris@16 137
Chris@16 138 void relative_set_begin_from_base(void *addr)
Chris@16 139 {
Chris@16 140 BOOST_ASSERT(addr < static_cast<void*>(this));
Chris@16 141 std::size_t off = reinterpret_cast<char*>(this) - reinterpret_cast<char*>(addr);
Chris@16 142 members.relative.beg = off >> align_bits;
Chris@16 143 }
Chris@16 144
Chris@16 145 //!Obtains the address pointed by the
Chris@16 146 //!object
Chris@16 147 std::size_t relative_size() const
Chris@16 148 {
Chris@16 149 std::size_t pow = members.relative.pow;
Chris@16 150 std::size_t size = (std::size_t(1u) << pow);
Chris@16 151 BOOST_ASSERT(pow >= frc_size_bits);
Chris@16 152 size |= members.relative.frc << (pow - frc_size_bits);
Chris@16 153 return size;
Chris@16 154 }
Chris@16 155
Chris@16 156 static std::size_t calculate_size(std::size_t orig_size, std::size_t &pow, std::size_t &frc)
Chris@16 157 {
Chris@16 158 if(orig_size < align)
Chris@16 159 orig_size = align;
Chris@16 160 orig_size = ipcdetail::get_rounded_size_po2(orig_size, align);
Chris@16 161 pow = ipcdetail::floor_log2(orig_size);
Chris@16 162 std::size_t low_size = (std::size_t(1) << pow);
Chris@16 163 std::size_t diff = orig_size - low_size;
Chris@16 164 BOOST_ASSERT(pow >= frc_size_bits);
Chris@16 165 std::size_t rounded = ipcdetail::get_rounded_size_po2
Chris@16 166 (diff, (std::size_t)(1u << (pow - frc_size_bits)));
Chris@16 167 if(rounded == low_size){
Chris@16 168 ++pow;
Chris@16 169 frc = 0;
Chris@16 170 rounded = 0;
Chris@16 171 }
Chris@16 172 else{
Chris@16 173 frc = rounded >> (pow - frc_size_bits);
Chris@16 174 }
Chris@16 175 BOOST_ASSERT(((frc << (pow - frc_size_bits)) & (align-1))==0);
Chris@16 176 return low_size + rounded;
Chris@16 177 }
Chris@16 178
Chris@16 179 std::size_t get_mode()const
Chris@16 180 { return members.direct.ctrl; }
Chris@16 181
Chris@16 182 void set_mode(std::size_t mode)
Chris@16 183 {
Chris@16 184 BOOST_ASSERT(mode < is_max_mode);
Chris@16 185 members.direct.ctrl = mode;
Chris@16 186 }
Chris@16 187
Chris@16 188 //!Returns true if object represents
Chris@16 189 //!null pointer
Chris@16 190 bool is_null() const
Chris@16 191 {
Chris@16 192 return (this->get_mode() < is_relative) &&
Chris@16 193 !members.direct.dummy &&
Chris@16 194 !members.direct.addr;
Chris@16 195 }
Chris@16 196
Chris@16 197 //!Sets the object to represent
Chris@16 198 //!the null pointer
Chris@16 199 void set_null()
Chris@16 200 {
Chris@16 201 if(this->get_mode() >= is_relative){
Chris@16 202 this->set_mode(is_pointee_outside);
Chris@16 203 }
Chris@16 204 members.direct.dummy = 0;
Chris@16 205 members.direct.addr = 0;
Chris@16 206 }
Chris@16 207
Chris@16 208 static std::size_t round_size(std::size_t orig_size)
Chris@16 209 {
Chris@16 210 std::size_t pow, frc;
Chris@16 211 return calculate_size(orig_size, pow, frc);
Chris@16 212 }
Chris@16 213 };
Chris@16 214
Chris@16 215
Chris@16 216
Chris@16 217 //!Configures intersegment_ptr with the capability to address:
Chris@16 218 //!2^(sizeof(std::size_t)*CHAR_BIT/2) segment groups
Chris@16 219 //!2^(sizeof(std::size_t)*CHAR_BIT/2) segments per group.
Chris@16 220 //!2^(sizeof(std::size_t)*CHAR_BIT/2)-1 bytes maximum per segment.
Chris@16 221 //!The mapping is implemented through flat_maps synchronized with mutexes.
Chris@16 222 template <class Mutex>
Chris@16 223 struct flat_map_intersegment
Chris@16 224 : public intersegment_base
Chris@16 225 {
Chris@16 226 typedef flat_map_intersegment<Mutex> self_t;
Chris@16 227
Chris@16 228 void set_from_pointer(const volatile void *ptr)
Chris@16 229 { this->set_from_pointer(const_cast<const void *>(ptr)); }
Chris@16 230
Chris@16 231 //!Obtains the address pointed
Chris@16 232 //!by the object
Chris@16 233 void *to_raw_pointer() const
Chris@16 234 {
Chris@16 235 if(is_null()){
Chris@16 236 return 0;
Chris@16 237 }
Chris@16 238 switch(this->get_mode()){
Chris@16 239 case is_relative:
Chris@16 240 return const_cast<char*>(reinterpret_cast<const char*>(this)) + members.relative.off;
Chris@16 241 break;
Chris@16 242 case is_segmented:
Chris@16 243 {
Chris@16 244 segment_info_t segment_info;
Chris@16 245 std::size_t offset;
Chris@16 246 void *this_base;
Chris@16 247 get_segment_info_and_offset(this, segment_info, offset, this_base);
Chris@16 248 char *base = static_cast<char*>(segment_info.group->address_of(this->members.segmented.segment));
Chris@16 249 return base + this->members.segmented.off;
Chris@16 250 }
Chris@16 251 break;
Chris@16 252 case is_in_stack:
Chris@16 253 case is_pointee_outside:
Chris@16 254 return members.direct.addr;
Chris@16 255 break;
Chris@16 256 default:
Chris@16 257 return 0;
Chris@16 258 break;
Chris@16 259 }
Chris@16 260 }
Chris@16 261
Chris@16 262 //!Calculates the distance between two basic_intersegment_ptr-s.
Chris@16 263 //!This only works with two basic_intersegment_ptr pointing
Chris@16 264 //!to the same segment. Otherwise undefined
Chris@16 265 std::ptrdiff_t diff(const self_t &other) const
Chris@16 266 { return static_cast<char*>(this->to_raw_pointer()) - static_cast<char*>(other.to_raw_pointer()); }
Chris@16 267
Chris@16 268 //!Returns true if both point to
Chris@16 269 //!the same object
Chris@16 270 bool equal(const self_t &y) const
Chris@16 271 { return this->to_raw_pointer() == y.to_raw_pointer(); }
Chris@16 272
Chris@16 273 //!Returns true if *this is less than other.
Chris@16 274 //!This only works with two basic_intersegment_ptr pointing
Chris@16 275 //!to the same segment group. Otherwise undefined. Never throws
Chris@16 276 bool less(const self_t &y) const
Chris@16 277 { return this->to_raw_pointer() < y.to_raw_pointer(); }
Chris@16 278
Chris@16 279 void swap(self_t &other)
Chris@16 280 {
Chris@16 281 void *ptr_this = this->to_raw_pointer();
Chris@16 282 void *ptr_other = other.to_raw_pointer();
Chris@16 283 other.set_from_pointer(ptr_this);
Chris@16 284 this->set_from_pointer(ptr_other);
Chris@16 285 }
Chris@16 286
Chris@16 287 //!Sets the object internals to represent the
Chris@16 288 //!address pointed by ptr
Chris@16 289 void set_from_pointer(const void *ptr)
Chris@16 290 {
Chris@16 291 if(!ptr){
Chris@16 292 this->set_null();
Chris@16 293 return;
Chris@16 294 }
Chris@16 295
Chris@16 296 std::size_t mode = this->get_mode();
Chris@16 297 if(mode == is_in_stack){
Chris@16 298 members.direct.addr = const_cast<void*>(ptr);
Chris@16 299 return;
Chris@16 300 }
Chris@16 301 if(mode == is_relative){
Chris@16 302 char *beg_addr = static_cast<char*>(this->relative_calculate_begin_addr());
Chris@16 303 std::size_t seg_size = this->relative_size();
Chris@16 304 if(ptr >= beg_addr && ptr < (beg_addr + seg_size)){
Chris@16 305 members.relative.off = static_cast<const char*>(ptr) - reinterpret_cast<const char*>(this);
Chris@16 306 return;
Chris@16 307 }
Chris@16 308 }
Chris@16 309 std::size_t ptr_offset;
Chris@16 310 std::size_t this_offset;
Chris@16 311 segment_info_t ptr_info;
Chris@16 312 segment_info_t this_info;
Chris@16 313 void *ptr_base;
Chris@16 314 void *this_base;
Chris@16 315 get_segment_info_and_offset(this, this_info, this_offset, this_base);
Chris@16 316
Chris@16 317 if(!this_info.group){
Chris@16 318 this->set_mode(is_in_stack);
Chris@16 319 this->members.direct.addr = const_cast<void*>(ptr);
Chris@16 320 }
Chris@16 321 else{
Chris@16 322 get_segment_info_and_offset(ptr, ptr_info, ptr_offset, ptr_base);
Chris@16 323
Chris@16 324 if(ptr_info.group != this_info.group){
Chris@16 325 this->set_mode(is_pointee_outside);
Chris@16 326 this->members.direct.addr = const_cast<void*>(ptr);
Chris@16 327 }
Chris@16 328 else if(ptr_info.id == this_info.id){
Chris@16 329 this->set_mode(is_relative);
Chris@16 330 members.relative.off = (static_cast<const char*>(ptr) - reinterpret_cast<const char*>(this));
Chris@16 331 this->relative_set_begin_from_base(this_base);
Chris@16 332 std::size_t pow, frc;
Chris@16 333 std::size_t s = calculate_size(this_info.size, pow, frc);
Chris@16 334 (void)s;
Chris@16 335 BOOST_ASSERT(this_info.size == s);
Chris@16 336 this->members.relative.pow = pow;
Chris@16 337 this->members.relative.frc = frc;
Chris@16 338 }
Chris@16 339 else{
Chris@16 340 this->set_mode(is_segmented);
Chris@16 341 this->members.segmented.segment = ptr_info.id;
Chris@16 342 this->members.segmented.off = ptr_offset;
Chris@16 343 }
Chris@16 344 }
Chris@16 345 }
Chris@16 346
Chris@16 347 //!Sets the object internals to represent the address pointed
Chris@16 348 //!by another flat_map_intersegment
Chris@16 349 void set_from_other(const self_t &other)
Chris@16 350 {
Chris@16 351 this->set_from_pointer(other.to_raw_pointer());
Chris@16 352 }
Chris@16 353
Chris@16 354 //!Increments internal
Chris@16 355 //!offset
Chris@16 356 void inc_offset(std::ptrdiff_t bytes)
Chris@16 357 {
Chris@16 358 this->set_from_pointer(static_cast<char*>(this->to_raw_pointer()) + bytes);
Chris@16 359 }
Chris@16 360
Chris@16 361 //!Decrements internal
Chris@16 362 //!offset
Chris@16 363 void dec_offset(std::ptrdiff_t bytes)
Chris@16 364 {
Chris@16 365 this->set_from_pointer(static_cast<char*>(this->to_raw_pointer()) - bytes);
Chris@16 366 }
Chris@16 367
Chris@16 368 //////////////////////////////////////
Chris@16 369 //////////////////////////////////////
Chris@16 370 //////////////////////////////////////
Chris@16 371
Chris@16 372 flat_map_intersegment()
Chris@16 373 : intersegment_base()
Chris@16 374 {}
Chris@16 375
Chris@16 376 ~flat_map_intersegment()
Chris@16 377 {}
Chris@16 378
Chris@16 379 private:
Chris@16 380
Chris@16 381 class segment_group_t
Chris@16 382 {
Chris@16 383 struct segment_data
Chris@16 384 {
Chris@16 385 void *addr;
Chris@16 386 std::size_t size;
Chris@16 387 };
Chris@16 388 vector<segment_data> m_segments;
Chris@16 389 multi_segment_services &m_ms_services;
Chris@16 390
Chris@16 391 public:
Chris@16 392 segment_group_t(multi_segment_services &ms_services)
Chris@16 393 : m_ms_services(ms_services)
Chris@16 394 {}
Chris@16 395
Chris@16 396 void push_back(void *addr, std::size_t size)
Chris@16 397 {
Chris@16 398 segment_data d = { addr, size };
Chris@16 399 m_segments.push_back(d);
Chris@16 400 }
Chris@16 401
Chris@16 402 void pop_back()
Chris@16 403 {
Chris@16 404 BOOST_ASSERT(!m_segments.empty());
Chris@16 405 m_segments.erase(--m_segments.end());
Chris@16 406 }
Chris@16 407
Chris@16 408
Chris@16 409 void *address_of(std::size_t segment_id)
Chris@16 410 {
Chris@16 411 BOOST_ASSERT(segment_id < (std::size_t)m_segments.size());
Chris@16 412 return m_segments[segment_id].addr;
Chris@16 413 }
Chris@16 414
Chris@16 415 void clear_segments()
Chris@16 416 { m_segments.clear(); }
Chris@16 417
Chris@16 418 std::size_t get_size() const
Chris@16 419 { return m_segments.size(); }
Chris@16 420
Chris@16 421 multi_segment_services &get_multi_segment_services() const
Chris@16 422 { return m_ms_services; }
Chris@16 423
Chris@16 424 friend bool operator< (const segment_group_t&l, const segment_group_t &r)
Chris@16 425 { return &l.m_ms_services < &r.m_ms_services; }
Chris@16 426 };
Chris@16 427
Chris@16 428 struct segment_info_t
Chris@16 429 {
Chris@16 430 std::size_t size;
Chris@16 431 std::size_t id;
Chris@16 432 segment_group_t *group;
Chris@16 433 segment_info_t()
Chris@16 434 : size(0), id(0), group(0)
Chris@16 435 {}
Chris@16 436 };
Chris@16 437
Chris@16 438 typedef set<segment_group_t> segment_groups_t;
Chris@16 439
Chris@16 440 typedef boost::interprocess::flat_map
Chris@16 441 <const void *
Chris@16 442 ,segment_info_t
Chris@16 443 ,std::less<const void *> > ptr_to_segment_info_t;
Chris@16 444
Chris@16 445 struct mappings_t : Mutex
Chris@16 446 {
Chris@16 447 //!Mutex to preserve integrity in multi-threaded
Chris@16 448 //!enviroments
Chris@16 449 typedef Mutex mutex_type;
Chris@16 450 //!Maps base addresses and segment information
Chris@16 451 //!(size and segment group and id)*
Chris@16 452
Chris@16 453 ptr_to_segment_info_t m_ptr_to_segment_info;
Chris@16 454
Chris@16 455 ~mappings_t()
Chris@16 456 {
Chris@16 457 //Check that all mappings have been erased
Chris@16 458 BOOST_ASSERT(m_ptr_to_segment_info.empty());
Chris@16 459 }
Chris@16 460 };
Chris@16 461
Chris@16 462 //Static members
Chris@16 463 static mappings_t s_map;
Chris@16 464 static segment_groups_t s_groups;
Chris@16 465 public:
Chris@16 466
Chris@16 467 typedef segment_group_t* segment_group_id;
Chris@16 468
Chris@16 469 //!Returns the segment and offset
Chris@16 470 //!of an address
Chris@16 471 static void get_segment_info_and_offset(const void *ptr, segment_info_t &segment, std::size_t &offset, void *&base)
Chris@16 472 {
Chris@16 473 //------------------------------------------------------------------
Chris@16 474 boost::interprocess::scoped_lock<typename mappings_t::mutex_type> lock(s_map);
Chris@16 475 //------------------------------------------------------------------
Chris@16 476 base = 0;
Chris@16 477 if(s_map.m_ptr_to_segment_info.empty()){
Chris@16 478 segment = segment_info_t();
Chris@16 479 offset = reinterpret_cast<const char*>(ptr) - static_cast<const char*>(0);
Chris@16 480 return;
Chris@16 481 }
Chris@16 482 //Find the first base address greater than ptr
Chris@16 483 typename ptr_to_segment_info_t::iterator it
Chris@16 484 = s_map.m_ptr_to_segment_info.upper_bound(ptr);
Chris@16 485 if(it == s_map.m_ptr_to_segment_info.begin()){
Chris@16 486 segment = segment_info_t();
Chris@16 487 offset = reinterpret_cast<const char*>(ptr) - static_cast<const char *>(0);
Chris@16 488 }
Chris@16 489 //Go to the previous one
Chris@16 490 --it;
Chris@16 491 char * segment_base = const_cast<char*>(reinterpret_cast<const char*>(it->first));
Chris@16 492 std::size_t segment_size = it->second.size;
Chris@16 493
Chris@16 494 if(segment_base <= reinterpret_cast<const char*>(ptr) &&
Chris@16 495 (segment_base + segment_size) >= reinterpret_cast<const char*>(ptr)){
Chris@16 496 segment = it->second;
Chris@16 497 offset = reinterpret_cast<const char*>(ptr) - segment_base;
Chris@16 498 base = segment_base;
Chris@16 499 }
Chris@16 500 else{
Chris@16 501 segment = segment_info_t();
Chris@16 502 offset = reinterpret_cast<const char*>(ptr) - static_cast<const char*>(0);
Chris@16 503 }
Chris@16 504 }
Chris@16 505
Chris@16 506 //!Associates a segment defined by group/id with a base address and size.
Chris@16 507 //!Returns false if the group is not found or there is an error
Chris@16 508 static void insert_mapping(segment_group_id group_id, void *ptr, std::size_t size)
Chris@16 509 {
Chris@16 510 //------------------------------------------------------------------
Chris@16 511 boost::interprocess::scoped_lock<typename mappings_t::mutex_type> lock(s_map);
Chris@16 512 //------------------------------------------------------------------
Chris@16 513
Chris@16 514 typedef typename ptr_to_segment_info_t::value_type value_type;
Chris@16 515 typedef typename ptr_to_segment_info_t::iterator iterator;
Chris@16 516 typedef std::pair<iterator, bool> it_b_t;
Chris@16 517
Chris@16 518 segment_info_t info;
Chris@16 519 info.group = group_id;
Chris@16 520 info.size = size;
Chris@16 521 info.id = group_id->get_size();
Chris@16 522
Chris@16 523 it_b_t ret = s_map.m_ptr_to_segment_info.insert(value_type(ptr, info));
Chris@16 524 BOOST_ASSERT(ret.second);
Chris@16 525
Chris@16 526 value_eraser<ptr_to_segment_info_t> v_eraser(s_map.m_ptr_to_segment_info, ret.first);
Chris@16 527 group_id->push_back(ptr, size);
Chris@16 528 v_eraser.release();
Chris@16 529 }
Chris@16 530
Chris@16 531 static bool erase_last_mapping(segment_group_id group_id)
Chris@16 532 {
Chris@16 533 //------------------------------------------------------------------
Chris@16 534 boost::interprocess::scoped_lock<typename mappings_t::mutex_type> lock(s_map);
Chris@16 535 //------------------------------------------------------------------
Chris@16 536 if(!group_id->get_size()){
Chris@16 537 return false;
Chris@16 538 }
Chris@16 539 else{
Chris@16 540 void *addr = group_id->address_of(group_id->get_size()-1);
Chris@16 541 group_id->pop_back();
Chris@16 542 std::size_t erased = s_map.m_ptr_to_segment_info.erase(addr);
Chris@16 543 (void)erased;
Chris@16 544 BOOST_ASSERT(erased);
Chris@16 545 return true;
Chris@16 546 }
Chris@16 547 }
Chris@16 548
Chris@16 549 static segment_group_id new_segment_group(multi_segment_services *services)
Chris@16 550 {
Chris@16 551 { //------------------------------------------------------------------
Chris@16 552 boost::interprocess::scoped_lock<typename mappings_t::mutex_type> lock(s_map);
Chris@16 553 //------------------------------------------------------------------
Chris@16 554 typedef typename segment_groups_t::iterator iterator;
Chris@16 555 std::pair<iterator, bool> ret =
Chris@16 556 s_groups.insert(segment_group_t(*services));
Chris@16 557 BOOST_ASSERT(ret.second);
Chris@16 558 return &*ret.first;
Chris@16 559 }
Chris@16 560 }
Chris@16 561
Chris@16 562 static bool delete_group(segment_group_id id)
Chris@16 563 {
Chris@16 564 { //------------------------------------------------------------------
Chris@16 565 boost::interprocess::scoped_lock<typename mappings_t::mutex_type> lock(s_map);
Chris@16 566 //------------------------------------------------------------------
Chris@16 567 bool success = 1u == s_groups.erase(segment_group_t(*id));
Chris@16 568 if(success){
Chris@16 569 typedef typename ptr_to_segment_info_t::iterator ptr_to_segment_info_it;
Chris@16 570 ptr_to_segment_info_it it(s_map.m_ptr_to_segment_info.begin());
Chris@16 571 while(it != s_map.m_ptr_to_segment_info.end()){
Chris@16 572 if(it->second.group == id){
Chris@16 573 it = s_map.m_ptr_to_segment_info.erase(it);
Chris@16 574 }
Chris@16 575 else{
Chris@16 576 ++it;
Chris@16 577 }
Chris@16 578 }
Chris@16 579 }
Chris@16 580 return success;
Chris@16 581 }
Chris@16 582 }
Chris@16 583 };
Chris@16 584
Chris@16 585 //!Static map-segment_info associated with
Chris@16 586 //!flat_map_intersegment<>
Chris@16 587 template <class Mutex>
Chris@16 588 typename flat_map_intersegment<Mutex>::mappings_t
Chris@16 589 flat_map_intersegment<Mutex>::s_map;
Chris@16 590
Chris@16 591 //!Static segment group container associated with
Chris@16 592 //!flat_map_intersegment<>
Chris@16 593 template <class Mutex>
Chris@16 594 typename flat_map_intersegment<Mutex>::segment_groups_t
Chris@16 595 flat_map_intersegment<Mutex>::s_groups;
Chris@16 596
Chris@16 597 //!A smart pointer that can point to a pointee that resides in another memory
Chris@16 598 //!memory mapped or shared memory segment.
Chris@16 599 template <class T>
Chris@16 600 class intersegment_ptr : public flat_map_intersegment<interprocess_mutex>
Chris@16 601 {
Chris@16 602 typedef flat_map_intersegment<interprocess_mutex> PT;
Chris@16 603 typedef intersegment_ptr<T> self_t;
Chris@16 604 typedef PT base_t;
Chris@16 605
Chris@16 606 void unspecified_bool_type_func() const {}
Chris@16 607 typedef void (self_t::*unspecified_bool_type)() const;
Chris@16 608
Chris@16 609 public:
Chris@16 610 typedef T * pointer;
Chris@16 611 typedef typename ipcdetail::add_reference<T>::type reference;
Chris@16 612 typedef T value_type;
Chris@16 613 typedef std::ptrdiff_t difference_type;
Chris@16 614 typedef std::random_access_iterator_tag iterator_category;
Chris@16 615
Chris@16 616 public: //Public Functions
Chris@16 617
Chris@16 618 //!Constructor from raw pointer (allows "0" pointer conversion).
Chris@16 619 //!Never throws.
Chris@16 620 intersegment_ptr(pointer ptr = 0)
Chris@16 621 { base_t::set_from_pointer(ptr); }
Chris@16 622
Chris@16 623 //!Constructor from other pointer.
Chris@16 624 //!Never throws.
Chris@16 625 template <class U>
Chris@16 626 intersegment_ptr(U *ptr){ base_t::set_from_pointer(pointer(ptr)); }
Chris@16 627
Chris@16 628 //!Constructor from other intersegment_ptr
Chris@16 629 //!Never throws
Chris@16 630 intersegment_ptr(const intersegment_ptr& ptr)
Chris@16 631 { base_t::set_from_other(ptr); }
Chris@16 632
Chris@16 633 //!Constructor from other intersegment_ptr. If pointers of pointee types are
Chris@16 634 //!convertible, intersegment_ptrs will be convertibles. Never throws.
Chris@16 635 template<class T2>
Chris@16 636 intersegment_ptr(const intersegment_ptr<T2> &ptr)
Chris@16 637 { pointer p(ptr.get()); (void)p; base_t::set_from_other(ptr); }
Chris@16 638
Chris@16 639 //!Emulates static_cast operator.
Chris@16 640 //!Never throws.
Chris@16 641 template<class U>
Chris@16 642 intersegment_ptr(const intersegment_ptr<U> &r, ipcdetail::static_cast_tag)
Chris@16 643 { base_t::set_from_pointer(static_cast<T*>(r.get())); }
Chris@16 644
Chris@16 645 //!Emulates const_cast operator.
Chris@16 646 //!Never throws.
Chris@16 647 template<class U>
Chris@16 648 intersegment_ptr(const intersegment_ptr<U> &r, ipcdetail::const_cast_tag)
Chris@16 649 { base_t::set_from_pointer(const_cast<T*>(r.get())); }
Chris@16 650
Chris@16 651 //!Emulates dynamic_cast operator.
Chris@16 652 //!Never throws.
Chris@16 653 template<class U>
Chris@16 654 intersegment_ptr(const intersegment_ptr<U> &r, ipcdetail::dynamic_cast_tag)
Chris@16 655 { base_t::set_from_pointer(dynamic_cast<T*>(r.get())); }
Chris@16 656
Chris@16 657 //!Emulates reinterpret_cast operator.
Chris@16 658 //!Never throws.
Chris@16 659 template<class U>
Chris@16 660 intersegment_ptr(const intersegment_ptr<U> &r, ipcdetail::reinterpret_cast_tag)
Chris@16 661 { base_t::set_from_pointer(reinterpret_cast<T*>(r.get())); }
Chris@16 662
Chris@16 663 //!Obtains raw pointer from offset.
Chris@16 664 //!Never throws.
Chris@16 665 pointer get()const
Chris@16 666 { return static_cast<pointer>(base_t::to_raw_pointer()); }
Chris@16 667
Chris@16 668 //!Pointer-like -> operator. It can return 0 pointer.
Chris@16 669 //!Never throws.
Chris@16 670 pointer operator->() const
Chris@16 671 { return self_t::get(); }
Chris@16 672
Chris@16 673 //!Dereferencing operator, if it is a null intersegment_ptr behavior
Chris@16 674 //!is undefined. Never throws.
Chris@16 675 reference operator* () const
Chris@16 676 { return *(self_t::get()); }
Chris@16 677
Chris@16 678 //!Indexing operator.
Chris@16 679 //!Never throws.
Chris@16 680 reference operator[](std::ptrdiff_t idx) const
Chris@16 681 { return self_t::get()[idx]; }
Chris@16 682
Chris@16 683 //!Assignment from pointer (saves extra conversion).
Chris@16 684 //!Never throws.
Chris@16 685 intersegment_ptr& operator= (pointer from)
Chris@16 686 { base_t::set_from_pointer(from); return *this; }
Chris@16 687
Chris@16 688 //!Assignment from other intersegment_ptr.
Chris@16 689 //!Never throws.
Chris@16 690 intersegment_ptr& operator= (const intersegment_ptr &ptr)
Chris@16 691 { base_t::set_from_other(ptr); return *this; }
Chris@16 692
Chris@16 693 //!Assignment from related intersegment_ptr. If pointers of pointee types
Chris@16 694 //!are assignable, intersegment_ptrs will be assignable. Never throws.
Chris@16 695 template <class T2>
Chris@16 696 intersegment_ptr& operator= (const intersegment_ptr<T2> & ptr)
Chris@16 697 {
Chris@16 698 pointer p(ptr.get()); (void)p;
Chris@16 699 base_t::set_from_other(ptr); return *this;
Chris@16 700 }
Chris@16 701
Chris@16 702 //!intersegment_ptr + std::ptrdiff_t.
Chris@16 703 //!Never throws.
Chris@16 704 intersegment_ptr operator+ (std::ptrdiff_t idx) const
Chris@16 705 {
Chris@16 706 intersegment_ptr result (*this);
Chris@16 707 result.inc_offset(idx*sizeof(T));
Chris@16 708 return result;
Chris@16 709 }
Chris@16 710
Chris@16 711 //!intersegment_ptr - std::ptrdiff_t.
Chris@16 712 //!Never throws.
Chris@16 713 intersegment_ptr operator- (std::ptrdiff_t idx) const
Chris@16 714 {
Chris@16 715 intersegment_ptr result (*this);
Chris@16 716 result.dec_offset(idx*sizeof(T));
Chris@16 717 return result;
Chris@16 718 }
Chris@16 719
Chris@16 720 //!intersegment_ptr += std::ptrdiff_t.
Chris@16 721 //!Never throws.
Chris@16 722 intersegment_ptr &operator+= (std::ptrdiff_t offset)
Chris@16 723 { base_t::inc_offset(offset*sizeof(T)); return *this; }
Chris@16 724
Chris@16 725 //!intersegment_ptr -= std::ptrdiff_t.
Chris@16 726 //!Never throws.
Chris@16 727 intersegment_ptr &operator-= (std::ptrdiff_t offset)
Chris@16 728 { base_t::dec_offset(offset*sizeof(T)); return *this; }
Chris@16 729
Chris@16 730 //!++intersegment_ptr.
Chris@16 731 //!Never throws.
Chris@16 732 intersegment_ptr& operator++ (void)
Chris@16 733 { base_t::inc_offset(sizeof(T)); return *this; }
Chris@16 734
Chris@16 735 //!intersegment_ptr++.
Chris@16 736 //!Never throws.
Chris@16 737 intersegment_ptr operator++ (int)
Chris@16 738 { intersegment_ptr temp(*this); ++*this; return temp; }
Chris@16 739
Chris@16 740 //!--intersegment_ptr.
Chris@16 741 //!Never throws.
Chris@16 742 intersegment_ptr& operator-- (void)
Chris@16 743 { base_t::dec_offset(sizeof(T)); return *this; }
Chris@16 744
Chris@16 745 //!intersegment_ptr--.
Chris@16 746 //!Never throws.
Chris@16 747 intersegment_ptr operator-- (int)
Chris@16 748 { intersegment_ptr temp(*this); --*this; return temp; }
Chris@16 749
Chris@16 750 //!Safe bool conversion operator.
Chris@16 751 //!Never throws.
Chris@16 752 operator unspecified_bool_type() const
Chris@16 753 { return base_t::is_null()? 0 : &self_t::unspecified_bool_type_func; }
Chris@16 754
Chris@16 755 //!Not operator. Not needed in theory, but improves portability.
Chris@16 756 //!Never throws.
Chris@16 757 bool operator! () const
Chris@16 758 { return base_t::is_null(); }
Chris@16 759
Chris@101 760 //!Swaps two intersegment_ptr-s. More efficient than standard swap.
Chris@16 761 //!Never throws.
Chris@16 762 void swap(intersegment_ptr &other)
Chris@16 763 { base_t::swap(other); }
Chris@16 764
Chris@16 765 //!Calculates the distance between two intersegment_ptr-s.
Chris@16 766 //!This only works with two basic_intersegment_ptr pointing
Chris@16 767 //!to the same segment. Otherwise undefined
Chris@16 768 template <class T2>
Chris@16 769 std::ptrdiff_t _diff(const intersegment_ptr<T2> &other) const
Chris@16 770 { return base_t::diff(other); }
Chris@16 771
Chris@16 772 //!Returns true if both point to the
Chris@16 773 //!same object
Chris@16 774 template <class T2>
Chris@16 775 bool _equal(const intersegment_ptr<T2>&other) const
Chris@16 776 { return base_t::equal(other); }
Chris@16 777
Chris@16 778 //!Returns true if *this is less than other.
Chris@16 779 //!This only works with two basic_intersegment_ptr pointing
Chris@16 780 //!to the same segment group. Otherwise undefined. Never throws
Chris@16 781 template <class T2>
Chris@16 782 bool _less(const intersegment_ptr<T2> &other) const
Chris@16 783 { return base_t::less(other); }
Chris@16 784 };
Chris@16 785
Chris@16 786 //!Compares the equality of two intersegment_ptr-s.
Chris@16 787 //!Never throws.
Chris@16 788 template <class T1, class T2> inline
Chris@16 789 bool operator ==(const intersegment_ptr<T1> &left,
Chris@16 790 const intersegment_ptr<T2> &right)
Chris@16 791 {
Chris@16 792 //Make sure both pointers can be compared
Chris@16 793 bool e = typename intersegment_ptr<T1>::pointer(0) ==
Chris@16 794 typename intersegment_ptr<T2>::pointer(0);
Chris@16 795 (void)e;
Chris@16 796 return left._equal(right);
Chris@16 797 }
Chris@16 798
Chris@16 799 //!Returns true if *this is less than other.
Chris@16 800 //!This only works with two basic_intersegment_ptr pointing
Chris@16 801 //!to the same segment group. Otherwise undefined. Never throws
Chris@16 802 template <class T1, class T2> inline
Chris@16 803 bool operator <(const intersegment_ptr<T1> &left,
Chris@16 804 const intersegment_ptr<T2> &right)
Chris@16 805 {
Chris@16 806 //Make sure both pointers can be compared
Chris@16 807 bool e = typename intersegment_ptr<T1>::pointer(0) <
Chris@16 808 typename intersegment_ptr<T2>::pointer(0);
Chris@16 809 (void)e;
Chris@16 810 return left._less(right);
Chris@16 811 }
Chris@16 812
Chris@16 813 template<class T1, class T2> inline
Chris@16 814 bool operator!= (const intersegment_ptr<T1> &pt1,
Chris@16 815 const intersegment_ptr<T2> &pt2)
Chris@16 816 { return !(pt1 ==pt2); }
Chris@16 817
Chris@16 818 //!intersegment_ptr<T1> <= intersegment_ptr<T2>.
Chris@16 819 //!Never throws.
Chris@16 820 template<class T1, class T2> inline
Chris@16 821 bool operator<= (const intersegment_ptr<T1> &pt1,
Chris@16 822 const intersegment_ptr<T2> &pt2)
Chris@16 823 { return !(pt1 > pt2); }
Chris@16 824
Chris@16 825 //!intersegment_ptr<T1> > intersegment_ptr<T2>.
Chris@16 826 //!Never throws.
Chris@16 827 template<class T1, class T2> inline
Chris@16 828 bool operator> (const intersegment_ptr<T1> &pt1,
Chris@16 829 const intersegment_ptr<T2> &pt2)
Chris@16 830 { return (pt2 < pt1); }
Chris@16 831
Chris@16 832 //!intersegment_ptr<T1> >= intersegment_ptr<T2>.
Chris@16 833 //!Never throws.
Chris@16 834 template<class T1, class T2> inline
Chris@16 835 bool operator>= (const intersegment_ptr<T1> &pt1,
Chris@16 836 const intersegment_ptr<T2> &pt2)
Chris@16 837 { return !(pt1 < pt2); }
Chris@16 838
Chris@16 839 //!operator<<
Chris@16 840 template<class E, class T, class U> inline
Chris@16 841 std::basic_ostream<E, T> & operator<<
Chris@16 842 (std::basic_ostream<E, T> & os, const intersegment_ptr<U> & p)
Chris@16 843 { return os << p.get(); }
Chris@16 844
Chris@16 845 //!operator>>
Chris@16 846 template<class E, class T, class U> inline
Chris@16 847 std::basic_istream<E, T> & operator>>
Chris@16 848 (std::basic_istream<E, T> & os, intersegment_ptr<U> & p)
Chris@16 849 { U * tmp; return os >> tmp; p = tmp; }
Chris@16 850
Chris@16 851 //!std::ptrdiff_t + intersegment_ptr.
Chris@16 852 //!The result is another pointer of the same segment
Chris@16 853 template<class T> inline
Chris@16 854 intersegment_ptr<T> operator+
Chris@16 855 (std::ptrdiff_t diff, const intersegment_ptr<T>& right)
Chris@16 856 { return right + diff; }
Chris@16 857
Chris@16 858 //!intersegment_ptr - intersegment_ptr.
Chris@16 859 //!This only works with two intersegment_ptr-s that point to the
Chris@16 860 //!same segment
Chris@16 861 template <class T, class T2> inline
Chris@16 862 std::ptrdiff_t operator- (const intersegment_ptr<T> &pt,
Chris@16 863 const intersegment_ptr<T2> &pt2)
Chris@16 864 { return pt._diff(pt2)/sizeof(T); }
Chris@16 865
Chris@16 866 //! swap specialization
Chris@16 867 template<class T> inline
Chris@16 868 void swap (boost::interprocess::intersegment_ptr<T> &pt,
Chris@16 869 boost::interprocess::intersegment_ptr<T> &pt2)
Chris@16 870 { pt.swap(pt2); }
Chris@16 871
Chris@16 872 //!to_raw_pointer() enables boost::mem_fn to recognize intersegment_ptr.
Chris@16 873 //!Never throws.
Chris@16 874 template<class T> inline
Chris@16 875 T * to_raw_pointer(boost::interprocess::intersegment_ptr<T> const & p)
Chris@16 876 { return p.get(); }
Chris@16 877
Chris@16 878 //!Simulation of static_cast between pointers.
Chris@16 879 //!Never throws.
Chris@16 880 template<class T, class U> inline
Chris@16 881 boost::interprocess::intersegment_ptr<T> static_pointer_cast(const boost::interprocess::intersegment_ptr<U> &r)
Chris@16 882 { return boost::interprocess::intersegment_ptr<T>(r, boost::interprocess::ipcdetail::static_cast_tag()); }
Chris@16 883
Chris@16 884 //!Simulation of const_cast between pointers.
Chris@16 885 //!Never throws.
Chris@16 886 template<class T, class U> inline
Chris@16 887 boost::interprocess::intersegment_ptr<T> const_pointer_cast(const boost::interprocess::intersegment_ptr<U> &r)
Chris@16 888 { return boost::interprocess::intersegment_ptr<T>(r, boost::interprocess::ipcdetail::const_cast_tag()); }
Chris@16 889
Chris@16 890 //!Simulation of dynamic_cast between pointers.
Chris@16 891 //!Never throws.
Chris@16 892 template<class T, class U> inline
Chris@16 893 boost::interprocess::intersegment_ptr<T> dynamic_pointer_cast(const boost::interprocess::intersegment_ptr<U> &r)
Chris@16 894 { return boost::interprocess::intersegment_ptr<T>(r, boost::interprocess::ipcdetail::dynamic_cast_tag()); }
Chris@16 895
Chris@16 896 //!Simulation of reinterpret_cast between pointers.
Chris@16 897 //!Never throws.
Chris@16 898 template<class T, class U> inline
Chris@16 899 boost::interprocess::intersegment_ptr<T> reinterpret_pointer_cast(const boost::interprocess::intersegment_ptr<U> &r)
Chris@16 900 { return boost::interprocess::intersegment_ptr<T>(r, boost::interprocess::ipcdetail::reinterpret_cast_tag()); }
Chris@16 901
Chris@16 902 //!Trait class to detect if an smart pointer has
Chris@16 903 //!multi-segment addressing capabilities.
Chris@16 904 template <class T>
Chris@16 905 struct is_multisegment_ptr
Chris@16 906 <boost::interprocess::intersegment_ptr<T> >
Chris@16 907 {
Chris@16 908 static const bool value = true;
Chris@16 909 };
Chris@16 910
Chris@16 911 } //namespace interprocess {
Chris@16 912
Chris@16 913 #if defined(_MSC_VER) && (_MSC_VER < 1400)
Chris@16 914 //!to_raw_pointer() enables boost::mem_fn to recognize intersegment_ptr.
Chris@16 915 //!Never throws.
Chris@16 916 template<class T> inline
Chris@16 917 T * to_raw_pointer(boost::interprocess::intersegment_ptr<T> const & p)
Chris@16 918 { return p.get(); }
Chris@16 919 #endif
Chris@16 920
Chris@16 921 //!has_trivial_constructor<> == true_type specialization
Chris@16 922 //!for optimizations
Chris@16 923 template <class T>
Chris@16 924 struct has_trivial_constructor
Chris@16 925 < boost::interprocess::intersegment_ptr<T> >
Chris@16 926 : public true_type{};
Chris@16 927
Chris@16 928 //!has_trivial_destructor<> == true_type specialization
Chris@16 929 //!for optimizations
Chris@16 930 template <class T>
Chris@16 931 struct has_trivial_destructor
Chris@16 932 < boost::interprocess::intersegment_ptr<T> >
Chris@16 933 : public true_type{};
Chris@16 934
Chris@16 935 } //namespace boost {
Chris@16 936
Chris@16 937 #if 0
Chris@16 938
Chris@16 939 //bits
Chris@16 940 //-> is_segmented
Chris@16 941 //-> is_relative
Chris@16 942 //-> is_in_stack
Chris@16 943 //-> is_pointee_outside
Chris@16 944
Chris@16 945 //Data
Chris@16 946
Chris@16 947
Chris@16 948
Chris@16 949
Chris@16 950 //segmented:
Chris@16 951 //
Chris@16 952 // std::size_t ctrl : CTRL_BITS;
Chris@16 953 // std::size_t segment : MAX_SEGMENT_BITS;
Chris@16 954 // std::size_t offset;
Chris@16 955
Chris@16 956 //RELATIVE_SIZE_BITS = SIZE_T_BITS -
Chris@16 957 // MAX_SEGMENT_BITS -
Chris@16 958 // CTRL_BITS 10 10
Chris@16 959 //MAX_SEGMENT_SIZE = SIZE_T_BITS - ALIGN_BITS 20 52
Chris@16 960
Chris@16 961 //SIZE_T_BITS - 1 - ALIGN_BITS 19 51
Chris@16 962 //POW_SIZE_BITS = upper_log2
Chris@16 963 // (SIZE_T_BITS - 1 - ALIGN_BITS) 5 6
Chris@16 964 //FRC_SIZE_BITS = SIZE_T_BITS - CTRL_BITS
Chris@16 965 // MAX_SEGMENT_SIZE_ALIGNBITS - POW_SIZE_BITS 6 5
Chris@16 966
Chris@16 967 //relative:
Chris@16 968 //
Chris@16 969 // std::size_t ctrl : CTRL_BITS; 2 2
Chris@16 970 // std::size_t size_pow : POW_SIZE_BITS 5 6
Chris@16 971 // std::size_t size_frc : FRC_SIZE_BITS; 6 5
Chris@16 972 // std::size_t start : MAX_SEGMENT_SIZE_ALIGNBITS;19 51
Chris@16 973 // std::ptrdiff_t distance : SIZE_T_BITS; 32 64
Chris@16 974
Chris@16 975 //direct:
Chris@16 976 //
Chris@16 977 // std::size_t ctrl : CTRL_BITS; 2 2
Chris@16 978 // std::size_t dummy : SIZE_T_BITS - CTRL_BITS 30 62
Chris@16 979 // void *addr : SIZE_T_BITS; 32 64
Chris@16 980
Chris@16 981 //32 bits systems:
Chris@16 982 //Page alignment: 2**12
Chris@16 983 //
Chris@16 984
Chris@16 985 //!Obtains the address pointed by the
Chris@16 986 //!object
Chris@16 987 void *to_raw_pointer() const
Chris@16 988 {
Chris@16 989 if(this->is_pointee_outside() || this->is_in_stack()){
Chris@16 990 return raw_address();
Chris@16 991 }
Chris@16 992 else if(this->is_relative()){
Chris@16 993 return (const_cast<char*>(reinterpret_cast<const char*>(this))) + this->relative_pointee_offset();
Chris@16 994 }
Chris@16 995 else{
Chris@16 996 group_manager *m = get_segment_group_manager(addr);
Chris@16 997 char *base = static_cast<char*>(m->get_id_address(this->segmented_id()));
Chris@16 998 return base + this->segmented_offset();
Chris@16 999 }
Chris@16 1000 }
Chris@16 1001
Chris@16 1002 void set_from_pointer(const void *ptr)
Chris@16 1003 {
Chris@16 1004 if(!ptr){
Chris@16 1005 this->set_pointee_outside();
Chris@16 1006 this->raw_address(ptr);
Chris@16 1007 }
Chris@16 1008 else if(this->is_in_stack()){
Chris@16 1009 this->raw_address(ptr);
Chris@16 1010 }
Chris@16 1011 else if(this->is_relative() &&
Chris@16 1012 ( (ptr >= this->relative_start())
Chris@16 1013 &&(ptr < this->relative_start() + this->relative_size()))
Chris@16 1014 ){
Chris@16 1015 this->relative_offset(ptr - this);
Chris@16 1016 }
Chris@16 1017 else{
Chris@16 1018 segment_info_t ptr_info = get_id_from_addr(ptr);
Chris@16 1019 segment_info_t this_info = get_id_from_addr(this);
Chris@16 1020 if(ptr_info.segment_group != this_info.segment_group){
Chris@16 1021 if(!ptr_info.segment_group){
Chris@16 1022 this->set_in_stack();
Chris@16 1023 }
Chris@16 1024 else{
Chris@16 1025 this->set_pointee_outside();
Chris@16 1026 }
Chris@16 1027 }
Chris@16 1028 else if(ptr_info.segment_id == this_info.segment_id){
Chris@16 1029 set_relative();
Chris@16 1030 this->relative_size (ptr_info.size);
Chris@16 1031 this->relative_offset(static_cast<const char*>(ptr) - reinterpret_cast<const char*>(this));
Chris@16 1032 this->relative_start (ptr_info.base);
Chris@16 1033 }
Chris@16 1034 }
Chris@16 1035 }
Chris@16 1036
Chris@16 1037 void set_from_other(const self_t &other)
Chris@16 1038 { this->set_from_pointer(other.to_raw_pointer()); }
Chris@16 1039
Chris@16 1040 #endif
Chris@16 1041
Chris@16 1042 #include <boost/interprocess/detail/config_end.hpp>
Chris@16 1043
Chris@16 1044 #endif //#ifndef BOOST_INTERPROCESS_INTERSEGMENT_PTR_HPP