void lock() { while (state_.exchange(Locked, boost::memory_order_acquire) == Locked) { /* busy-wait */ } }
/** * The environment should be initialised exactly once during shared library initialisation. * Prior to that, all operations work in pass-through mode. * To overcome undefined global initialisation order, we use a local static variable. * This variable is accesd by a single writer (lib (de)initialisation), and multiple readers (exported operations). * Writer: toggle == true (toggles is_initialised) * Reader: toggle == false (returns the current value of is_initialised) * * NOTE: pthread_once initialisation for the overlay leads to a deadlock due to a re-entry situation: * - environment ctor is called the first time via pthread_once * - which leads a write somewhere (probably to a socket during client initialisation) * - which then enters the pthread_once initialisation mechanism again and blocks deadlocks */ bool overlay_initialized(bool toggle /* defaults to: false */) { static boost::atomic<bool> is_initilized(false); // writer if(toggle) { return is_initilized.exchange(!is_initilized.load()); } // reader return is_initilized.load(); }
/// Attempts to acquire ownership of the \a recursive_mutex. /// Suspends the current HPX-thread until \a timeout if ownership cannot /// be obtained immediately. /// /// \returns \a true if ownership was acquired; otherwise, \a false. /// /// \throws Throws \a hpx#bad_parameter if an error occurs while /// suspending. Throws \a hpx#yield_aborted if the mutex is /// destroyed while suspended. Throws \a hpx#null_thread_id if /// called outside of a HPX-thread. // template<typename Duration> // bool timed_lock(Duration const& timeout) // { // return timed_lock(boost::get_system_time() + timeout); // } // // bool timed_lock(boost::xtime const& timeout) // { // return timed_lock(boost::posix_time::ptime(timeout)); // } // /// Release ownership of the \a recursive_mutex. /// /// \throws Throws \a hpx#bad_parameter if an error occurs while /// releasing the mutex. Throws \a hpx#null_thread_id if called /// outside of a HPX-thread. void unlock() { util::unregister_lock(this); if (0 == --recursion_count) { locking_thread_id.exchange(thread_id_from_mutex<Mutex> ::invalid_id()); util::reset_ignored(&mtx); mtx.unlock(); } }
bool try_basic_lock(thread_id_type current_thread_id) { if (mtx.try_lock()) { locking_thread_id.exchange(current_thread_id); util::ignore_lock(&mtx); util::register_lock(this); recursion_count.store(1); return true; } return false; }
/// Acquires ownership of the \a recursive_mutex. Suspends the /// current HPX-thread if ownership cannot be obtained immediately. /// /// \throws Throws \a hpx#bad_parameter if an error occurs while /// suspending. Throws \a hpx#yield_aborted if the mutex is /// destroyed while suspended. Throws \a hpx#null_thread_id if /// called outside of a HPX-thread. void lock() { thread_id_type const id = thread_id_from_mutex<Mutex>::call(); HPX_ASSERT(id != thread_id_from_mutex<Mutex>::invalid_id()); if (!try_recursive_lock(id)) { mtx.lock(); locking_thread_id.exchange(id); util::ignore_lock(&mtx); util::register_lock(this); recursion_count.store(1); } }
void push_back(T elem) { // Construct an element to hold it synclist_item<T>* itm = new synclist_item<T>(); itm->value = elem; itm->prev.store(m_last.load(boost::memory_order_release), boost::memory_order_acquire); itm->next.store(NULL, boost::memory_order_acquire); // Insert the element in the list synclist_item<T>* tmpItm = itm; synclist_item<T>* prevLast = m_last.exchange(tmpItm, boost::memory_order_consume); tmpItm = itm; synclist_item<T>* null = NULL; m_first.compare_exchange_strong(null, tmpItm, boost::memory_order_consume, boost::memory_order_acquire); if(prevLast != NULL) { prevLast->next.store(itm, boost::memory_order_consume); } m_length.fetch_add(1, boost::memory_order_consume); }
IntrusivePtr& swap(IntrusivePtr&& other) { T* old = ptr.exchange(other.ptr); other.ptr = old; return other; }
~IntrusivePtr() { T* _p = ptr.exchange(NULL); if(_p) intrusive_ptr_release(_p); }
void swap( boost::atomic<T>& lhs, boost::atomic<T>& rhs ) { lhs.store(rhs.exchange(lhs.load())); }
/** Swap the atomic value with value. * \return the previously held value */ T swap(T value) { return _value.exchange(value); }