Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r85615 - in branches/release: boost/interprocess boost/interprocess/detail boost/interprocess/smart_ptr/detail boost/interprocess/streams boost/interprocess/sync boost/interprocess/sync/posix boost/interprocess/sync/spin libs/interprocess libs/interprocess/doc libs/interprocess/test
From: igaztanaga_at_[hidden]
Date: 2013-09-08 16:07:03


Author: igaztanaga
Date: 2013-09-08 16:07:03 EDT (Sun, 08 Sep 2013)
New Revision: 85615
URL: http://svn.boost.org/trac/boost/changeset/85615

Log:
Merged Interprocess to the release branch

Added:
   branches/release/boost/interprocess/sync/spin/wait.hpp
      - copied unchanged from r85614, trunk/boost/interprocess/sync/spin/wait.hpp
Deleted:
   branches/release/boost/interprocess/detail/yield_k.hpp
Properties modified:
   branches/release/boost/interprocess/ (props changed)
   branches/release/libs/interprocess/ (props changed)
Text files modified:
   branches/release/boost/interprocess/detail/atomic.hpp | 2
   branches/release/boost/interprocess/detail/intermodule_singleton_common.hpp | 9
   branches/release/boost/interprocess/detail/managed_open_or_create_impl.hpp | 13 +
   branches/release/boost/interprocess/detail/os_thread_functions.hpp | 266 ++++++++++++++++++++++++++++++++++++++-
   branches/release/boost/interprocess/detail/robust_emulation.hpp | 17 +-
   branches/release/boost/interprocess/detail/tmp_dir_helpers.hpp | 2
   branches/release/boost/interprocess/detail/win32_api.hpp | 119 +++++++++++++----
   /dev/null | 136 --------------------
   branches/release/boost/interprocess/smart_ptr/detail/sp_counted_impl.hpp | 9
   branches/release/boost/interprocess/streams/bufferstream.hpp | 137 +++++++++++++-------
   branches/release/boost/interprocess/streams/vectorstream.hpp | 113 +++++++++-------
   branches/release/boost/interprocess/sync/file_lock.hpp | 9
   branches/release/boost/interprocess/sync/posix/mutex.hpp | 5
   branches/release/boost/interprocess/sync/posix/recursive_mutex.hpp | 5
   branches/release/boost/interprocess/sync/posix/semaphore_wrapper.hpp | 5
   branches/release/boost/interprocess/sync/spin/condition.hpp | 9
   branches/release/boost/interprocess/sync/spin/mutex.hpp | 9
   branches/release/boost/interprocess/sync/spin/semaphore.hpp | 11
   branches/release/boost/interprocess/sync/spin/wait.hpp | 186 +++++++++++++++++++++++++++
   branches/release/libs/interprocess/Jamfile.v2 | 2
   branches/release/libs/interprocess/doc/interprocess.qbk | 9 +
   branches/release/libs/interprocess/test/bufferstream_test.cpp | 2
   branches/release/libs/interprocess/test/robust_mutex_test.hpp | 9
   23 files changed, 753 insertions(+), 331 deletions(-)

Modified: branches/release/boost/interprocess/detail/atomic.hpp
==============================================================================
--- branches/release/boost/interprocess/detail/atomic.hpp Sun Sep 8 15:29:06 2013 (r85614)
+++ branches/release/boost/interprocess/detail/atomic.hpp 2013-09-08 16:07:03 EDT (Sun, 08 Sep 2013) (r85615)
@@ -213,7 +213,7 @@
                  "bne- 1b\n\t"
                  "2:"
                  : "=&r"(prev)
- : "b" (mem), "r"(cmp), "r" (with)
+ : "b" (mem), "r" (with), "r" (cmp)
                  : "cc", "memory");
    return prev;
 }

Modified: branches/release/boost/interprocess/detail/intermodule_singleton_common.hpp
==============================================================================
--- branches/release/boost/interprocess/detail/intermodule_singleton_common.hpp Sun Sep 8 15:29:06 2013 (r85614)
+++ branches/release/boost/interprocess/detail/intermodule_singleton_common.hpp 2013-09-08 16:07:03 EDT (Sun, 08 Sep 2013) (r85615)
@@ -23,6 +23,7 @@
 #include <boost/interprocess/exceptions.hpp>
 #include <boost/type_traits/type_with_alignment.hpp>
 #include <boost/interprocess/detail/mpl.hpp>
+#include <boost/interprocess/sync/spin/wait.hpp>
 #include <boost/assert.hpp>
 #include <cstddef>
 #include <cstdio>
@@ -145,7 +146,7 @@
          //If previous state was initializing, this means that another winner thread is
          //trying to initialize the singleton. Just wait until completes its work.
          else if(previous_module_singleton_initialized == Initializing){
- unsigned int k = 0;
+ spin_wait swait;
             while(1){
                previous_module_singleton_initialized = atomic_read32(&this_module_singleton_initialized);
                if(previous_module_singleton_initialized >= Initialized){
@@ -153,7 +154,7 @@
                   break;
                }
                else if(previous_module_singleton_initialized == Initializing){
- yield(k++);
+ swait.yield();
                }
                else{
                   //This can't be happening!
@@ -207,7 +208,7 @@
    static void initialize_global_map_handle()
    {
       //Obtain unique map name and size
- unsigned k = 0;
+ spin_wait swait;
       while(1){
          //Try to pass map state to initializing
          ::boost::uint32_t tmp = atomic_cas32(&this_module_map_initialized, Initializing, Uninitialized);
@@ -220,7 +221,7 @@
          }
          //If some other thread is doing the work wait
          else if(tmp == Initializing){
- yield(k++);
+ swait.yield();
          }
          else{ //(tmp == Uninitialized)
             //If not initialized try it again?

Modified: branches/release/boost/interprocess/detail/managed_open_or_create_impl.hpp
==============================================================================
--- branches/release/boost/interprocess/detail/managed_open_or_create_impl.hpp Sun Sep 8 15:29:06 2013 (r85614)
+++ branches/release/boost/interprocess/detail/managed_open_or_create_impl.hpp 2013-09-08 16:07:03 EDT (Sun, 08 Sep 2013) (r85615)
@@ -25,6 +25,7 @@
 #include <boost/interprocess/permissions.hpp>
 #include <boost/type_traits/alignment_of.hpp>
 #include <boost/type_traits/type_with_alignment.hpp>
+#include <boost/interprocess/sync/spin/wait.hpp>
 #include <boost/move/move.hpp>
 #include <boost/cstdint.hpp>
 
@@ -354,7 +355,7 @@
          //file and know if we have really created it or just open it
          //drop me a e-mail!
          bool completed = false;
- unsigned k = 0;
+ spin_wait swait;
          while(!completed){
             try{
                create_device<FileBased>(dev, id, size, perm, file_like_t());
@@ -385,7 +386,7 @@
             catch(...){
                throw;
             }
- yield(k++);
+ swait.yield();
          }
       }
 
@@ -432,12 +433,12 @@
       else{
          if(FileBased){
             offset_t filesize = 0;
- unsigned k = 0;
+ spin_wait swait;
             while(filesize == 0){
                if(!get_file_size(file_handle_from_mapping_handle(dev.get_mapping_handle()), filesize)){
                   throw interprocess_exception(error_info(system_error_code()));
                }
- yield(k++);
+ swait.yield();
             }
             if(filesize == 1){
                throw interprocess_exception(error_info(corrupted_error));
@@ -449,9 +450,9 @@
          boost::uint32_t *patomic_word = static_cast<boost::uint32_t*>(region.get_address());
          boost::uint32_t value = atomic_read32(patomic_word);
 
- unsigned k = 0;
+ spin_wait swait;
          while(value == InitializingSegment || value == UninitializedSegment){
- yield(k++);
+ swait.yield();
             value = atomic_read32(patomic_word);
          }
 

Modified: branches/release/boost/interprocess/detail/os_thread_functions.hpp
==============================================================================
--- branches/release/boost/interprocess/detail/os_thread_functions.hpp Sun Sep 8 15:29:06 2013 (r85614)
+++ branches/release/boost/interprocess/detail/os_thread_functions.hpp 2013-09-08 16:07:03 EDT (Sun, 08 Sep 2013) (r85615)
@@ -15,18 +15,36 @@
 #include <boost/interprocess/detail/workaround.hpp>
 #include <boost/interprocess/streams/bufferstream.hpp>
 #include <boost/interprocess/detail/posix_time_types_wrk.hpp>
-#include <boost/interprocess/detail/yield_k.hpp>
+#include <cstddef>
 
 #if defined(BOOST_INTERPROCESS_WINDOWS)
 # include <boost/interprocess/detail/win32_api.hpp>
 #else
-# ifdef BOOST_HAS_UNISTD_H
-# include <pthread.h>
-# include <unistd.h>
-# include <sched.h>
-# include <time.h>
+# include <pthread.h>
+# include <unistd.h>
+# include <sched.h>
+# include <time.h>
+# ifdef BOOST_INTERPROCESS_BSD_DERIVATIVE
+ //Some *BSD systems (OpenBSD & NetBSD) need sys/param.h before sys/sysctl.h, whereas
+ //others (FreeBSD & Darwin) need sys/types.h
+# include <sys/types.h>
+# include <sys/param.h>
+# include <sys/sysctl.h>
+# endif
+//According to the article "C/C++ tip: How to measure elapsed real time for benchmarking"
+# if defined(CLOCK_MONOTONIC_PRECISE) //BSD
+# define BOOST_INTERPROCESS_CLOCK_MONOTONIC CLOCK_MONOTONIC_PRECISE
+# elif defined(CLOCK_MONOTONIC_RAW) //Linux
+# define BOOST_INTERPROCESS_CLOCK_MONOTONIC CLOCK_MONOTONIC_RAW
+# elif defined(CLOCK_HIGHRES) //Solaris
+# define BOOST_INTERPROCESS_CLOCK_MONOTONIC CLOCK_HIGHRES
+# elif defined(CLOCK_MONOTONIC) //POSIX (AIX, BSD, Linux, Solaris)
+# define BOOST_INTERPROCESS_CLOCK_MONOTONIC CLOCK_MONOTONIC
+# elif !defined(CLOCK_MONOTONIC) && (defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__))
+# include <mach/mach_time.h> // mach_absolute_time, mach_timebase_info_data_t
+# define BOOST_INTERPROCESS_MATCH_ABSOLUTE_TIME
 # else
-# error Unknown platform
+# error "No high resolution steady clock in your system, please provide a patch"
 # endif
 #endif
 
@@ -57,6 +75,75 @@
 inline bool equal_thread_id(OS_thread_id_t id1, OS_thread_id_t id2)
 { return id1 == id2; }
 
+//return the system tick in ns
+inline unsigned long get_system_tick_ns()
+{
+ unsigned long curres;
+ winapi::set_timer_resolution(10000, 0, &curres);
+ //Windows API returns the value in hundreds of ns
+ return (curres - 1ul)*100ul;
+}
+
+//return the system tick in us
+inline unsigned long get_system_tick_us()
+{
+ unsigned long curres;
+ winapi::set_timer_resolution(10000, 0, &curres);
+ //Windows API returns the value in hundreds of ns
+ return (curres - 1ul)/10ul + 1ul;
+}
+
+typedef unsigned __int64 OS_highres_count_t;
+
+inline OS_highres_count_t get_system_tick_in_highres_counts()
+{
+ __int64 freq;
+ unsigned long curres;
+ winapi::set_timer_resolution(10000, 0, &curres);
+ //Frequency in counts per second
+ if(!winapi::query_performance_frequency(&freq)){
+ //Tick resolution in ms
+ return (curres-1)/10000u + 1;
+ }
+ else{
+ //In femtoseconds
+ __int64 count_fs = __int64(1000000000000000LL - 1LL)/freq + 1LL;
+ __int64 tick_counts = (__int64(curres)*100000000LL - 1LL)/count_fs + 1LL;
+ return static_cast<OS_highres_count_t>(tick_counts);
+ }
+}
+
+inline OS_highres_count_t get_current_system_highres_count()
+{
+ __int64 count;
+ if(!winapi::query_performance_counter(&count)){
+ count = winapi::get_tick_count();
+ }
+ return count;
+}
+
+inline void zero_highres_count(OS_highres_count_t &count)
+{ count = 0; }
+
+inline bool is_highres_count_zero(const OS_highres_count_t &count)
+{ return count == 0; }
+
+template <class Ostream>
+inline Ostream &ostream_highres_count(Ostream &ostream, const OS_highres_count_t &count)
+{
+ ostream << count;
+ return ostream;
+}
+
+inline OS_highres_count_t system_highres_count_subtract(const OS_highres_count_t &l, const OS_highres_count_t &r)
+{ return l - r; }
+
+inline bool system_highres_count_less(const OS_highres_count_t &l, const OS_highres_count_t &r)
+{ return l < r; }
+
+inline void thread_sleep_tick()
+{ winapi::sleep_tick(); }
+
 inline void thread_yield()
 { winapi::sched_yield(); }
 
@@ -98,6 +185,13 @@
               CreationTime.dwLowDateTime*resolution;
 }
 
+inline unsigned int get_num_cores()
+{
+ winapi::system_info sysinfo;
+ winapi::get_system_info( &sysinfo );
+ //in Windows dw is long which is equal in bits to int
+ return static_cast<unsigned>(sysinfo.dwNumberOfProcessors);
+}
 
 #else //#if (defined BOOST_INTERPROCESS_WINDOWS)
 
@@ -165,9 +259,132 @@
 inline void thread_yield()
 { ::sched_yield(); }
 
+#ifndef BOOST_INTERPROCESS_MATCH_ABSOLUTE_TIME
+typedef struct timespec OS_highres_count_t;
+#else
+typedef unsigned long long OS_highres_count_t;
+#endif
+
+inline unsigned long get_system_tick_ns()
+{
+ #ifdef _SC_CLK_TCK
+ long hz =::sysconf(_SC_CLK_TCK); // ticks per sec
+ if(hz <= 0){ //Try a typical value on error
+ hz = 100;
+ }
+ return 999999999ul/static_cast<unsigned long>(hz)+1ul;
+ #else
+ #error "Can't obtain system tick value for your system, please provide a patch"
+ #endif
+}
+
+inline OS_highres_count_t get_system_tick_in_highres_counts()
+{
+ #ifndef BOOST_INTERPROCESS_MATCH_ABSOLUTE_TIME
+ struct timespec ts;
+ ts.tv_sec = 0;
+ ts.tv_nsec = get_system_tick_ns();
+ return ts;
+ #else
+ mach_timebase_info_data_t info;
+ mach_timebase_info(&info);
+ //ns
+ return static_cast<OS_highres_count_t>
+ (
+ static_cast<double>(get_system_tick_ns())
+ / (static_cast<double>(info.numer) / info.denom)
+ );
+ #endif
+}
+
+//return system ticks in us
+inline unsigned long get_system_tick_us()
+{
+ return (get_system_tick_ns()-1)/1000ul + 1ul;
+}
+
+inline OS_highres_count_t get_current_system_highres_count()
+{
+ #if defined(BOOST_INTERPROCESS_CLOCK_MONOTONIC)
+ struct timespec count;
+ ::clock_gettime(BOOST_INTERPROCESS_CLOCK_MONOTONIC, &count);
+ return count;
+ #elif defined(BOOST_INTERPROCESS_MATCH_ABSOLUTE_TIME)
+ return ::mach_absolute_time();
+ #endif
+}
+
+#ifndef BOOST_INTERPROCESS_MATCH_ABSOLUTE_TIME
+
+inline void zero_highres_count(OS_highres_count_t &count)
+{ count.tv_sec = 0; count.tv_nsec = 0; }
+
+inline bool is_highres_count_zero(const OS_highres_count_t &count)
+{ return count.tv_sec == 0 && count.tv_nsec == 0; }
+
+template <class Ostream>
+inline Ostream &ostream_highres_count(Ostream &ostream, const OS_highres_count_t &count)
+{
+ ostream << count.tv_sec << "s:" << count.tv_nsec << "ns";
+ return ostream;
+}
+
+inline OS_highres_count_t system_highres_count_subtract(const OS_highres_count_t &l, const OS_highres_count_t &r)
+{
+ OS_highres_count_t res;
+
+ if (l.tv_nsec < r.tv_nsec){
+ res.tv_nsec = 1000000000 + l.tv_nsec - r.tv_nsec;
+ res.tv_sec = l.tv_sec - 1 - r.tv_sec;
+ }
+ else{
+ res.tv_nsec = l.tv_nsec - r.tv_nsec;
+ res.tv_sec = l.tv_sec - r.tv_sec;
+ }
+
+ return res;
+}
+
+inline bool system_highres_count_less(const OS_highres_count_t &l, const OS_highres_count_t &r)
+{ return l.tv_sec < r.tv_sec || (l.tv_sec == r.tv_sec && l.tv_nsec < r.tv_nsec); }
+
+#else
+
+inline void zero_highres_count(OS_highres_count_t &count)
+{ count = 0; }
+
+inline bool is_highres_count_zero(const OS_highres_count_t &count)
+{ return count == 0; }
+
+template <class Ostream>
+inline Ostream &ostream_highres_count(Ostream &ostream, const OS_highres_count_t &count)
+{
+ ostream << count ;
+ return ostream;
+}
+
+inline OS_highres_count_t system_highres_count_subtract(const OS_highres_count_t &l, const OS_highres_count_t &r)
+{ return l - r; }
+
+inline bool system_highres_count_less(const OS_highres_count_t &l, const OS_highres_count_t &r)
+{ return l < r; }
+
+#endif
+
+inline void thread_sleep_tick()
+{
+ struct timespec rqt;
+ //Sleep for the half of the tick time
+ rqt.tv_sec = 0;
+ rqt.tv_nsec = get_system_tick_ns()/2;
+ ::nanosleep(&rqt, 0);
+}
+
 inline void thread_sleep(unsigned int ms)
 {
- const struct timespec rqt = { ms/1000u, (ms%1000u)*1000000u };
+ struct timespec rqt;
+ rqt.tv_sec = ms/1000u;
+ rqt.tv_nsec = (ms%1000u)*1000000u;
    ::nanosleep(&rqt, 0);
 }
 
@@ -190,6 +407,39 @@
 inline long double get_current_process_creation_time()
 { return 0.0L; }
 
+inline unsigned int get_num_cores()
+{
+ #ifdef _SC_NPROCESSORS_ONLN
+ long cores = ::sysconf(_SC_NPROCESSORS_ONLN);
+ // sysconf returns -1 if the name is invalid, the option does not exist or
+ // does not have a definite limit.
+ // if sysconf returns some other negative number, we have no idea
+ // what is going on. Default to something safe.
+ if(cores <= 0){
+ return 1;
+ }
+ //Check for overflow (unlikely)
+ else if(static_cast<unsigned long>(cores) >=
+ static_cast<unsigned long>(static_cast<unsigned int>(-1))){
+ return static_cast<unsigned int>(-1);
+ }
+ else{
+ return static_cast<unsigned int>(cores);
+ }
+ #elif defined(BOOST_INTERPROCESS_BSD_DERIVATIVE) && defined(HW_NCPU)
+ int request[2] = { CTL_HW, HW_NCPU };
+ int num_cores;
+ std::size_t result_len = sizeof(num_cores);
+ if ( (::sysctl (request, 2, &num_cores, &result_len, 0, 0) < 0) || (num_cores <= 0) ){
+ //Return a safe value
+ return 1;
+ }
+ else{
+ return static_cast<unsigned int>(num_cores);
+ }
+ #endif
+}
+
 #endif //#if (defined BOOST_INTERPROCESS_WINDOWS)
 
 typedef char pid_str_t[sizeof(OS_process_id_t)*3+1];

Modified: branches/release/boost/interprocess/detail/robust_emulation.hpp
==============================================================================
--- branches/release/boost/interprocess/detail/robust_emulation.hpp Sun Sep 8 15:29:06 2013 (r85614)
+++ branches/release/boost/interprocess/detail/robust_emulation.hpp 2013-09-08 16:07:03 EDT (Sun, 08 Sep 2013) (r85615)
@@ -24,6 +24,7 @@
 #include <boost/interprocess/detail/tmp_dir_helpers.hpp>
 #include <boost/interprocess/detail/intermodule_singleton.hpp>
 #include <boost/interprocess/exceptions.hpp>
+#include <boost/interprocess/sync/spin/wait.hpp>
 #include <string>
 
 namespace boost{
@@ -228,7 +229,7 @@
 
    //Now the logic. Try to lock, if successful mark the owner
    //if it fails, start recovery logic
- unsigned int spin_count = 0;
+ spin_wait swait;
    while(1){
       if (mtx.try_lock()){
          atomic_write32(&this->owner, get_current_process_id());
@@ -236,14 +237,10 @@
       }
       else{
          //Do the dead owner checking each spin_threshold lock tries
- yield(spin_count);
- ++spin_count;
- if(spin_count > spin_threshold){
+ swait.yield();
+ if(0 == (swait.count() & 255u)){
             //Check if owner dead and take ownership if possible
- if(!this->robust_check()){
- spin_count = 0;
- }
- else{
+ if(this->robust_check()){
                break;
             }
          }
@@ -292,7 +289,7 @@
    if(now >= abs_time)
       return this->try_lock();
 
- unsigned k = 0;
+ spin_wait swait;
    do{
       if(this->try_lock()){
          break;
@@ -303,7 +300,7 @@
          return this->try_lock();
       }
       // relinquish current time slice
- ipcdetail::yield(k++);
+ swait.yield();
    }while (true);
 
    return true;

Modified: branches/release/boost/interprocess/detail/tmp_dir_helpers.hpp
==============================================================================
--- branches/release/boost/interprocess/detail/tmp_dir_helpers.hpp Sun Sep 8 15:29:06 2013 (r85614)
+++ branches/release/boost/interprocess/detail/tmp_dir_helpers.hpp 2013-09-08 16:07:03 EDT (Sun, 08 Sep 2013) (r85615)
@@ -58,7 +58,7 @@
          struct ::timeval result;
          std::size_t result_len = sizeof result;
 
- if (::sysctl (request, 2, &result, &result_len, NULL, 0) < 0)
+ if (::sysctl (request, 2, &result, &result_len, 0, 0) < 0)
             return;
 
          char bootstamp_str[256];

Modified: branches/release/boost/interprocess/detail/win32_api.hpp
==============================================================================
--- branches/release/boost/interprocess/detail/win32_api.hpp Sun Sep 8 15:29:06 2013 (r85614)
+++ branches/release/boost/interprocess/detail/win32_api.hpp 2013-09-08 16:07:03 EDT (Sun, 08 Sep 2013) (r85615)
@@ -883,6 +883,7 @@
    , interprocess_filetime *lpExitTime,interprocess_filetime *lpKernelTime
    , interprocess_filetime *lpUserTime );
 extern "C" __declspec(dllimport) void __stdcall Sleep(unsigned long);
+extern "C" __declspec(dllimport) unsigned long __stdcall GetTickCount(void);
 extern "C" __declspec(dllimport) int __stdcall SwitchToThread();
 extern "C" __declspec(dllimport) unsigned long __stdcall GetLastError();
 extern "C" __declspec(dllimport) void __stdcall SetLastError(unsigned long);
@@ -943,7 +944,6 @@
 extern "C" __declspec(dllimport) void *__stdcall GetProcAddress(void *, const char*);
 extern "C" __declspec(dllimport) void *__stdcall GetModuleHandleA(const char*);
 extern "C" __declspec(dllimport) void *__stdcall GetFileInformationByHandle(void *, interprocess_by_handle_file_information*);
-extern "C" __declspec(dllimport) int __stdcall QueryPerformanceCounter(__int64 *lpPerformanceCount);
 
 //Advapi32.dll
 extern "C" __declspec(dllimport) long __stdcall RegOpenKeyExA(void *, const char *, unsigned long, unsigned long, void **);
@@ -1013,6 +1013,12 @@
 typedef long (__stdcall *NtQueryInformationFile_t)(void *,io_status_block_t *,void *, long, int);
 typedef long (__stdcall *NtOpenFile_t)(void*,unsigned long ,object_attributes_t*,io_status_block_t*,unsigned long,unsigned long);
 typedef long (__stdcall *NtClose_t) (void*);
+typedef long (__stdcall *NtQueryTimerResolution_t) (unsigned long* LowestResolution, unsigned long* HighestResolution, unsigned long* CurrentResolution);
+typedef long (__stdcall *NtSetTimerResolution_t) (unsigned long RequestedResolution, int Set, unsigned long* ActualResolution);
+
+//kernel32.dll
+typedef int (__stdcall *QueryPerformanceCounter_t) (__int64 *lpPerformanceCount);
+typedef int (__stdcall *QueryPerformanceFrequency_t)(__int64 *lpFrequency);
 
 } //namespace winapi {
 } //namespace interprocess {
@@ -1047,10 +1053,13 @@
 inline void sched_yield()
 {
    if(!SwitchToThread()){
- Sleep(1);
+ Sleep(0);
    }
 }
 
+inline void sleep_tick()
+{ Sleep(1); }
+
 inline void sleep(unsigned long ms)
 { Sleep(ms); }
 
@@ -1270,11 +1279,6 @@
 inline long reg_close_key(void *hKey)
 { return RegCloseKey(hKey); }
 
-inline bool query_performance_counter(__int64 *lpPerformanceCount)
-{
- return 0 != QueryPerformanceCounter(lpPerformanceCount);
-}
-
 inline void initialize_object_attributes
 ( object_attributes_t *pobject_attr, unicode_string_t *name
  , unsigned long attr, void *rootdir, void *security_descr)
@@ -1299,8 +1303,20 @@
 template<int Dummy>
 struct function_address_holder
 {
- enum { NtSetInformationFile, NtQuerySystemInformation, NtQueryObject, NtQuerySemaphore, NtQuerySection, NtOpenFile, NtClose, NumFunction };
- enum { NtDll_dll, NumModule };
+ enum { NtSetInformationFile
+ , NtQuerySystemInformation
+ , NtQueryObject
+ , NtQuerySemaphore
+ , NtQuerySection
+ , NtOpenFile
+ , NtClose
+ , NtQueryTimerResolution
+ , NtSetTimerResolution
+ , QueryPerformanceCounter
+ , QueryPerformanceFrequency
+ , NumFunction
+ };
+ enum { NtDll_dll, Kernel32_dll, NumModule };
 
    private:
    static const char *FunctionNames[NumFunction];
@@ -1314,21 +1330,26 @@
    static void *get_module_from_id(unsigned int id)
    {
       BOOST_ASSERT(id < (unsigned int)NumModule);
- return get_module_handle(ModuleNames[id]);
+ void *addr = get_module_handle(ModuleNames[id]);
+ BOOST_ASSERT(addr);
+ return addr;
    }
 
    static void *get_module(const unsigned int id)
    {
       BOOST_ASSERT(id < (unsigned int)NumModule);
- while(ModuleStates[id] < 2){
+ for(unsigned i = 0; ModuleStates[id] < 2; ++i){
          if(interlocked_compare_exchange(&ModuleStates[id], 1, 0) == 0){
             ModuleAddresses[id] = get_module_from_id(id);
             interlocked_increment(&ModuleStates[id]);
             break;
          }
- else{
+ else if(i & 1){
             sched_yield();
          }
+ else{
+ sleep_tick();
+ }
       }
       return ModuleAddresses[id];
    }
@@ -1336,22 +1357,27 @@
    static void *get_address_from_dll(const unsigned int id)
    {
       BOOST_ASSERT(id < (unsigned int)NumFunction);
- return get_proc_address(get_module(FunctionModules[id]), FunctionNames[id]);
+ void *addr = get_proc_address(get_module(FunctionModules[id]), FunctionNames[id]);
+ BOOST_ASSERT(addr);
+ return addr;
    }
 
    public:
    static void *get(const unsigned int id)
    {
       BOOST_ASSERT(id < (unsigned int)NumFunction);
- while(FunctionStates[id] < 2){
+ for(unsigned i = 0; FunctionStates[id] < 2; ++i){
          if(interlocked_compare_exchange(&FunctionStates[id], 1, 0) == 0){
             FunctionAddresses[id] = get_address_from_dll(id);
             interlocked_increment(&FunctionStates[id]);
             break;
          }
- else{
+ else if(i & 1){
             sched_yield();
          }
+ else{
+ sleep_tick();
+ }
       }
       return FunctionAddresses[id];
    }
@@ -1366,7 +1392,11 @@
    "NtQuerySemaphore",
    "NtQuerySection",
    "NtOpenFile",
- "NtClose"
+ "NtClose",
+ "NtQueryTimerResolution",
+ "NtSetTimerResolution",
+ "QueryPerformanceCounter",
+ "QueryPerformanceFrequency"
 };
 
 template<int Dummy>
@@ -1378,13 +1408,18 @@
    NtDll_dll,
    NtDll_dll,
    NtDll_dll,
- NtDll_dll
+ NtDll_dll,
+ NtDll_dll,
+ NtDll_dll,
+ Kernel32_dll,
+ Kernel32_dll
 };
 
 template<int Dummy>
 const char *function_address_holder<Dummy>::ModuleNames[function_address_holder<Dummy>::NumModule] =
 {
- "ntdll.dll"
+ "ntdll.dll",
+ "kernel32.dll"
 };
 
 
@@ -1549,7 +1584,7 @@
       delete[]m_buf;
    }
 
- void realloc(std::size_t num_bytes)
+ void realloc_mem(std::size_t num_bytes)
    {
       num_bytes += rename_suffix + rename_offset;
       char *buf = m_buf;
@@ -1584,7 +1619,7 @@
       if(m_buf) ::free(m_buf);
    }
 
- void realloc(std::size_t num_bytes)
+ void realloc_mem(std::size_t num_bytes)
    {
       void *buf = ::realloc(m_buf, num_bytes);
       if(!buf){
@@ -1639,7 +1674,7 @@
          //Obtain file name with guessed length
          if(pNtQueryObject(fh, object_name_information, nt_query_mem.query_mem(), nt_query_mem.object_name_information_size(), &size)){
             //Obtain file name with exact length buffer
- nt_query_mem.realloc(size);
+ nt_query_mem.realloc_mem(size);
             if(pNtQueryObject(fh, object_name_information, nt_query_mem.query_mem(), nt_query_mem.object_name_information_size(), &size)){
                return false;
             }
@@ -2021,7 +2056,7 @@
                if (error_insufficient_buffer == status) {
                   status = 0;
                   dwBytesToRead = dwMinimumBytesToRead;
- heap_deleter.realloc(dwMinimumBytesToRead);
+ heap_deleter.realloc_mem(dwMinimumBytesToRead);
                   if (!heap_deleter.get()){
                      return false;
                   }
@@ -2065,11 +2100,8 @@
    interprocess_section_basic_information info;
    unsigned long ntstatus =
       pNtQuerySection(file_mapping_hnd, section_basic_information, &info, sizeof(info), 0);
- if(ntstatus){
- return false;
- }
    size = info.section_size;
- return true;
+ return !ntstatus;
 }
 
 inline bool get_semaphore_info(void *handle, long &count, long &limit)
@@ -2079,14 +2111,41 @@
          (winapi::NtQuerySemaphore_t)dll_func::get(winapi::dll_func::NtQuerySemaphore);
    unsigned int ret_len;
    long status = pNtQuerySemaphore(handle, winapi::semaphore_basic_information, &info, sizeof(info), &ret_len);
- if(status){
- return false;
- }
    count = info.count;
    limit = info.limit;
- return true;
+ return !status;
+}
+
+inline bool query_timer_resolution(unsigned long *lowres, unsigned long *highres, unsigned long *curres)
+{
+ winapi::NtQueryTimerResolution_t pNtQueryTimerResolution =
+ (winapi::NtQueryTimerResolution_t)dll_func::get(winapi::dll_func::NtQueryTimerResolution);
+ return !pNtQueryTimerResolution(lowres, highres, curres);
+}
+
+inline bool set_timer_resolution(unsigned long RequestedResolution, int Set, unsigned long* ActualResolution)
+{
+ winapi::NtSetTimerResolution_t pNtSetTimerResolution =
+ (winapi::NtSetTimerResolution_t)dll_func::get(winapi::dll_func::NtSetTimerResolution);
+ return !pNtSetTimerResolution(RequestedResolution, Set, ActualResolution);
+}
+
+inline bool query_performance_counter(__int64 *lpPerformanceCount)
+{
+ QueryPerformanceCounter_t pQueryPerformanceCounter = (QueryPerformanceCounter_t)
+ dll_func::get(dll_func::QueryPerformanceCounter);
+ return 0 != pQueryPerformanceCounter(lpPerformanceCount);
+}
+
+inline bool query_performance_frequency(__int64 *lpFrequency)
+{
+ QueryPerformanceCounter_t pQueryPerformanceFrequency = (QueryPerformanceFrequency_t)
+ dll_func::get(dll_func::QueryPerformanceFrequency);
+ return 0 != pQueryPerformanceFrequency(lpFrequency);
 }
 
+inline unsigned long get_tick_count()
+{ return GetTickCount(); }
 
 } //namespace winapi
 } //namespace interprocess

Deleted: branches/release/boost/interprocess/detail/yield_k.hpp
==============================================================================
--- branches/release/boost/interprocess/detail/yield_k.hpp 2013-09-08 16:07:03 EDT (Sun, 08 Sep 2013) (r85614)
+++ /dev/null 00:00:00 1970 (deleted)
@@ -1,136 +0,0 @@
-//This file was copied from boost/smart_ptr/detail and
-//modified here to avoid dependencies with that library
-#ifndef BOOST_INTERPROCESS_DETAIL_YIELD_K_HPP_INCLUDED
-#define BOOST_INTERPROCESS_DETAIL_YIELD_K_HPP_INCLUDED
-
-// MS compatible compilers support #pragma once
-
-#if defined(_MSC_VER) && (_MSC_VER >= 1020)
-# pragma once
-#endif
-
-//
-// yield_k.hpp
-//
-// Copyright (c) 2008 Peter Dimov
-//
-// void yield( unsigned k );
-//
-// Typical use:
-//
-// for( unsigned k = 0; !try_lock(); ++k ) yield( k );
-//
-// Distributed under the Boost Software License, Version 1.0.
-// See accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt
-//
-
-#include <boost/interprocess/detail/config_begin.hpp>
-#include <boost/interprocess/detail/workaround.hpp>
-
-// BOOST_INTERPROCESS_SMT_PAUSE
-
-#if defined(_MSC_VER) && _MSC_VER >= 1310 && ( defined(_M_IX86) || defined(_M_X64) )
-
-extern "C" void _mm_pause();
-#pragma intrinsic( _mm_pause )
-
-#define BOOST_INTERPROCESS_SMT_PAUSE _mm_pause();
-
-#elif defined(__GNUC__) && ( defined(__i386__) || defined(__x86_64__) )
-
-#define BOOST_INTERPROCESS_SMT_PAUSE __asm__ __volatile__( "rep; nop" : : : "memory" );
-
-#endif
-
-//
-
-#if defined (BOOST_INTERPROCESS_WINDOWS)
-
-#include <boost/interprocess/detail/win32_api.hpp>
-
-namespace boost
-{
-namespace interprocess
-{
-namespace ipcdetail
-{
-
-inline void yield( unsigned k )
-{
- if( k < 4 )
- {
- }
-#if defined( BOOST_INTERPROCESS_SMT_PAUSE )
- else if( k < 16 ){
- BOOST_INTERPROCESS_SMT_PAUSE
- }
-#endif
- else if( k < 32 ){
- //Try to yield to another thread running on the current processor
- if(!winapi::SwitchToThread()){
- //If not yield to any thread of same or higher priority on any processor
- boost::interprocess::winapi::Sleep(0);
- }
- }
- else{
- //Yields to any thread on any processor
- boost::interprocess::winapi::Sleep(1);
- }
-}
-
-} // namespace ipcdetail
-} // namespace interprocess
-} // namespace boost
-
-#else
-
-#include <sched.h>
-#include <time.h>
-
-namespace boost
-{
-namespace interprocess
-{
-namespace ipcdetail
-{
-
-inline void yield( unsigned k )
-{
- if( k < 4 )
- {
- }
-#if defined( BOOST_INTERPROCESS_SMT_PAUSE )
- else if( k < 16 )
- {
- BOOST_INTERPROCESS_SMT_PAUSE
- }
-#endif
- else if( k < 32 || k & 1 )
- {
- sched_yield();
- }
- else
- {
- // g++ -Wextra warns on {} or {0}
- struct timespec rqtp = { 0, 0 };
-
- // POSIX says that timespec has tv_sec and tv_nsec
- // But it doesn't guarantee order or placement
-
- rqtp.tv_sec = 0;
- rqtp.tv_nsec = 1000;
-
- nanosleep( &rqtp, 0 );
- }
-}
-
-} // namespace ipcdetail
-} // namespace interprocess
-} // namespace boost
-
-#endif
-
-#include <boost/interprocess/detail/config_end.hpp>
-
-#endif // #ifndef BOOST_INTERPROCESS_DETAIL_YIELD_K_HPP_INCLUDED

Modified: branches/release/boost/interprocess/smart_ptr/detail/sp_counted_impl.hpp
==============================================================================
--- branches/release/boost/interprocess/smart_ptr/detail/sp_counted_impl.hpp Sun Sep 8 15:29:06 2013 (r85614)
+++ branches/release/boost/interprocess/smart_ptr/detail/sp_counted_impl.hpp 2013-09-08 16:07:03 EDT (Sun, 08 Sep 2013) (r85615)
@@ -83,6 +83,8 @@
          portable_rebind_alloc
             < const this_type >::type const_this_allocator;
    typedef typename this_allocator::pointer this_pointer;
+ typedef typename boost::intrusive::
+ pointer_traits<this_pointer> this_pointer_traits;
 
    sp_counted_impl_pd( sp_counted_impl_pd const & );
    sp_counted_impl_pd & operator= ( sp_counted_impl_pd const & );
@@ -115,11 +117,10 @@
 
    void destroy() // nothrow
    {
- //Self destruction, so get a copy of the allocator
- //(in the future we could move it)
- this_allocator a_copy(*this);
+ //Self destruction, so move the allocator
+ this_allocator a_copy(::boost::move(static_cast<this_allocator&>(*this)));
       BOOST_ASSERT(a_copy == *this);
- this_pointer this_ptr (this);
+ this_pointer this_ptr(this_pointer_traits::pointer_to(*this));
       //Do it now!
       scoped_ptr< this_type, scoped_ptr_dealloc_functor<this_allocator> >
          deleter_ptr(this_ptr, a_copy);

Modified: branches/release/boost/interprocess/streams/bufferstream.hpp
==============================================================================
--- branches/release/boost/interprocess/streams/bufferstream.hpp Sun Sep 8 15:29:06 2013 (r85614)
+++ branches/release/boost/interprocess/streams/bufferstream.hpp 2013-09-08 16:07:03 EDT (Sun, 08 Sep 2013) (r85615)
@@ -251,8 +251,11 @@
 //!A basic_istream class that uses a fixed size character buffer
 //!as its formatting buffer.
 template <class CharT, class CharTraits>
-class basic_ibufferstream
- : public std::basic_istream<CharT, CharTraits>
+class basic_ibufferstream :
+ /// @cond
+ private basic_bufferbuf<CharT, CharTraits>,
+ /// @endcond
+ public std::basic_istream<CharT, CharTraits>
 {
    public: // Typedefs
    typedef typename std::basic_ios
@@ -262,24 +265,40 @@
    typedef typename std::basic_ios<char_type, CharTraits>::off_type off_type;
    typedef typename std::basic_ios<char_type, CharTraits>::traits_type traits_type;
 
+ /// @cond
    private:
- typedef std::basic_ios<char_type, CharTraits> basic_ios_t;
- typedef std::basic_istream<char_type, CharTraits> base_t;
+ typedef basic_bufferbuf<CharT, CharTraits> bufferbuf_t;
+ typedef std::basic_ios<char_type, CharTraits> basic_ios_t;
+ typedef std::basic_istream<char_type, CharTraits> base_t;
+ bufferbuf_t & get_buf() { return *this; }
+ const bufferbuf_t & get_buf() const{ return *this; }
+ /// @endcond
 
    public:
    //!Constructor.
    //!Does not throw.
    basic_ibufferstream(std::ios_base::openmode mode = std::ios_base::in)
- : basic_ios_t(), base_t(0), m_buf(mode | std::ios_base::in)
- { basic_ios_t::init(&m_buf); }
+ : //basic_ios_t() is called first (lefting it uninitialized) as it's a
+ //virtual base of basic_istream. The class will be initialized when
+ //basic_istream is constructed calling basic_ios_t::init().
+ //As bufferbuf_t's constructor does not throw there is no risk of
+ //calling the basic_ios_t's destructor without calling basic_ios_t::init()
+ bufferbuf_t(mode | std::ios_base::in)
+ , base_t(&get_buf())
+ {}
 
    //!Constructor. Assigns formatting buffer.
    //!Does not throw.
    basic_ibufferstream(const CharT *buf, std::size_t length,
                        std::ios_base::openmode mode = std::ios_base::in)
- : basic_ios_t(), base_t(0),
- m_buf(const_cast<CharT*>(buf), length, mode | std::ios_base::in)
- { basic_ios_t::init(&m_buf); }
+ : //basic_ios_t() is called first (lefting it uninitialized) as it's a
+ //virtual base of basic_istream. The class will be initialized when
+ //basic_istream is constructed calling basic_ios_t::init().
+ //As bufferbuf_t's constructor does not throw there is no risk of
+ //calling the basic_ios_t's destructor without calling basic_ios_t::init()
+ bufferbuf_t(const_cast<CharT*>(buf), length, mode | std::ios_base::in)
+ , base_t(&get_buf())
+ {}
 
    ~basic_ibufferstream(){};
 
@@ -287,29 +306,27 @@
    //!Returns the address of the stored
    //!stream buffer.
    basic_bufferbuf<CharT, CharTraits>* rdbuf() const
- { return const_cast<basic_bufferbuf<CharT, CharTraits>*>(&m_buf); }
+ { return const_cast<basic_bufferbuf<CharT, CharTraits>*>(&get_buf()); }
 
    //!Returns the pointer and size of the internal buffer.
    //!Does not throw.
    std::pair<const CharT *, std::size_t> buffer() const
- { return m_buf.buffer(); }
+ { return get_buf().buffer(); }
 
    //!Sets the underlying buffer to a new value. Resets
    //!stream position. Does not throw.
    void buffer(const CharT *buf, std::size_t length)
- { m_buf.buffer(const_cast<CharT*>(buf), length); }
-
- /// @cond
- private:
- basic_bufferbuf<CharT, CharTraits> m_buf;
- /// @endcond
+ { get_buf().buffer(const_cast<CharT*>(buf), length); }
 };
 
 //!A basic_ostream class that uses a fixed size character buffer
 //!as its formatting buffer.
 template <class CharT, class CharTraits>
-class basic_obufferstream
- : public std::basic_ostream<CharT, CharTraits>
+class basic_obufferstream :
+ /// @cond
+ private basic_bufferbuf<CharT, CharTraits>,
+ /// @endcond
+ public std::basic_ostream<CharT, CharTraits>
 {
    public:
    typedef typename std::basic_ios
@@ -321,23 +338,38 @@
 
    /// @cond
    private:
+ typedef basic_bufferbuf<CharT, CharTraits> bufferbuf_t;
    typedef std::basic_ios<char_type, CharTraits> basic_ios_t;
    typedef std::basic_ostream<char_type, CharTraits> base_t;
+ bufferbuf_t & get_buf() { return *this; }
+ const bufferbuf_t & get_buf() const{ return *this; }
    /// @endcond
+
    public:
    //!Constructor.
    //!Does not throw.
    basic_obufferstream(std::ios_base::openmode mode = std::ios_base::out)
- : basic_ios_t(), base_t(0), m_buf(mode | std::ios_base::out)
- { basic_ios_t::init(&m_buf); }
+ : //basic_ios_t() is called first (lefting it uninitialized) as it's a
+ //virtual base of basic_istream. The class will be initialized when
+ //basic_istream is constructed calling basic_ios_t::init().
+ //As bufferbuf_t's constructor does not throw there is no risk of
+ //calling the basic_ios_t's destructor without calling basic_ios_t::init()
+ bufferbuf_t(mode | std::ios_base::out)
+ , base_t(&get_buf())
+ {}
 
    //!Constructor. Assigns formatting buffer.
    //!Does not throw.
    basic_obufferstream(CharT *buf, std::size_t length,
                        std::ios_base::openmode mode = std::ios_base::out)
- : basic_ios_t(), base_t(0),
- m_buf(buf, length, mode | std::ios_base::out)
- { basic_ios_t::init(&m_buf); }
+ : //basic_ios_t() is called first (lefting it uninitialized) as it's a
+ //virtual base of basic_istream. The class will be initialized when
+ //basic_istream is constructed calling basic_ios_t::init().
+ //As bufferbuf_t's constructor does not throw there is no risk of
+ //calling the basic_ios_t's destructor without calling basic_ios_t::init()
+ bufferbuf_t(buf, length, mode | std::ios_base::out)
+ , base_t(&get_buf())
+ {}
 
    ~basic_obufferstream(){}
 
@@ -345,31 +377,28 @@
    //!Returns the address of the stored
    //!stream buffer.
    basic_bufferbuf<CharT, CharTraits>* rdbuf() const
- { return const_cast<basic_bufferbuf<CharT, CharTraits>*>(&m_buf); }
+ { return const_cast<basic_bufferbuf<CharT, CharTraits>*>(&get_buf()); }
 
    //!Returns the pointer and size of the internal buffer.
    //!Does not throw.
    std::pair<CharT *, std::size_t> buffer() const
- { return m_buf.buffer(); }
+ { return get_buf().buffer(); }
 
    //!Sets the underlying buffer to a new value. Resets
    //!stream position. Does not throw.
    void buffer(CharT *buf, std::size_t length)
- { m_buf.buffer(buf, length); }
-
- /// @cond
- private:
- basic_bufferbuf<CharT, CharTraits> m_buf;
- /// @endcond
+ { get_buf().buffer(buf, length); }
 };
 
 
 //!A basic_iostream class that uses a fixed size character buffer
 //!as its formatting buffer.
 template <class CharT, class CharTraits>
-class basic_bufferstream
- : public std::basic_iostream<CharT, CharTraits>
-
+class basic_bufferstream :
+ /// @cond
+ private basic_bufferbuf<CharT, CharTraits>,
+ /// @endcond
+ public std::basic_iostream<CharT, CharTraits>
 {
    public: // Typedefs
    typedef typename std::basic_ios
@@ -381,8 +410,11 @@
 
    /// @cond
    private:
- typedef std::basic_ios<char_type, CharTraits> basic_ios_t;
- typedef std::basic_iostream<char_type, CharTraits> base_t;
+ typedef basic_bufferbuf<CharT, CharTraits> bufferbuf_t;
+ typedef std::basic_ios<char_type, CharTraits> basic_ios_t;
+ typedef std::basic_iostream<char_type, CharTraits> base_t;
+ bufferbuf_t & get_buf() { return *this; }
+ const bufferbuf_t & get_buf() const{ return *this; }
    /// @endcond
 
    public:
@@ -390,16 +422,28 @@
    //!Does not throw.
    basic_bufferstream(std::ios_base::openmode mode
                       = std::ios_base::in | std::ios_base::out)
- : basic_ios_t(), base_t(0), m_buf(mode)
- { basic_ios_t::init(&m_buf); }
+ : //basic_ios_t() is called first (lefting it uninitialized) as it's a
+ //virtual base of basic_istream. The class will be initialized when
+ //basic_istream is constructed calling basic_ios_t::init().
+ //As bufferbuf_t's constructor does not throw there is no risk of
+ //calling the basic_ios_t's destructor without calling basic_ios_t::init()
+ bufferbuf_t(mode)
+ , base_t(&get_buf())
+ {}
 
    //!Constructor. Assigns formatting buffer.
    //!Does not throw.
    basic_bufferstream(CharT *buf, std::size_t length,
                       std::ios_base::openmode mode
                         = std::ios_base::in | std::ios_base::out)
- : basic_ios_t(), base_t(0), m_buf(buf, length, mode)
- { basic_ios_t::init(&m_buf); }
+ : //basic_ios_t() is called first (lefting it uninitialized) as it's a
+ //virtual base of basic_istream. The class will be initialized when
+ //basic_istream is constructed calling basic_ios_t::init().
+ //As bufferbuf_t's constructor does not throw there is no risk of
+ //calling the basic_ios_t's destructor without calling basic_ios_t::init()
+ bufferbuf_t(buf, length, mode)
+ , base_t(&get_buf())
+ {}
 
    ~basic_bufferstream(){}
 
@@ -407,22 +451,17 @@
    //!Returns the address of the stored
    //!stream buffer.
    basic_bufferbuf<CharT, CharTraits>* rdbuf() const
- { return const_cast<basic_bufferbuf<CharT, CharTraits>*>(&m_buf); }
+ { return const_cast<basic_bufferbuf<CharT, CharTraits>*>(&get_buf()); }
 
    //!Returns the pointer and size of the internal buffer.
    //!Does not throw.
    std::pair<CharT *, std::size_t> buffer() const
- { return m_buf.buffer(); }
+ { return get_buf().buffer(); }
 
    //!Sets the underlying buffer to a new value. Resets
    //!stream position. Does not throw.
    void buffer(CharT *buf, std::size_t length)
- { m_buf.buffer(buf, length); }
-
- /// @cond
- private:
- basic_bufferbuf<CharT, CharTraits> m_buf;
- /// @endcond
+ { get_buf().buffer(buf, length); }
 };
 
 //Some typedefs to simplify usage

Modified: branches/release/boost/interprocess/streams/vectorstream.hpp
==============================================================================
--- branches/release/boost/interprocess/streams/vectorstream.hpp Sun Sep 8 15:29:06 2013 (r85614)
+++ branches/release/boost/interprocess/streams/vectorstream.hpp 2013-09-08 16:07:03 EDT (Sun, 08 Sep 2013) (r85615)
@@ -92,8 +92,6 @@
       : base_t(), m_mode(mode), m_vect(param)
    { this->initialize_pointers(); }
 
- virtual ~basic_vectorbuf(){}
-
    public:
 
    //!Swaps the underlying vector with the passed vector.
@@ -367,10 +365,10 @@
 //!boost::interprocess::basic_string
 template <class CharVector, class CharTraits>
 class basic_ivectorstream
+ : public std::basic_istream<typename CharVector::value_type, CharTraits>
    /// @cond
- : private basic_vectorbuf<CharVector, CharTraits>
+ , private basic_vectorbuf<CharVector, CharTraits>
    /// @endcond
- , public std::basic_istream<typename CharVector::value_type, CharTraits>
 {
    public:
    typedef CharVector vector_type;
@@ -384,56 +382,62 @@
    /// @cond
    private:
    typedef basic_vectorbuf<CharVector, CharTraits> vectorbuf_t;
+ typedef std::basic_ios<char_type, CharTraits> basic_ios_t;
    typedef std::basic_istream<char_type, CharTraits> base_t;
 
- vectorbuf_t & m_buf() { return *this; }
- const vectorbuf_t & m_buf() const{ return *this; }
+ vectorbuf_t & get_buf() { return *this; }
+ const vectorbuf_t & get_buf() const{ return *this; }
    /// @endcond
 
    public:
+
    //!Constructor. Throws if vector_type default
    //!constructor throws.
    basic_ivectorstream(std::ios_base::openmode mode = std::ios_base::in)
- : vectorbuf_t(mode | std::ios_base::in), base_t(&m_buf())
- {}
+ : base_t(0) //Initializes first the base class to safely init the virtual basic_ios base
+ //(via basic_ios::init() call in base_t's constructor) without the risk of a
+ //previous throwing vectorbuf constructor. Set the streambuf after risk has gone.
+ , vectorbuf_t(mode | std::ios_base::in)
+ { this->base_t::rdbuf(&get_buf()); }
 
    //!Constructor. Throws if vector_type(const VectorParameter &param)
    //!throws.
    template<class VectorParameter>
    basic_ivectorstream(const VectorParameter &param,
                        std::ios_base::openmode mode = std::ios_base::in)
- : vectorbuf_t(param, mode | std::ios_base::in), base_t(&m_buf())
+ : vectorbuf_t(param, mode | std::ios_base::in)
+ //basic_ios_t() is constructed uninitialized as virtual base
+ //and initialized inside base_t calling basic_ios::init()
+ , base_t(&get_buf())
    {}
 
- ~basic_ivectorstream(){};
-
    public:
    //!Returns the address of the stored
    //!stream buffer.
    basic_vectorbuf<CharVector, CharTraits>* rdbuf() const
- { return const_cast<basic_vectorbuf<CharVector, CharTraits>*>(&m_buf()); }
+ { return const_cast<basic_vectorbuf<CharVector, CharTraits>*>(&get_buf()); }
 
    //!Swaps the underlying vector with the passed vector.
    //!This function resets the read position in the stream.
    //!Does not throw.
    void swap_vector(vector_type &vect)
- { m_buf().swap_vector(vect); }
+ { get_buf().swap_vector(vect); }
 
    //!Returns a const reference to the internal vector.
    //!Does not throw.
    const vector_type &vector() const
- { return m_buf().vector(); }
+ { return get_buf().vector(); }
 
    //!Calls reserve() method of the internal vector.
    //!Resets the stream to the first position.
    //!Throws if the internals vector's reserve throws.
    void reserve(typename vector_type::size_type size)
- { m_buf().reserve(size); }
+ { get_buf().reserve(size); }
 
    //!Calls clear() method of the internal vector.
    //!Resets the stream to the first position.
    void clear()
- { m_buf().clear(); }
+ { get_buf().clear(); }
 };
 
 //!A basic_ostream class that holds a character vector specified by CharVector
@@ -442,10 +446,10 @@
 //!boost::interprocess::basic_string
 template <class CharVector, class CharTraits>
 class basic_ovectorstream
+ : public std::basic_ostream<typename CharVector::value_type, CharTraits>
    /// @cond
- : private basic_vectorbuf<CharVector, CharTraits>
+ , private basic_vectorbuf<CharVector, CharTraits>
    /// @endcond
- , public std::basic_ostream<typename CharVector::value_type, CharTraits>
 {
    public:
    typedef CharVector vector_type;
@@ -459,54 +463,58 @@
    /// @cond
    private:
    typedef basic_vectorbuf<CharVector, CharTraits> vectorbuf_t;
+ typedef std::basic_ios<char_type, CharTraits> basic_ios_t;
    typedef std::basic_ostream<char_type, CharTraits> base_t;
 
- vectorbuf_t & m_buf() { return *this; }
- const vectorbuf_t & m_buf()const { return *this; }
+ vectorbuf_t & get_buf() { return *this; }
+ const vectorbuf_t & get_buf()const { return *this; }
    /// @endcond
 
    public:
    //!Constructor. Throws if vector_type default
    //!constructor throws.
    basic_ovectorstream(std::ios_base::openmode mode = std::ios_base::out)
- : vectorbuf_t(mode | std::ios_base::out), base_t(&m_buf())
- {}
+ : base_t(0) //Initializes first the base class to safely init the virtual basic_ios base
+ //(via basic_ios::init() call in base_t's constructor) without the risk of a
+ //previous throwing vectorbuf constructor. Set the streambuf after risk has gone.
+ , vectorbuf_t(mode | std::ios_base::out)
+ { this->base_t::rdbuf(&get_buf()); }
 
    //!Constructor. Throws if vector_type(const VectorParameter &param)
    //!throws.
    template<class VectorParameter>
    basic_ovectorstream(const VectorParameter &param,
                         std::ios_base::openmode mode = std::ios_base::out)
- : vectorbuf_t(param, mode | std::ios_base::out), base_t(&m_buf())
- {}
-
- ~basic_ovectorstream(){}
+ : base_t(0) //Initializes first the base class to safely init the virtual basic_ios base
+ //(via basic_ios::init() call in base_t's constructor) without the risk of a
+ //previous throwing vectorbuf constructor. Set the streambuf after risk has gone.
+ , vectorbuf_t(param, mode | std::ios_base::out)
+ { this->base_t::rdbuf(&get_buf()); }
 
    public:
    //!Returns the address of the stored
    //!stream buffer.
    basic_vectorbuf<CharVector, CharTraits>* rdbuf() const
- { return const_cast<basic_vectorbuf<CharVector, CharTraits>*>(&m_buf()); }
+ { return const_cast<basic_vectorbuf<CharVector, CharTraits>*>(&get_buf()); }
 
    //!Swaps the underlying vector with the passed vector.
    //!This function resets the write position in the stream.
    //!Does not throw.
    void swap_vector(vector_type &vect)
- { m_buf().swap_vector(vect); }
+ { get_buf().swap_vector(vect); }
 
    //!Returns a const reference to the internal vector.
    //!Does not throw.
    const vector_type &vector() const
- { return m_buf().vector(); }
+ { return get_buf().vector(); }
 
    //!Calls reserve() method of the internal vector.
    //!Resets the stream to the first position.
    //!Throws if the internals vector's reserve throws.
    void reserve(typename vector_type::size_type size)
- { m_buf().reserve(size); }
+ { get_buf().reserve(size); }
 };
 
-
 //!A basic_iostream class that holds a character vector specified by CharVector
 //!template parameter as its formatting buffer. The vector must have
 //!contiguous storage, like std::vector, boost::interprocess::vector or
@@ -514,7 +522,9 @@
 template <class CharVector, class CharTraits>
 class basic_vectorstream
    : public std::basic_iostream<typename CharVector::value_type, CharTraits>
-
+ /// @cond
+ , private basic_vectorbuf<CharVector, CharTraits>
+ /// @endcond
 {
    public:
    typedef CharVector vector_type;
@@ -527,8 +537,12 @@
 
    /// @cond
    private:
- typedef std::basic_ios<char_type, CharTraits> basic_ios_t;
- typedef std::basic_iostream<char_type, CharTraits> base_t;
+ typedef basic_vectorbuf<CharVector, CharTraits> vectorbuf_t;
+ typedef std::basic_ios<char_type, CharTraits> basic_ios_t;
+ typedef std::basic_iostream<char_type, CharTraits> base_t;
+
+ vectorbuf_t & get_buf() { return *this; }
+ const vectorbuf_t & get_buf() const{ return *this; }
    /// @endcond
 
    public:
@@ -536,50 +550,49 @@
    //!constructor throws.
    basic_vectorstream(std::ios_base::openmode mode
                       = std::ios_base::in | std::ios_base::out)
- : basic_ios_t(), base_t(0), m_buf(mode)
- { basic_ios_t::init(&m_buf); }
+ : base_t(0) //Initializes first the base class to safely init the virtual basic_ios base
+ //(via basic_ios::init() call in base_t's constructor) without the risk of a
+ //previous throwing vectorbuf constructor. Set the streambuf after risk has gone.
+ , vectorbuf_t(mode)
+ { this->base_t::rdbuf(&get_buf()); }
 
    //!Constructor. Throws if vector_type(const VectorParameter &param)
    //!throws.
    template<class VectorParameter>
    basic_vectorstream(const VectorParameter &param, std::ios_base::openmode mode
                       = std::ios_base::in | std::ios_base::out)
- : basic_ios_t(), base_t(0), m_buf(param, mode)
- { basic_ios_t::init(&m_buf); }
-
- ~basic_vectorstream(){}
+ : base_t(0) //Initializes first the base class to safely init the virtual basic_ios base
+ //(via basic_ios::init() call in base_t's constructor) without the risk of a
+ //previous throwing vectorbuf constructor. Set the streambuf after risk has gone.
+ , vectorbuf_t(param, mode)
+ { this->base_t::rdbuf(&get_buf()); }
 
    public:
    //Returns the address of the stored stream buffer.
    basic_vectorbuf<CharVector, CharTraits>* rdbuf() const
- { return const_cast<basic_vectorbuf<CharVector, CharTraits>*>(&m_buf); }
+ { return const_cast<basic_vectorbuf<CharVector, CharTraits>*>(&get_buf()); }
 
    //!Swaps the underlying vector with the passed vector.
    //!This function resets the read/write position in the stream.
    //!Does not throw.
    void swap_vector(vector_type &vect)
- { m_buf.swap_vector(vect); }
+ { get_buf().swap_vector(vect); }
 
    //!Returns a const reference to the internal vector.
    //!Does not throw.
    const vector_type &vector() const
- { return m_buf.vector(); }
+ { return get_buf().vector(); }
 
    //!Calls reserve() method of the internal vector.
    //!Resets the stream to the first position.
    //!Throws if the internals vector's reserve throws.
    void reserve(typename vector_type::size_type size)
- { m_buf.reserve(size); }
+ { get_buf().reserve(size); }
 
    //!Calls clear() method of the internal vector.
    //!Resets the stream to the first position.
    void clear()
- { m_buf.clear(); }
-
- /// @cond
- private:
- basic_vectorbuf<CharVector, CharTraits> m_buf;
- /// @endcond
+ { get_buf().clear(); }
 };
 
 //Some typedefs to simplify usage

Modified: branches/release/boost/interprocess/sync/file_lock.hpp
==============================================================================
--- branches/release/boost/interprocess/sync/file_lock.hpp Sun Sep 8 15:29:06 2013 (r85614)
+++ branches/release/boost/interprocess/sync/file_lock.hpp 2013-09-08 16:07:03 EDT (Sun, 08 Sep 2013) (r85615)
@@ -21,6 +21,7 @@
 #include <boost/interprocess/detail/os_file_functions.hpp>
 #include <boost/interprocess/detail/os_thread_functions.hpp>
 #include <boost/interprocess/detail/posix_time_types_wrk.hpp>
+#include <boost/interprocess/sync/spin/wait.hpp>
 #include <boost/move/move.hpp>
 
 //!\file
@@ -149,7 +150,7 @@
       using namespace boost::detail;
 
       if(now >= abs_time) return false;
- unsigned k = 0;
+ spin_wait swait;
       do{
          if(!ipcdetail::try_acquire_file_lock(hnd, acquired))
             return false;
@@ -164,7 +165,7 @@
                return true;
             }
             // relinquish current time slice
- ipcdetail::yield(k++);
+ swait.yield();
          }
       }while (true);
    }
@@ -178,7 +179,7 @@
 
       if(now >= abs_time) return false;
 
- unsigned k = 0;
+ spin_wait swait;
       do{
          if(!ipcdetail::try_acquire_file_lock_sharable(hnd, acquired))
             return false;
@@ -193,7 +194,7 @@
                return true;
             }
             // relinquish current time slice
- ipcdetail::yield(k++);
+ swait.yield();
          }
       }while (true);
    }

Modified: branches/release/boost/interprocess/sync/posix/mutex.hpp
==============================================================================
--- branches/release/boost/interprocess/sync/posix/mutex.hpp Sun Sep 8 15:29:06 2013 (r85614)
+++ branches/release/boost/interprocess/sync/posix/mutex.hpp 2013-09-08 16:07:03 EDT (Sun, 08 Sep 2013) (r85615)
@@ -44,6 +44,7 @@
 
 #ifndef BOOST_INTERPROCESS_POSIX_TIMEOUTS
 # include <boost/interprocess/detail/os_thread_functions.hpp>
+# include <boost/interprocess/sync/spin/wait.hpp>
 #endif
 #include <boost/assert.hpp>
 
@@ -119,7 +120,7 @@
    //Obtain current count and target time
    boost::posix_time::ptime now = microsec_clock::universal_time();
 
- unsigned k = 0;
+ spin_wait swait;
    do{
       if(this->try_lock()){
          break;
@@ -130,7 +131,7 @@
          return false;
       }
       // relinquish current time slice
- ipcdetail::yield(k++);
+ swait.yield();
    }while (true);
    return true;
 

Modified: branches/release/boost/interprocess/sync/posix/recursive_mutex.hpp
==============================================================================
--- branches/release/boost/interprocess/sync/posix/recursive_mutex.hpp Sun Sep 8 15:29:06 2013 (r85614)
+++ branches/release/boost/interprocess/sync/posix/recursive_mutex.hpp 2013-09-08 16:07:03 EDT (Sun, 08 Sep 2013) (r85615)
@@ -38,6 +38,7 @@
 #include <boost/interprocess/exceptions.hpp>
 #ifndef BOOST_INTERPROCESS_POSIX_TIMEOUTS
 # include <boost/interprocess/detail/os_thread_functions.hpp>
+# include <boost/interprocess/sync/spin/wait.hpp>
 #endif
 #include <boost/assert.hpp>
 
@@ -108,7 +109,7 @@
 
    //Obtain current count and target time
    boost::posix_time::ptime now = microsec_clock::universal_time();
- unsigned k = 0;
+ spin_wait swait;
    do{
       if(this->try_lock()){
          break;
@@ -119,7 +120,7 @@
          return false;
       }
       // relinquish current time slice
- yield(k++);
+ swait.yield();
    }while (true);
    return true;
 

Modified: branches/release/boost/interprocess/sync/posix/semaphore_wrapper.hpp
==============================================================================
--- branches/release/boost/interprocess/sync/posix/semaphore_wrapper.hpp Sun Sep 8 15:29:06 2013 (r85614)
+++ branches/release/boost/interprocess/sync/posix/semaphore_wrapper.hpp 2013-09-08 16:07:03 EDT (Sun, 08 Sep 2013) (r85615)
@@ -35,6 +35,7 @@
 #include <boost/interprocess/sync/posix/ptime_to_timespec.hpp>
 #else
 #include <boost/interprocess/detail/os_thread_functions.hpp>
+#include <boost/interprocess/sync/spin/wait.hpp>
 #endif
 
 namespace boost {
@@ -195,11 +196,11 @@
    return false;
    #else //#ifdef BOOST_INTERPROCESS_POSIX_TIMEOUTS
    boost::posix_time::ptime now;
- unsigned k = 0;
+ spin_wait swait;
    do{
       if(semaphore_try_wait(handle))
          return true;
- yield(k++);
+ swait.yield();
    }while((now = microsec_clock::universal_time()) < abs_time);
    return false;
    #endif //#ifdef BOOST_INTERPROCESS_POSIX_TIMEOUTS

Modified: branches/release/boost/interprocess/sync/spin/condition.hpp
==============================================================================
--- branches/release/boost/interprocess/sync/spin/condition.hpp Sun Sep 8 15:29:06 2013 (r85614)
+++ branches/release/boost/interprocess/sync/spin/condition.hpp 2013-09-08 16:07:03 EDT (Sun, 08 Sep 2013) (r85615)
@@ -19,6 +19,7 @@
 #include <boost/interprocess/sync/scoped_lock.hpp>
 #include <boost/interprocess/exceptions.hpp>
 #include <boost/interprocess/detail/os_thread_functions.hpp>
+#include <boost/interprocess/sync/spin/wait.hpp>
 #include <boost/move/move.hpp>
 #include <boost/cstdint.hpp>
 
@@ -140,9 +141,9 @@
    }
 
    //Notify that all threads should execute wait logic
- unsigned k = 0;
+ spin_wait swait;
    while(SLEEP != atomic_cas32(const_cast<boost::uint32_t*>(&m_command), command, SLEEP)){
- yield(k++);
+ swait.yield();
    }
    //The enter mutex will rest locked until the last waiting thread unlocks it
 }
@@ -206,9 +207,9 @@
    while(1){
       //The thread sleeps/spins until a spin_condition commands a notification
       //Notification occurred, we will lock the checking mutex so that
- unsigned k = 0;
+ spin_wait swait;
       while(atomic_read32(&m_command) == SLEEP){
- yield(k++);
+ swait.yield();
 
          //Check for timeout
          if(tout_enabled){

Modified: branches/release/boost/interprocess/sync/spin/mutex.hpp
==============================================================================
--- branches/release/boost/interprocess/sync/spin/mutex.hpp Sun Sep 8 15:29:06 2013 (r85614)
+++ branches/release/boost/interprocess/sync/spin/mutex.hpp 2013-09-08 16:07:03 EDT (Sun, 08 Sep 2013) (r85615)
@@ -22,6 +22,7 @@
 #include <boost/interprocess/detail/atomic.hpp>
 #include <boost/cstdint.hpp>
 #include <boost/interprocess/detail/os_thread_functions.hpp>
+#include <boost/interprocess/sync/spin/wait.hpp>
 
 namespace boost {
 namespace interprocess {
@@ -60,7 +61,7 @@
 
 inline void spin_mutex::lock(void)
 {
- unsigned k = 0;
+ spin_wait swait;
    do{
       boost::uint32_t prev_s = ipcdetail::atomic_cas32(const_cast<boost::uint32_t*>(&m_s), 1, 0);
 
@@ -68,7 +69,7 @@
             break;
       }
       // relinquish current timeslice
- ipcdetail::yield(k++);
+ swait.yield();
    }while (true);
 }
 
@@ -87,7 +88,7 @@
    //Obtain current count and target time
    boost::posix_time::ptime now = microsec_clock::universal_time();
 
- unsigned k = 0;
+ spin_wait swait;
    do{
       if(this->try_lock()){
          break;
@@ -98,7 +99,7 @@
          return false;
       }
       // relinquish current time slice
- ipcdetail::yield(k++);
+ swait.yield();
    }while (true);
 
    return true;

Modified: branches/release/boost/interprocess/sync/spin/semaphore.hpp
==============================================================================
--- branches/release/boost/interprocess/sync/spin/semaphore.hpp Sun Sep 8 15:29:06 2013 (r85614)
+++ branches/release/boost/interprocess/sync/spin/semaphore.hpp 2013-09-08 16:07:03 EDT (Sun, 08 Sep 2013) (r85615)
@@ -20,6 +20,7 @@
 #include <boost/interprocess/detail/atomic.hpp>
 #include <boost/interprocess/detail/os_thread_functions.hpp>
 #include <boost/interprocess/detail/posix_time_types_wrk.hpp>
+#include <boost/interprocess/sync/spin/wait.hpp>
 #include <boost/cstdint.hpp>
 
 namespace boost {
@@ -59,11 +60,9 @@
 
 inline void spin_semaphore::wait()
 {
- unsigned k = 0;
+ spin_wait swait;
    while(!ipcdetail::atomic_add_unless32(&m_count, boost::uint32_t(-1), boost::uint32_t(0))){
- while(ipcdetail::atomic_read32(&m_count) == 0){
- ipcdetail::yield(k++);
- }
+ swait.yield();
    }
 }
 
@@ -81,7 +80,7 @@
    //Obtain current count and target time
    boost::posix_time::ptime now(microsec_clock::universal_time());
 
- unsigned k = 0;
+ spin_wait swait;
    do{
       if(this->try_wait()){
          break;
@@ -92,7 +91,7 @@
          return this->try_wait();
       }
       // relinquish current time slice
- ipcdetail::yield(k++);
+ swait.yield();
    }while (true);
    return true;
 }

Copied: branches/release/boost/interprocess/sync/spin/wait.hpp (from r85614, trunk/boost/interprocess/sync/spin/wait.hpp)
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ branches/release/boost/interprocess/sync/spin/wait.hpp 2013-09-08 16:07:03 EDT (Sun, 08 Sep 2013) (r85615, copy of r85614, trunk/boost/interprocess/sync/spin/wait.hpp)
@@ -0,0 +1,186 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Peter Dimov 2008.
+// (C) Copyright Ion Gaztanaga 2013. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/interprocess for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+//Parts of this file come from boost/smart_ptr/detail/yield_k.hpp
+//Many thanks to Peter Dimov.
+
+#ifndef BOOST_INTERPROCESS_SYNC_WAIT_HPP_INCLUDED
+#define BOOST_INTERPROCESS_SYNC_WAIT_HPP_INCLUDED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+#include <boost/interprocess/detail/config_begin.hpp>
+#include <boost/interprocess/detail/workaround.hpp>
+#include <boost/interprocess/detail/os_thread_functions.hpp>
+
+//#define BOOST_INTERPROCESS_SPIN_WAIT_DEBUG
+#ifdef BOOST_INTERPROCESS_SPIN_WAIT_DEBUG
+#include <iostream>
+#endif
+
+// BOOST_INTERPROCESS_SMT_PAUSE
+
+#if defined(_MSC_VER) && _MSC_VER >= 1310 && ( defined(_M_IX86) || defined(_M_X64) )
+
+extern "C" void _mm_pause();
+#pragma intrinsic( _mm_pause )
+
+#define BOOST_INTERPROCESS_SMT_PAUSE _mm_pause();
+
+#elif defined(__GNUC__) && ( defined(__i386__) || defined(__x86_64__) )
+
+#define BOOST_INTERPROCESS_SMT_PAUSE __asm__ __volatile__( "rep; nop" : : : "memory" );
+
+#endif
+
+namespace boost{
+namespace interprocess{
+namespace ipcdetail {
+
+template<int Dummy = 0>
+class num_core_holder
+{
+ public:
+ static unsigned int get()
+ {
+ if(!num_cores){
+ return ipcdetail::get_num_cores();
+ }
+ else{
+ return num_cores;
+ }
+ }
+
+ private:
+ static unsigned int num_cores;
+};
+
+template<int Dummy>
+unsigned int num_core_holder<Dummy>::num_cores = ipcdetail::get_num_cores();
+
+} //namespace ipcdetail {
+
+class spin_wait
+{
+ public:
+ spin_wait()
+ : m_k(0u)
+ {
+ (void)m_nop_pause_limit;
+ (void)m_yield_only_counts;
+ (void)m_count_start;
+ }
+
+ #ifdef BOOST_INTERPROCESS_SPIN_WAIT_DEBUG
+ ~spin_wait()
+ {
+ if(m_k){
+ std::cout << "final m_k: " << m_k
+ << " system tick(us): " << ipcdetail::get_system_tick_us() << std::endl;
+ }
+ }
+ #endif
+
+ unsigned int count() const
+ { return m_k; }
+
+ void yield()
+ {
+ //Lazy initialization of limits
+ if( !m_k){
+ this->init_limits();
+ }
+ //Nop tries
+ if( m_k < (m_nop_pause_limit >> 2) ){
+
+ }
+ //Pause tries if the processor supports it
+ #if defined(BOOST_INTERPROCESS_SMT_PAUSE)
+ else if( m_k < m_nop_pause_limit ){
+ BOOST_INTERPROCESS_SMT_PAUSE
+ }
+ #endif
+ //Yield/Sleep strategy
+ else{
+ //Lazy initialization of tick information
+ if(m_k == m_nop_pause_limit){
+ this->init_tick_info();
+ }
+ else if( this->yield_or_sleep() ){
+ ipcdetail::thread_yield();
+ }
+ else{
+ ipcdetail::thread_sleep_tick();
+ }
+ }
+ ++m_k;
+ }
+
+ void reset()
+ {
+ m_k = 0u;
+ m_count_start = ipcdetail::get_current_system_highres_count();
+ }
+
+ private:
+
+ void init_limits()
+ {
+ unsigned int num_cores = ipcdetail::num_core_holder<0>::get();
+ m_nop_pause_limit = num_cores > 1u ? 32u : 0u;
+ }
+
+ void init_tick_info()
+ {
+ m_yield_only_counts = ipcdetail::get_system_tick_in_highres_counts();
+ m_count_start = ipcdetail::get_current_system_highres_count();
+ }
+
+ //Returns true if yield must be called, false is sleep must be called
+ bool yield_or_sleep()
+ {
+ if(ipcdetail::is_highres_count_zero(m_yield_only_counts)){ //If yield-only limit was reached then yield one in every two tries
+ return (m_k & 1u) != 0;
+ }
+ else{ //Try to see if we've reched yield-only time limit
+ const ipcdetail::OS_highres_count_t now = ipcdetail::get_current_system_highres_count();
+ const ipcdetail::OS_highres_count_t elapsed = ipcdetail::system_highres_count_subtract(now, m_count_start);
+ if(!ipcdetail::system_highres_count_less(elapsed, m_yield_only_counts)){
+ #ifdef BOOST_INTERPROCESS_SPIN_WAIT_DEBUG
+ std::cout << "elapsed!\n"
+ << " m_yield_only_counts: ";
+ ipcdetail::ostream_highres_count(std::cout, m_yield_only_counts)
+ << " system tick(us): " << ipcdetail::get_system_tick_us() << '\n'
+ << " m_k: " << m_k << " elapsed counts: ";
+ ipcdetail::ostream_highres_count(std::cout, elapsed) << std::endl;
+ #endif
+ //Yield-only time reached, now it's time to sleep
+ ipcdetail::zero_highres_count(m_yield_only_counts);
+ return false;
+ }
+ }
+ return true; //Otherwise yield
+ }
+
+ unsigned int m_k;
+ unsigned int m_nop_pause_limit;
+ ipcdetail::OS_highres_count_t m_yield_only_counts;
+ ipcdetail::OS_highres_count_t m_count_start;
+};
+
+} // namespace interprocess
+} // namespace boost
+
+#include <boost/interprocess/detail/config_end.hpp>
+
+#endif // #ifndef BOOST_INTERPROCESS_SYNC_WAIT_HPP_INCLUDED

Modified: branches/release/libs/interprocess/Jamfile.v2
==============================================================================
--- branches/release/libs/interprocess/Jamfile.v2 Sun Sep 8 15:29:06 2013 (r85614)
+++ branches/release/libs/interprocess/Jamfile.v2 2013-09-08 16:07:03 EDT (Sun, 08 Sep 2013) (r85615)
@@ -2,4 +2,4 @@
 
 # Tests from Jamfiles in individual library test subdirectories
 build-project example ; # test-suite interprocess_example
-build-project test ; # test-suite interprocess_test
+build-project test ; # test-suite interprocess_test
\ No newline at end of file

Modified: branches/release/libs/interprocess/doc/interprocess.qbk
==============================================================================
--- branches/release/libs/interprocess/doc/interprocess.qbk Sun Sep 8 15:29:06 2013 (r85614)
+++ branches/release/libs/interprocess/doc/interprocess.qbk 2013-09-08 16:07:03 EDT (Sun, 08 Sep 2013) (r85615)
@@ -6715,8 +6715,13 @@
 
 [section:release_notes_boost_1_55_00 Boost 1.55 Release]
 
-* Fixed bugs [@https://svn.boost.org/trac/boost/ticket/7164 #7164],
- [@https://svn.boost.org/trac/boost/ticket/8277 #8277].
+* Fixed bugs [@https://svn.boost.org/trac/boost/ticket/7156 #7156],
+ [@https://svn.boost.org/trac/boost/ticket/7164 #7164],
+ [@https://svn.boost.org/trac/boost/ticket/8277 #8277],
+ [@https://svn.boost.org/trac/boost/ticket/8976 #8976],
+ [@https://svn.boost.org/trac/boost/ticket/9065 #9065],
+ [@https://svn.boost.org/trac/boost/ticket/9073 #9073],
+ [@https://svn.boost.org/trac/boost/ticket/8277 #9908].
 
 [endsect]
 

Modified: branches/release/libs/interprocess/test/bufferstream_test.cpp
==============================================================================
--- branches/release/libs/interprocess/test/bufferstream_test.cpp Sun Sep 8 15:29:06 2013 (r85614)
+++ branches/release/libs/interprocess/test/bufferstream_test.cpp 2013-09-08 16:07:03 EDT (Sun, 08 Sep 2013) (r85615)
@@ -33,7 +33,7 @@
       const int BufSize = 10001;
       //This will be zero-initialized
       static char buffer [BufSize];
- bufferstream bufstream;;
+ bufferstream bufstream;
       std::stringstream std_stringstream;
       std::string str1, str2, str3("testline:");
       int number1, number2;

Modified: branches/release/libs/interprocess/test/robust_mutex_test.hpp
==============================================================================
--- branches/release/libs/interprocess/test/robust_mutex_test.hpp Sun Sep 8 15:29:06 2013 (r85614)
+++ branches/release/libs/interprocess/test/robust_mutex_test.hpp 2013-09-08 16:07:03 EDT (Sun, 08 Sep 2013) (r85615)
@@ -16,6 +16,7 @@
 #include <cstdlib> //std::system
 #include <boost/interprocess/sync/scoped_lock.hpp>
 #include <boost/interprocess/managed_shared_memory.hpp>
+#include <boost/interprocess/sync/spin/wait.hpp>
 #include "get_process_id_name.hpp"
 #include "mutex_test_template.hpp"
 #include <iostream>
@@ -66,9 +67,9 @@
          return 1;
 
       //Wait until child locks the mutexes and dies
- unsigned k = 0;
+ spin_wait swait;
       while(!*go_ahead){
- ipcdetail::yield(k++);
+ swait.yield();
       }
 
       std::cout << "... recovering mutex[0]" << std::endl;
@@ -164,9 +165,9 @@
          }
 
          //Wait until child locks the 2nd mutex and dies
- unsigned k = 0;
+ spin_wait swait;
          while(!*go_ahead2){
- ipcdetail::yield(k++);
+ swait.yield();
          }
 
          //Done, now try to lock number 3 to see if robust


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk