summaryrefslogtreecommitdiff
path: root/boost/interprocess/sync/spin/condition.hpp
diff options
context:
space:
mode:
authorChanho Park <chanho61.park@samsung.com>2014-12-11 18:55:56 +0900
committerChanho Park <chanho61.park@samsung.com>2014-12-11 18:55:56 +0900
commit08c1e93fa36a49f49325a07fe91ff92c964c2b6c (patch)
tree7a7053ceb8874b28ec4b868d4c49b500008a102e /boost/interprocess/sync/spin/condition.hpp
parentbb4dd8289b351fae6b55e303f189127a394a1edd (diff)
downloadboost-08c1e93fa36a49f49325a07fe91ff92c964c2b6c.tar.gz
boost-08c1e93fa36a49f49325a07fe91ff92c964c2b6c.tar.bz2
boost-08c1e93fa36a49f49325a07fe91ff92c964c2b6c.zip
Imported Upstream version 1.57.0upstream/1.57.0
Diffstat (limited to 'boost/interprocess/sync/spin/condition.hpp')
-rw-r--r--boost/interprocess/sync/spin/condition.hpp43
1 files changed, 24 insertions, 19 deletions
diff --git a/boost/interprocess/sync/spin/condition.hpp b/boost/interprocess/sync/spin/condition.hpp
index 55dd79b406..e587c32c9b 100644
--- a/boost/interprocess/sync/spin/condition.hpp
+++ b/boost/interprocess/sync/spin/condition.hpp
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2012. 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)
//
@@ -11,6 +11,10 @@
#ifndef BOOST_INTERPROCESS_DETAIL_SPIN_CONDITION_HPP
#define BOOST_INTERPROCESS_DETAIL_SPIN_CONDITION_HPP
+#if defined(_MSC_VER)
+# pragma once
+#endif
+
#include <boost/interprocess/detail/config_begin.hpp>
#include <boost/interprocess/detail/workaround.hpp>
#include <boost/interprocess/sync/spin/mutex.hpp>
@@ -19,7 +23,8 @@
#include <boost/interprocess/sync/scoped_lock.hpp>
#include <boost/interprocess/exceptions.hpp>
#include <boost/interprocess/detail/os_thread_functions.hpp>
-#include <boost/move/move.hpp>
+#include <boost/interprocess/sync/spin/wait.hpp>
+#include <boost/move/utility_core.hpp>
#include <boost/cstdint.hpp>
namespace boost {
@@ -40,24 +45,26 @@ class spin_condition
template <typename L>
bool timed_wait(L& lock, const boost::posix_time::ptime &abs_time)
{
+ if (!lock)
+ throw lock_exception();
+ //Handle infinity absolute time here to avoid complications in do_timed_wait
if(abs_time == boost::posix_time::pos_infin){
this->wait(lock);
return true;
}
- if (!lock)
- throw lock_exception();
return this->do_timed_wait(abs_time, *lock.mutex());
}
template <typename L, typename Pr>
bool timed_wait(L& lock, const boost::posix_time::ptime &abs_time, Pr pred)
{
+ if (!lock)
+ throw lock_exception();
+ //Handle infinity absolute time here to avoid complications in do_timed_wait
if(abs_time == boost::posix_time::pos_infin){
this->wait(lock, pred);
return true;
}
- if (!lock)
- throw lock_exception();
while (!pred()){
if (!this->do_timed_wait(abs_time, *lock.mutex()))
return pred();
@@ -110,8 +117,10 @@ inline spin_condition::spin_condition()
}
inline spin_condition::~spin_condition()
-{
- //Trivial destructor
+{
+ //Notify all waiting threads
+ //to allow POSIX semantics on condition destruction
+ this->notify_all();
}
inline void spin_condition::notify_one()
@@ -140,15 +149,10 @@ inline void spin_condition::notify(boost::uint32_t command)
}
//Notify that all threads should execute wait logic
+ spin_wait swait;
while(SLEEP != atomic_cas32(const_cast<boost::uint32_t*>(&m_command), command, SLEEP)){
- thread_yield();
+ swait.yield();
}
-/*
- //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
}
@@ -171,7 +175,7 @@ inline bool spin_condition::do_timed_wait(bool tout_enabled,
InterprocessMutex &mut)
{
boost::posix_time::ptime now = microsec_clock::universal_time();
-
+
if(tout_enabled){
if(now >= abs_time) return false;
}
@@ -205,14 +209,15 @@ inline bool spin_condition::do_timed_wait(bool tout_enabled,
//By default, we suppose that no timeout has happened
bool timed_out = false, unlock_enter_mut= false;
-
+
//Loop until a notification indicates that the thread should
//exit or timeout occurs
while(1){
//The thread sleeps/spins until a spin_condition commands a notification
//Notification occurred, we will lock the checking mutex so that
+ spin_wait swait;
while(atomic_read32(&m_command) == SLEEP){
- thread_yield();
+ swait.yield();
//Check for timeout
if(tout_enabled){
@@ -253,7 +258,7 @@ inline bool spin_condition::do_timed_wait(bool tout_enabled,
continue;
}
else if(result == NOTIFY_ONE){
- //If it was a NOTIFY_ONE command, only this thread should
+ //If it was a NOTIFY_ONE command, only this thread should
//exit. This thread has atomically marked command as sleep before
//so no other thread will exit.
//Decrement wait count.