Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r85444 - in branches/release: boost/interprocess boost/interprocess/detail 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-08-24 06:52:48


Author: igaztanaga
Date: 2013-08-24 06:52:47 EDT (Sat, 24 Aug 2013)
New Revision: 85444
URL: http://svn.boost.org/trac/boost/changeset/85444

Log:
Merged revision(s) 84426-85443 from trunk/boost/interprocess. Merged revision(s) 84426-85443 from trunk/libs/interprocess. First Interprocess merge for 1.55

Added:
   branches/release/boost/interprocess/detail/yield_k.hpp
      - copied unchanged from r85443, trunk/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/intermodule_singleton_common.hpp | 8 +
   branches/release/boost/interprocess/detail/managed_open_or_create_impl.hpp | 9 +
   branches/release/boost/interprocess/detail/os_thread_functions.hpp | 3
   branches/release/boost/interprocess/detail/robust_emulation.hpp | 5
   branches/release/boost/interprocess/detail/windows_intermodule_singleton.hpp | 5 +
   branches/release/boost/interprocess/detail/yield_k.hpp | 136 ++++++++++++++++++++++++++++++++++++++++
   branches/release/boost/interprocess/errors.hpp | 2
   branches/release/boost/interprocess/sync/file_lock.hpp | 7 +
   branches/release/boost/interprocess/sync/named_mutex.hpp | 10 +-
   branches/release/boost/interprocess/sync/posix/mutex.hpp | 3
   branches/release/boost/interprocess/sync/posix/recursive_mutex.hpp | 4
   branches/release/boost/interprocess/sync/posix/semaphore_wrapper.hpp | 3
   branches/release/boost/interprocess/sync/spin/condition.hpp | 12 +--
   branches/release/boost/interprocess/sync/spin/mutex.hpp | 6 +
   branches/release/boost/interprocess/sync/spin/semaphore.hpp | 6 +
   branches/release/libs/interprocess/doc/interprocess.qbk | 7 ++
   branches/release/libs/interprocess/test/robust_mutex_test.hpp | 6 +
   17 files changed, 195 insertions(+), 37 deletions(-)

Modified: branches/release/boost/interprocess/detail/intermodule_singleton_common.hpp
==============================================================================
--- branches/release/boost/interprocess/detail/intermodule_singleton_common.hpp Sat Aug 24 06:41:09 2013 (r85443)
+++ branches/release/boost/interprocess/detail/intermodule_singleton_common.hpp 2013-08-24 06:52:47 EDT (Sat, 24 Aug 2013) (r85444)
@@ -145,6 +145,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;
             while(1){
                previous_module_singleton_initialized = atomic_read32(&this_module_singleton_initialized);
                if(previous_module_singleton_initialized >= Initialized){
@@ -152,7 +153,7 @@
                   break;
                }
                else if(previous_module_singleton_initialized == Initializing){
- thread_yield();
+ yield(k++);
                }
                else{
                   //This can't be happening!
@@ -206,6 +207,7 @@
    static void initialize_global_map_handle()
    {
       //Obtain unique map name and size
+ unsigned k = 0;
       while(1){
          //Try to pass map state to initializing
          ::boost::uint32_t tmp = atomic_cas32(&this_module_map_initialized, Initializing, Uninitialized);
@@ -218,7 +220,7 @@
          }
          //If some other thread is doing the work wait
          else if(tmp == Initializing){
- thread_yield();
+ yield(k++);
          }
          else{ //(tmp == Uninitialized)
             //If not initialized try it again?
@@ -309,7 +311,7 @@
 
 
 //Now this class is a singleton, initializing the singleton in
-//the first get() function call if LazyInit is false. If true
+//the first get() function call if LazyInit is true. If false
 //then the singleton will be initialized when loading the module.
 template<typename C, bool LazyInit, bool Phoenix, class ThreadSafeGlobalMap>
 class intermodule_singleton_impl

Modified: branches/release/boost/interprocess/detail/managed_open_or_create_impl.hpp
==============================================================================
--- branches/release/boost/interprocess/detail/managed_open_or_create_impl.hpp Sat Aug 24 06:41:09 2013 (r85443)
+++ branches/release/boost/interprocess/detail/managed_open_or_create_impl.hpp 2013-08-24 06:52:47 EDT (Sat, 24 Aug 2013) (r85444)
@@ -354,6 +354,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;
          while(!completed){
             try{
                create_device<FileBased>(dev, id, size, perm, file_like_t());
@@ -384,7 +385,7 @@
             catch(...){
                throw;
             }
- thread_yield();
+ yield(k++);
          }
       }
 
@@ -431,11 +432,12 @@
       else{
          if(FileBased){
             offset_t filesize = 0;
+ unsigned k = 0;
             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()));
                }
- thread_yield();
+ yield(k++);
             }
             if(filesize == 1){
                throw interprocess_exception(error_info(corrupted_error));
@@ -447,8 +449,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;
          while(value == InitializingSegment || value == UninitializedSegment){
- thread_yield();
+ yield(k++);
             value = atomic_read32(patomic_word);
          }
 

Modified: branches/release/boost/interprocess/detail/os_thread_functions.hpp
==============================================================================
--- branches/release/boost/interprocess/detail/os_thread_functions.hpp Sat Aug 24 06:41:09 2013 (r85443)
+++ branches/release/boost/interprocess/detail/os_thread_functions.hpp 2013-08-24 06:52:47 EDT (Sat, 24 Aug 2013) (r85444)
@@ -15,8 +15,9 @@
 #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>
 
-#if (defined BOOST_INTERPROCESS_WINDOWS)
+#if defined(BOOST_INTERPROCESS_WINDOWS)
 # include <boost/interprocess/detail/win32_api.hpp>
 #else
 # ifdef BOOST_HAS_UNISTD_H

Modified: branches/release/boost/interprocess/detail/robust_emulation.hpp
==============================================================================
--- branches/release/boost/interprocess/detail/robust_emulation.hpp Sat Aug 24 06:41:09 2013 (r85443)
+++ branches/release/boost/interprocess/detail/robust_emulation.hpp 2013-08-24 06:52:47 EDT (Sat, 24 Aug 2013) (r85444)
@@ -236,7 +236,7 @@
       }
       else{
          //Do the dead owner checking each spin_threshold lock tries
- ipcdetail::thread_yield();
+ yield(spin_count);
          ++spin_count;
          if(spin_count > spin_threshold){
             //Check if owner dead and take ownership if possible
@@ -292,6 +292,7 @@
    if(now >= abs_time)
       return this->try_lock();
 
+ unsigned k = 0;
    do{
       if(this->try_lock()){
          break;
@@ -302,7 +303,7 @@
          return this->try_lock();
       }
       // relinquish current time slice
- ipcdetail::thread_yield();
+ ipcdetail::yield(k++);
    }while (true);
 
    return true;

Modified: branches/release/boost/interprocess/detail/windows_intermodule_singleton.hpp
==============================================================================
--- branches/release/boost/interprocess/detail/windows_intermodule_singleton.hpp Sat Aug 24 06:41:09 2013 (r85443)
+++ branches/release/boost/interprocess/detail/windows_intermodule_singleton.hpp 2013-08-24 06:52:47 EDT (Sat, 24 Aug 2013) (r85444)
@@ -135,6 +135,7 @@
          success = success && m_sem_map.open_or_create
             (name.c_str(), initial_count, max_count, perm, created);
          if(!success){
+ delete m;
             //winapi_xxx wrappers do the cleanup...
             throw int(0);
          }
@@ -217,7 +218,9 @@
       scoped_lock<winapi_mutex_wrapper> lck(m_mtx_lock);
       m_sem_count.wait();
       if(0 == m_sem_count.value()){
- delete &this->get_map_unlocked();
+ map_type &map = this->get_map_unlocked();
+ BOOST_ASSERT(map.empty());
+ delete &map;
       }
       //First close sems to protect this with the external mutex
       m_sem_map.close();

Copied: branches/release/boost/interprocess/detail/yield_k.hpp (from r85443, trunk/boost/interprocess/detail/yield_k.hpp)
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ branches/release/boost/interprocess/detail/yield_k.hpp 2013-08-24 06:52:47 EDT (Sat, 24 Aug 2013) (r85444, copy of r85443, trunk/boost/interprocess/detail/yield_k.hpp)
@@ -0,0 +1,136 @@
+//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/errors.hpp
==============================================================================
--- branches/release/boost/interprocess/errors.hpp Sat Aug 24 06:41:09 2013 (r85443)
+++ branches/release/boost/interprocess/errors.hpp 2013-08-24 06:52:47 EDT (Sat, 24 Aug 2013) (r85444)
@@ -114,7 +114,7 @@
    not_such_file_or_directory,
    invalid_argument,
    timeout_when_locking_error,
- timeout_when_waiting_error,
+ timeout_when_waiting_error
 };
 
 typedef int native_error_t;

Modified: branches/release/boost/interprocess/sync/file_lock.hpp
==============================================================================
--- branches/release/boost/interprocess/sync/file_lock.hpp Sat Aug 24 06:41:09 2013 (r85443)
+++ branches/release/boost/interprocess/sync/file_lock.hpp 2013-08-24 06:52:47 EDT (Sat, 24 Aug 2013) (r85444)
@@ -149,7 +149,7 @@
       using namespace boost::detail;
 
       if(now >= abs_time) return false;
-
+ unsigned k = 0;
       do{
          if(!ipcdetail::try_acquire_file_lock(hnd, acquired))
             return false;
@@ -164,7 +164,7 @@
                return true;
             }
             // relinquish current time slice
- ipcdetail::thread_yield();
+ ipcdetail::yield(k++);
          }
       }while (true);
    }
@@ -178,6 +178,7 @@
 
       if(now >= abs_time) return false;
 
+ unsigned k = 0;
       do{
          if(!ipcdetail::try_acquire_file_lock_sharable(hnd, acquired))
             return false;
@@ -192,7 +193,7 @@
                return true;
             }
             // relinquish current time slice
- ipcdetail::thread_yield();
+ ipcdetail::yield(k++);
          }
       }while (true);
    }

Modified: branches/release/boost/interprocess/sync/named_mutex.hpp
==============================================================================
--- branches/release/boost/interprocess/sync/named_mutex.hpp Sat Aug 24 06:41:09 2013 (r85443)
+++ branches/release/boost/interprocess/sync/named_mutex.hpp 2013-08-24 06:52:47 EDT (Sat, 24 Aug 2013) (r85444)
@@ -56,7 +56,7 @@
    /// @endcond
 
    public:
- //!Creates a global interprocess_mutex with a name.
+ //!Creates a global mutex with a name.
    //!Throws interprocess_exception on error.
    named_mutex(create_only_t create_only, const char *name, const permissions &perm = permissions());
 
@@ -82,19 +82,19 @@
    ~named_mutex();
 
    //!Unlocks a previously locked
- //!interprocess_mutex.
+ //!mutex.
    void unlock();
 
- //!Locks interprocess_mutex, sleeps when interprocess_mutex is already locked.
+ //!Locks the mutex, sleeps when the mutex is already locked.
    //!Throws interprocess_exception if a severe error is found
    void lock();
 
- //!Tries to lock the interprocess_mutex, returns false when interprocess_mutex
+ //!Tries to lock the mutex, returns false when the mutex
    //!is already locked, returns true when success.
    //!Throws interprocess_exception if a severe error is found
    bool try_lock();
 
- //!Tries to lock the interprocess_mutex until time abs_time,
+ //!Tries to lock the the mutex until time abs_time,
    //!Returns false when timeout expires, returns true when locks.
    //!Throws interprocess_exception if a severe error is found
    bool timed_lock(const boost::posix_time::ptime &abs_time);

Modified: branches/release/boost/interprocess/sync/posix/mutex.hpp
==============================================================================
--- branches/release/boost/interprocess/sync/posix/mutex.hpp Sat Aug 24 06:41:09 2013 (r85443)
+++ branches/release/boost/interprocess/sync/posix/mutex.hpp 2013-08-24 06:52:47 EDT (Sat, 24 Aug 2013) (r85444)
@@ -119,6 +119,7 @@
    //Obtain current count and target time
    boost::posix_time::ptime now = microsec_clock::universal_time();
 
+ unsigned k = 0;
    do{
       if(this->try_lock()){
          break;
@@ -129,7 +130,7 @@
          return false;
       }
       // relinquish current time slice
- thread_yield();
+ ipcdetail::yield(k++);
    }while (true);
    return true;
 

Modified: branches/release/boost/interprocess/sync/posix/recursive_mutex.hpp
==============================================================================
--- branches/release/boost/interprocess/sync/posix/recursive_mutex.hpp Sat Aug 24 06:41:09 2013 (r85443)
+++ branches/release/boost/interprocess/sync/posix/recursive_mutex.hpp 2013-08-24 06:52:47 EDT (Sat, 24 Aug 2013) (r85444)
@@ -108,7 +108,7 @@
 
    //Obtain current count and target time
    boost::posix_time::ptime now = microsec_clock::universal_time();
-
+ unsigned k = 0;
    do{
       if(this->try_lock()){
          break;
@@ -119,7 +119,7 @@
          return false;
       }
       // relinquish current time slice
- thread_yield();
+ yield(k++);
    }while (true);
    return true;
 

Modified: branches/release/boost/interprocess/sync/posix/semaphore_wrapper.hpp
==============================================================================
--- branches/release/boost/interprocess/sync/posix/semaphore_wrapper.hpp Sat Aug 24 06:41:09 2013 (r85443)
+++ branches/release/boost/interprocess/sync/posix/semaphore_wrapper.hpp 2013-08-24 06:52:47 EDT (Sat, 24 Aug 2013) (r85444)
@@ -195,10 +195,11 @@
    return false;
    #else //#ifdef BOOST_INTERPROCESS_POSIX_TIMEOUTS
    boost::posix_time::ptime now;
+ unsigned k = 0;
    do{
       if(semaphore_try_wait(handle))
          return true;
- thread_yield();
+ yield(k++);
    }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 Sat Aug 24 06:41:09 2013 (r85443)
+++ branches/release/boost/interprocess/sync/spin/condition.hpp 2013-08-24 06:52:47 EDT (Sat, 24 Aug 2013) (r85444)
@@ -140,15 +140,10 @@
    }
 
    //Notify that all threads should execute wait logic
+ unsigned k = 0;
    while(SLEEP != atomic_cas32(const_cast<boost::uint32_t*>(&m_command), command, SLEEP)){
- thread_yield();
+ yield(k++);
    }
-/*
- //Wait until the threads are woken
- while(SLEEP != atomic_cas32(const_cast<boost::uint32_t*>(&m_command), 0)){
- thread_yield();
- }
-*/
    //The enter mutex will rest locked until the last waiting thread unlocks it
 }
 
@@ -211,8 +206,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;
       while(atomic_read32(&m_command) == SLEEP){
- thread_yield();
+ yield(k++);
 
          //Check for timeout
          if(tout_enabled){

Modified: branches/release/boost/interprocess/sync/spin/mutex.hpp
==============================================================================
--- branches/release/boost/interprocess/sync/spin/mutex.hpp Sat Aug 24 06:41:09 2013 (r85443)
+++ branches/release/boost/interprocess/sync/spin/mutex.hpp 2013-08-24 06:52:47 EDT (Sat, 24 Aug 2013) (r85444)
@@ -60,6 +60,7 @@
 
 inline void spin_mutex::lock(void)
 {
+ unsigned k = 0;
    do{
       boost::uint32_t prev_s = ipcdetail::atomic_cas32(const_cast<boost::uint32_t*>(&m_s), 1, 0);
 
@@ -67,7 +68,7 @@
             break;
       }
       // relinquish current timeslice
- ipcdetail::thread_yield();
+ ipcdetail::yield(k++);
    }while (true);
 }
 
@@ -86,6 +87,7 @@
    //Obtain current count and target time
    boost::posix_time::ptime now = microsec_clock::universal_time();
 
+ unsigned k = 0;
    do{
       if(this->try_lock()){
          break;
@@ -96,7 +98,7 @@
          return false;
       }
       // relinquish current time slice
- ipcdetail::thread_yield();
+ ipcdetail::yield(k++);
    }while (true);
 
    return true;

Modified: branches/release/boost/interprocess/sync/spin/semaphore.hpp
==============================================================================
--- branches/release/boost/interprocess/sync/spin/semaphore.hpp Sat Aug 24 06:41:09 2013 (r85443)
+++ branches/release/boost/interprocess/sync/spin/semaphore.hpp 2013-08-24 06:52:47 EDT (Sat, 24 Aug 2013) (r85444)
@@ -59,9 +59,10 @@
 
 inline void spin_semaphore::wait()
 {
+ unsigned k = 0;
    while(!ipcdetail::atomic_add_unless32(&m_count, boost::uint32_t(-1), boost::uint32_t(0))){
       while(ipcdetail::atomic_read32(&m_count) == 0){
- ipcdetail::thread_yield();
+ ipcdetail::yield(k++);
       }
    }
 }
@@ -80,6 +81,7 @@
    //Obtain current count and target time
    boost::posix_time::ptime now(microsec_clock::universal_time());
 
+ unsigned k = 0;
    do{
       if(this->try_wait()){
          break;
@@ -90,7 +92,7 @@
          return this->try_wait();
       }
       // relinquish current time slice
- ipcdetail::thread_yield();
+ ipcdetail::yield(k++);
    }while (true);
    return true;
 }

Modified: branches/release/libs/interprocess/doc/interprocess.qbk
==============================================================================
--- branches/release/libs/interprocess/doc/interprocess.qbk Sat Aug 24 06:41:09 2013 (r85443)
+++ branches/release/libs/interprocess/doc/interprocess.qbk 2013-08-24 06:52:47 EDT (Sat, 24 Aug 2013) (r85444)
@@ -6713,6 +6713,13 @@
 
 [section:release_notes Release Notes]
 
+[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].
+
+[endsect]
+
 [section:release_notes_boost_1_54_00 Boost 1.54 Release]
 
 * Added support for platform-specific flags to mapped_region (ticket #8030)

Modified: branches/release/libs/interprocess/test/robust_mutex_test.hpp
==============================================================================
--- branches/release/libs/interprocess/test/robust_mutex_test.hpp Sat Aug 24 06:41:09 2013 (r85443)
+++ branches/release/libs/interprocess/test/robust_mutex_test.hpp 2013-08-24 06:52:47 EDT (Sat, 24 Aug 2013) (r85444)
@@ -66,8 +66,9 @@
          return 1;
 
       //Wait until child locks the mutexes and dies
+ unsigned k = 0;
       while(!*go_ahead){
- ipcdetail::thread_yield();
+ ipcdetail::yield(k++);
       }
 
       std::cout << "... recovering mutex[0]" << std::endl;
@@ -163,8 +164,9 @@
          }
 
          //Wait until child locks the 2nd mutex and dies
+ unsigned k = 0;
          while(!*go_ahead2){
- ipcdetail::thread_yield();
+ ipcdetail::yield(k++);
          }
 
          //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