void lock()
		{
			while (state_.exchange(Locked, boost::memory_order_acquire) == Locked)
			{
				/* busy-wait */
			}
		}
Exemple #2
0
/**
 * 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();
}
Exemple #3
0
            /// 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();
                }
            }
Exemple #4
0
 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;
 }
Exemple #5
0
            /// 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);
                }
            }
Exemple #6
0
	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()));
}
Exemple #10
0
 /** Swap the atomic value with value.
  * \return the previously held value
  */
 T swap(T value)
 { return _value.exchange(value); }