|
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 ↦
}
//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