synchronization

The contents of this module can be included with the header hpx/modules/synchronization.hpp. These headers may be used by user-code but are not guaranteed stable (neither header location nor contents). You are using these at your own risk. If you wish to use non-public functionality from a module we strongly suggest only including the module header hpx/modules/synchronization.hpp, not the particular header in which the functionality you would like to use is defined. See Public API for a list of names that are part of the public HPX API.

namespace hpx
namespace experimental
template<typename ReadWriteT, typename ReadT, typename Allocator>
class async_rw_mutex
#include <async_rw_mutex.hpp>

Read-write mutex where access is granted to a value through senders.

The wrapped value is accessed through read and readwrite, both of which return senders which call set_value on a connected receiver when the wrapped value is safe to read or write. The senders send the value through a wrapper type which is implicitly convertible to a reference of the wrapped value. Read-only senders send wrappers that are convertible to const references.

A read-write sender gives exclusive access to the wrapped value, while a read-only sender gives shared (with other read-only senders) access to the value.

A void mutex acts as a mutex around some user-managed resource, i.e. the void mutex does not manage any value and the types sent by the senders are not convertible. The sent types are copyable and release access to the protected resource when released.

The order in which senders call set_value is determined by the order in which the senders are retrieved from the mutex. Connecting and starting the senders is thread-safe.

Retrieving senders from the mutex is not thread-safe.

The mutex is movable and non-copyable.

Public Types

template<>
using read_type = std::decay_t<ReadT> const
template<>
using readwrite_type = std::decay_t<ReadWriteT>
template<>
using value_type = readwrite_type
template<>
using read_access_type = detail::async_rw_mutex_access_wrapper<readwrite_type, read_type, detail::async_rw_mutex_access_type::read>
template<>
using readwrite_access_type = detail::async_rw_mutex_access_wrapper<readwrite_type, read_type, detail::async_rw_mutex_access_type::readwrite>
template<>
using allocator_type = Allocator

Public Functions

async_rw_mutex()
template<typename U, typename = std::enable_if_t<!std::is_same<std::decay_t<U>, async_rw_mutex>::value>>
async_rw_mutex(U &&u, allocator_type const &alloc = {})
async_rw_mutex(async_rw_mutex&&)
async_rw_mutex &operator=(async_rw_mutex&&)
async_rw_mutex(async_rw_mutex const&)
async_rw_mutex &operator=(async_rw_mutex const&)
sender<detail::async_rw_mutex_access_type::read> read()
sender<detail::async_rw_mutex_access_type::readwrite> readwrite()

Private Types

template<>
using shared_state_type = detail::async_rw_mutex_shared_state<value_type>
template<>
using shared_state_ptr_type = std::shared_ptr<shared_state_type>

Private Members

value_type value
allocator_type alloc
detail::async_rw_mutex_access_type prev_access = detail::async_rw_mutex_access_type::readwrite
shared_state_ptr_type prev_state
shared_state_ptr_type state
template<detail::async_rw_mutex_access_type AccessType>
struct sender

Public Types

template<>
template<>
using access_type = detail::async_rw_mutex_access_wrapper<readwrite_type, read_type, AccessType>
template<>
template<template<typename...> class Tuple, template<typename...> class Variant>
using value_types = Variant<Tuple<access_type>>
template<>
template<template<typename...> class Variant>
using error_types = Variant<std::exception_ptr>

Public Functions

template<typename R>
auto connect(R &&r) &&

Public Members

template<>
shared_state_ptr_type prev_state
template<>
shared_state_ptr_type state

Public Static Attributes

template<>
constexpr bool sends_done = false
template<typename R>
struct operation_state

Public Functions

template<>
template<typename R_>
operation_state(R_ &&r, shared_state_ptr_type prev_state, shared_state_ptr_type state)
template<>
template<>
operation_state(operation_state&&)
template<>
template<>
operation_state &operator=(operation_state&&)
template<>
template<>
operation_state(operation_state const&)
template<>
template<>
operation_state &operator=(operation_state const&)
template<>
template<>
void start()

Public Members

template<>
template<>
std::decay_t<R> r
template<>
template<>
shared_state_ptr_type prev_state
template<>
template<>
shared_state_ptr_type state
template<typename Allocator>
class async_rw_mutex<void, void, Allocator>

Public Types

template<>
using read_type = void
template<>
using readwrite_type = void
template<>
using read_access_type = detail::async_rw_mutex_access_wrapper<readwrite_type, read_type, detail::async_rw_mutex_access_type::read>
template<>
using readwrite_access_type = detail::async_rw_mutex_access_wrapper<readwrite_type, read_type, detail::async_rw_mutex_access_type::readwrite>
template<>
using allocator_type = Allocator

Public Functions

async_rw_mutex(allocator_type const &alloc = {})
async_rw_mutex(async_rw_mutex&&)
async_rw_mutex &operator=(async_rw_mutex&&)
async_rw_mutex(async_rw_mutex const&)
async_rw_mutex &operator=(async_rw_mutex const&)
sender<detail::async_rw_mutex_access_type::read> read()
sender<detail::async_rw_mutex_access_type::readwrite> readwrite()

Private Types

template<>
using shared_state_type = detail::async_rw_mutex_shared_state<void>
template<>
using shared_state_ptr_type = std::shared_ptr<shared_state_type>

Private Members

allocator_type alloc
detail::async_rw_mutex_access_type prev_access = detail::async_rw_mutex_access_type::readwrite
shared_state_ptr_type prev_state
shared_state_ptr_type state
template<detail::async_rw_mutex_access_type AccessType>
struct sender

Public Types

template<>
template<>
using access_type = detail::async_rw_mutex_access_wrapper<readwrite_type, read_type, AccessType>
template<>
template<template<typename...> class Tuple, template<typename...> class Variant>
using value_types = Variant<Tuple<access_type>>
template<>
template<template<typename...> class Variant>
using error_types = Variant<std::exception_ptr>

Public Functions

template<typename R>
auto connect(R &&r) &&

Public Members

template<>
shared_state_ptr_type prev_state
template<>
shared_state_ptr_type state

Public Static Attributes

template<>
constexpr bool sends_done = false
template<typename R>
struct operation_state

Public Functions

template<>
template<typename R_>
operation_state(R_ &&r, shared_state_ptr_type prev_state, shared_state_ptr_type state)
template<>
template<>
operation_state(operation_state&&)
template<>
template<>
operation_state &operator=(operation_state&&)
template<>
template<>
operation_state(operation_state const&)
template<>
template<>
operation_state &operator=(operation_state const&)
template<>
template<>
void start()

Public Members

template<>
template<>
std::decay_t<R> r
template<>
template<>
shared_state_ptr_type prev_state
template<>
template<>
shared_state_ptr_type state
namespace hpx
namespace lcos
namespace local
class barrier
#include <barrier.hpp>

A barrier can be used to synchronize a specific number of threads, blocking all of the entering threads until all of the threads have entered the barrier.

Note

A barrier is not a LCO in the sense that it has no global id and it can’t be triggered using the action (parcel) mechanism. It is just a low level synchronization primitive allowing to synchronize a given number of threads.

Public Functions

barrier(std::size_t number_of_threads)
~barrier()
void wait()

The function wait will block the number of entering threads (as given by the constructor parameter number_of_threads), releasing all waiting threads as soon as the last thread entered this function.

void count_up()

The function count_up will increase the number of threads to be waited in wait function.

void reset(std::size_t number_of_threads)

The function reset will reset the number of threads as given by the function parameter number_of_threads. the newer coming threads executing the function wait will be waiting until total_ is equal to barrier_flag. The last thread exiting the wait function will notify the newer threads waiting and the newer threads will get the reset number_of_threads_. The function reset can be executed while previous threads executing waiting after they have been waken up. Thus total_ can not be reset to barrier_flag which will break the comparison condition under the function wait.

Private Types

typedef lcos::local::spinlock mutex_type

Private Members

std::size_t number_of_threads_
std::size_t total_
mutex_type mtx_
local::detail::condition_variable cond_

Private Static Attributes

constexpr std::size_t barrier_flag = static_cast<std::size_t>(1) << (CHAR_BIT * sizeof(std::size_t) - 1)
template<typename OnCompletion = detail::empty_oncompletion>
class cpp20_barrier

Public Types

template<>
using arrival_token = bool

Public Functions

HPX_NON_COPYABLE(cpp20_barrier)
cpp20_barrier(std::ptrdiff_t expected, OnCompletion completion = OnCompletion())
HPX_NODISCARD arrival_token hpx::lcos::local::cpp20_barrier::arrive(std::ptrdiff_t update = 1)
void wait(arrival_token &&old_phase) const
void arrive_and_wait()

Effects: Equivalent to: wait(arrive()).

void arrive_and_drop()

Public Static Functions

static constexpr std::ptrdiff_t() hpx::lcos::local::cpp20_barrier::max()

Private Types

template<>
using mutex_type = lcos::local::spinlock

Private Members

mutex_type mtx_
local::detail::condition_variable cond_
std::ptrdiff_t expected_
std::ptrdiff_t arrived_
OnCompletion completion_
bool phase_
namespace hpx
namespace lcos
namespace local

Typedefs

template<typename T>
using channel_mpmc = bounded_channel<T, hpx::lcos::local::spinlock>
template<typename T, typename Mutex = util::spinlock>
class bounded_channel

Public Functions

bounded_channel(std::size_t size)
bounded_channel(bounded_channel &&rhs)
bounded_channel &operator=(bounded_channel &&rhs)
~bounded_channel()
bool get(T *val = nullptr) const
bool set(T &&t)
std::size_t close()
std::size_t capacity() const

Protected Functions

std::size_t close(std::unique_lock<mutex_type> &l)

Private Types

template<>
using mutex_type = Mutex

Private Functions

bool is_full(std::size_t tail) const
bool is_empty(std::size_t head) const

Private Members

hpx::util::cache_aligned_data<mutex_type> mtx_
hpx::util::cache_aligned_data<std::size_t> head_
hpx::util::cache_aligned_data<std::size_t> tail_
std::size_t size_
std::unique_ptr<T[]> buffer_
bool closed_
namespace hpx
namespace lcos
namespace local

Typedefs

template<typename T>
using channel_mpsc = base_channel_mpsc<T, hpx::lcos::local::spinlock>
template<typename T, typename Mutex = util::spinlock>
class base_channel_mpsc

Public Functions

base_channel_mpsc(std::size_t size)
base_channel_mpsc(base_channel_mpsc &&rhs)
base_channel_mpsc &operator=(base_channel_mpsc &&rhs)
~base_channel_mpsc()
bool get(T *val = nullptr) const
bool set(T &&t)
std::size_t close()
std::size_t capacity() const

Private Types

template<>
using mutex_type = Mutex

Private Functions

bool is_full(std::size_t tail) const
bool is_empty(std::size_t head) const

Private Members

hpx::util::cache_aligned_data<std::atomic<std::size_t>> head_
hpx::util::cache_aligned_data<tail_data> tail_
std::size_t size_
std::unique_ptr<T[]> buffer_
std::atomic<bool> closed_
struct tail_data

Public Members

template<>
mutex_type mtx_
template<>
std::atomic<std::size_t> tail_
namespace hpx
namespace lcos
namespace local
template<typename T>
class channel_spsc

Public Functions

channel_spsc(std::size_t size)
channel_spsc(channel_spsc &&rhs)
channel_spsc &operator=(channel_spsc &&rhs)
~channel_spsc()
bool get(T *val = nullptr) const
bool set(T &&t)
std::size_t close()
std::size_t capacity() const

Private Functions

bool is_full(std::size_t tail) const
bool is_empty(std::size_t head) const

Private Members

hpx::util::cache_aligned_data<std::atomic<std::size_t>> head_
hpx::util::cache_aligned_data<std::atomic<std::size_t>> tail_
std::size_t size_
std::unique_ptr<T[]> buffer_
std::atomic<bool> closed_
namespace hpx
namespace lcos
namespace local

Enums

enum cv_status

Values:

no_timeout
timeout
error
class condition_variable

Public Functions

condition_variable()
~condition_variable()
void notify_one(error_code &ec = throws)
void notify_all(error_code &ec = throws)
template<typename Mutex>
void wait(std::unique_lock<Mutex> &lock, error_code &ec = throws)
template<typename Mutex, typename Predicate>
void wait(std::unique_lock<Mutex> &lock, Predicate pred, error_code& = throws)
template<typename Mutex>
cv_status wait_until(std::unique_lock<Mutex> &lock, hpx::chrono::steady_time_point const &abs_time, error_code &ec = throws)
template<typename Mutex, typename Predicate>
bool wait_until(std::unique_lock<Mutex> &lock, hpx::chrono::steady_time_point const &abs_time, Predicate pred, error_code &ec = throws)
template<typename Mutex>
cv_status wait_for(std::unique_lock<Mutex> &lock, hpx::chrono::steady_duration const &rel_time, error_code &ec = throws)
template<typename Mutex, typename Predicate>
bool wait_for(std::unique_lock<Mutex> &lock, hpx::chrono::steady_duration const &rel_time, Predicate pred, error_code &ec = throws)

Private Types

using mutex_type = detail::condition_variable_data::mutex_type
using data_type = hpx::memory::intrusive_ptr<detail::condition_variable_data>

Private Members

hpx::util::cache_aligned_data_derived<data_type> data_
class condition_variable_any

Public Functions

condition_variable_any()
~condition_variable_any()
void notify_one(error_code &ec = throws)
void notify_all(error_code &ec = throws)
template<typename Lock>
void wait(Lock &lock, error_code &ec = throws)
template<typename Lock, typename Predicate>
void wait(Lock &lock, Predicate pred, error_code& = throws)
template<typename Lock>
cv_status wait_until(Lock &lock, hpx::chrono::steady_time_point const &abs_time, error_code &ec = throws)
template<typename Lock, typename Predicate>
bool wait_until(Lock &lock, hpx::chrono::steady_time_point const &abs_time, Predicate pred, error_code &ec = throws)
template<typename Lock>
cv_status wait_for(Lock &lock, hpx::chrono::steady_duration const &rel_time, error_code &ec = throws)
template<typename Lock, typename Predicate>
bool wait_for(Lock &lock, hpx::chrono::steady_duration const &rel_time, Predicate pred, error_code &ec = throws)
template<typename Lock, typename Predicate>
bool wait(Lock &lock, stop_token stoken, Predicate pred, error_code &ec = throws)
template<typename Lock, typename Predicate>
bool wait_until(Lock &lock, stop_token stoken, hpx::chrono::steady_time_point const &abs_time, Predicate pred, error_code &ec = throws)
template<typename Lock, typename Predicate>
bool wait_for(Lock &lock, stop_token stoken, hpx::chrono::steady_duration const &rel_time, Predicate pred, error_code &ec = throws)

Private Types

using mutex_type = detail::condition_variable_data::mutex_type
using data_type = hpx::memory::intrusive_ptr<detail::condition_variable_data>

Private Members

hpx::util::cache_aligned_data_derived<data_type> data_
namespace hpx
namespace lcos
namespace local

Typedefs

typedef counting_semaphore_var counting_semaphore
template<typename Mutex = hpx::lcos::local::spinlock, int N = 0>
class counting_semaphore_var : private hpx::lcos::local::cpp20_counting_semaphore<PTRDIFF_MAX, hpx::lcos::local::spinlock>

Public Functions

counting_semaphore_var(std::ptrdiff_t value = N)
counting_semaphore_var(counting_semaphore_var const&)
counting_semaphore_var &operator=(counting_semaphore_var const&)
void wait(std::ptrdiff_t count = 1)
bool try_wait(std::ptrdiff_t count = 1)
void signal(std::ptrdiff_t count = 1)

Signal the semaphore.

std::ptrdiff_t signal_all()

Private Types

template<>
using mutex_type = Mutex
template<typename Mutex = hpx::lcos::local::spinlock>
class cpp20_binary_semaphore : public hpx::lcos::local::cpp20_counting_semaphore<1, hpx::lcos::local::spinlock>

Public Functions

HPX_NON_COPYABLE(cpp20_binary_semaphore)
cpp20_binary_semaphore(std::ptrdiff_t value = 1)
~cpp20_binary_semaphore()
template<std::ptrdiff_t LeastMaxValue = PTRDIFF_MAX, typename Mutex = hpx::lcos::local::spinlock>
class cpp20_counting_semaphore

Public Functions

HPX_NON_COPYABLE(cpp20_counting_semaphore)
cpp20_counting_semaphore(std::ptrdiff_t value)
~cpp20_counting_semaphore()
void release(std::ptrdiff_t update = 1)
bool try_acquire()
void acquire()
bool try_acquire_until(hpx::chrono::steady_time_point const &abs_time)
bool try_acquire_for(hpx::chrono::steady_duration const &rel_time)

Public Static Functions

static constexpr std::ptrdiff_t() hpx::lcos::local::cpp20_counting_semaphore::max()

Protected Types

template<>
using mutex_type = Mutex

Protected Attributes

mutex_type mtx_
detail::counting_semaphore sem_
namespace hpx
namespace lcos
namespace local
class event
#include <event.hpp>

Event semaphores can be used for synchronizing multiple threads that need to wait for an event to occur. When the event occurs, all threads waiting for the event are woken up.

Public Functions

event()

Construct a new event semaphore.

bool occurred()

Check if the event has occurred.

void wait()

Wait for the event to occur.

void set()

Release all threads waiting on this semaphore.

void reset()

Reset the event.

Private Types

typedef lcos::local::spinlock mutex_type

Private Functions

void wait_locked(std::unique_lock<mutex_type> &l)
void set_locked(std::unique_lock<mutex_type> l)

Private Members

mutex_type mtx_

This mutex protects the queue.

local::detail::condition_variable cond_
std::atomic<bool> event_
namespace hpx
namespace lcos
namespace local
class cpp20_latch
#include <latch.hpp>

Latches are a thread coordination mechanism that allow one or more threads to block until an operation is completed. An individual latch is a singleuse object; once the operation has been completed, the latch cannot be reused.

Subclassed by hpx::lcos::local::latch

Public Functions

HPX_NON_COPYABLE(cpp20_latch)
cpp20_latch(std::ptrdiff_t count)

Initialize the latch

Requires: count >= 0. Synchronization: None Postconditions: counter_ == count.

~cpp20_latch()

Requires: No threads are blocked at the synchronization point.

Note

May be called even if some threads have not yet returned from wait() or count_down_and_wait(), provided that counter_ is 0.

Note

The destructor might not return until all threads have exited wait() or count_down_and_wait().

Note

It is the caller’s responsibility to ensure that no other thread enters wait() after one thread has called the destructor. This may require additional coordination.

void count_down(std::ptrdiff_t update)

Decrements counter_ by n. Does not block.

Requires: counter_ >= n and n >= 0.

Synchronization: Synchronizes with all calls that block on this latch and with all try_wait calls on this latch that return true .

Exceptions
  • Nothing.:

bool try_wait() const

Returns: With very low probability false. Otherwise counter == 0.

void wait() const

If counter_ is 0, returns immediately. Otherwise, blocks the calling thread at the synchronization point until counter_ reaches 0.

Exceptions
  • Nothing.:

void arrive_and_wait(std::ptrdiff_t update = 1)

Effects: Equivalent to: count_down(update); wait();

Public Static Functions

static constexpr std::ptrdiff_t() hpx::lcos::local::cpp20_latch::max()

Returns: The maximum value of counter that the implementation supports.

Protected Types

using mutex_type = lcos::local::spinlock

Protected Attributes

util::cache_line_data<mutex_type> mtx_
util::cache_line_data<local::detail::condition_variable> cond_
std::atomic<std::ptrdiff_t> counter_
bool notified_
class latch : public hpx::lcos::local::cpp20_latch
#include <latch.hpp>

A latch maintains an internal counter_ that is initialized when the latch is created. Threads may block at a synchronization point waiting for counter_ to be decremented to 0. When counter_ reaches 0, all such blocked threads are released.

Calls to countdown_and_wait() , count_down() , wait() , is_ready(), count_up() , and reset() behave as atomic operations.

Note

A local::latch is not an LCO in the sense that it has no global id and it can’t be triggered using the action (parcel) mechanism. Use lcos::latch instead if this is required. It is just a low level synchronization primitive allowing to synchronize a given number of threads.

Public Functions

HPX_NON_COPYABLE(latch)
latch(std::ptrdiff_t count)

Initialize the latch

Requires: count >= 0. Synchronization: None Postconditions: counter_ == count.

~latch()

Requires: No threads are blocked at the synchronization point.

Note

May be called even if some threads have not yet returned from wait() or count_down_and_wait(), provided that counter_ is 0.

Note

The destructor might not return until all threads have exited wait() or count_down_and_wait().

Note

It is the caller’s responsibility to ensure that no other thread enters wait() after one thread has called the destructor. This may require additional coordination.

void count_down_and_wait()

Decrements counter_ by 1 . Blocks at the synchronization point until counter_ reaches 0.

Requires: counter_ > 0.

Synchronization: Synchronizes with all calls that block on this latch and with all is_ready calls on this latch that return true.

Exceptions
  • Nothing.:

bool is_ready() const

Returns: counter_ == 0. Does not block.

Exceptions
  • Nothing.:

void abort_all()
void count_up(std::ptrdiff_t n)

Increments counter_ by n. Does not block.

Requires: n >= 0.

Exceptions
  • Nothing.:

void reset(std::ptrdiff_t n)

Reset counter_ to n. Does not block.

Requires: n >= 0.

Exceptions
  • Nothing.:

namespace hpx
namespace lcos
namespace local

Functions

template<typename Mutex>
void swap(upgrade_lock<Mutex> &lhs, upgrade_lock<Mutex> &rhs)
template<typename Mutex>
class upgrade_lock

Public Types

template<>
using mutex_type = Mutex

Public Functions

upgrade_lock(upgrade_lock const&)
upgrade_lock &operator=(upgrade_lock const&)
upgrade_lock()
upgrade_lock(Mutex &m_)
upgrade_lock(Mutex &m_, std::adopt_lock_t)
upgrade_lock(Mutex &m_, std::defer_lock_t)
upgrade_lock(Mutex &m_, std::try_to_lock_t)
upgrade_lock(upgrade_lock<Mutex> &&other)
upgrade_lock(std::unique_lock<Mutex> &&other)
upgrade_lock &operator=(upgrade_lock<Mutex> &&other)
void swap(upgrade_lock &other)
Mutex *mutex() const
Mutex *release()
~upgrade_lock()
void lock()
bool try_lock()
void unlock()
operator bool() const
bool owns_lock() const

Protected Attributes

Mutex *m
bool is_locked

Friends

friend hpx::lcos::local::upgrade_to_unique_lock
template<typename Mutex>
class upgrade_to_unique_lock

Public Types

template<>
using mutex_type = Mutex

Public Functions

upgrade_to_unique_lock(upgrade_to_unique_lock const&)
upgrade_to_unique_lock &operator=(upgrade_to_unique_lock const&)
upgrade_to_unique_lock(upgrade_lock<Mutex> &m_)
~upgrade_to_unique_lock()
upgrade_to_unique_lock(upgrade_to_unique_lock<Mutex> &&other)
upgrade_to_unique_lock &operator=(upgrade_to_unique_lock<Mutex> &&other)
void swap(upgrade_to_unique_lock &other)
operator bool() const
bool owns_lock() const
Mutex *mutex() const

Private Members

upgrade_lock<Mutex> *source
std::unique_lock<Mutex> exclusive
namespace hpx
namespace lcos
namespace local
class mutex

Subclassed by hpx::lcos::local::timed_mutex

Public Functions

HPX_NON_COPYABLE(mutex)
mutex(char const *const description = "")
~mutex()
void lock(char const *description, error_code &ec = throws)
void lock(error_code &ec = throws)
bool try_lock(char const *description, error_code &ec = throws)
bool try_lock(error_code &ec = throws)
void unlock(error_code &ec = throws)

Protected Types

typedef lcos::local::spinlock mutex_type

Protected Attributes

mutex_type mtx_
threads::thread_id_type owner_id_
lcos::local::detail::condition_variable cond_
class timed_mutex : private hpx::lcos::local::mutex

Public Functions

HPX_NON_COPYABLE(timed_mutex)
timed_mutex(char const *const description = "")
~timed_mutex()
bool try_lock_until(hpx::chrono::steady_time_point const &abs_time, char const *description, error_code &ec = throws)
bool try_lock_until(hpx::chrono::steady_time_point const &abs_time, error_code &ec = throws)
bool try_lock_for(hpx::chrono::steady_duration const &rel_time, char const *description, error_code &ec = throws)
bool try_lock_for(hpx::chrono::steady_duration const &rel_time, error_code &ec = throws)
void lock(char const *description, error_code &ec = throws)
void lock(error_code &ec = throws)
bool try_lock(char const *description, error_code &ec = throws)
bool try_lock(error_code &ec = throws)
void unlock(error_code &ec = throws)
namespace threads

Typedefs

using thread_id_type = thread_id
using thread_self = coroutines::detail::coroutine_self

Functions

thread_id_type get_self_id()

The function get_self_id returns the HPX thread id of the current thread (or zero if the current thread is not a HPX thread).

thread_self *get_self_ptr()

The function get_self_ptr returns a pointer to the (OS thread specific) self reference to the current HPX thread.

namespace hpx
namespace lcos
namespace local
struct no_mutex

Public Functions

void lock()
bool try_lock()
void unlock()

Defines

HPX_ONCE_INIT
namespace hpx
namespace lcos
namespace local

Functions

template<typename F, typename ...Args>
void call_once(once_flag &flag, F &&f, Args&&... args)
struct once_flag

Public Functions

HPX_NON_COPYABLE(once_flag)
once_flag()

Private Members

std::atomic<long> status_
lcos::local::event event_

Friends

template<typename F, typename ...Args>
void call_once(once_flag &flag, F &&f, Args&&... args)
namespace hpx
namespace lcos
namespace local

Typedefs

using recursive_mutex = detail::recursive_mutex_impl<>
namespace hpx
namespace lcos
namespace local

Typedefs

typedef detail::shared_mutex shared_mutex
namespace hpx
namespace lcos
namespace local

Typedefs

typedef sliding_semaphore_var sliding_semaphore
template<typename Mutex = hpx::lcos::local::spinlock>
class sliding_semaphore_var
#include <sliding_semaphore.hpp>

A semaphore is a protected variable (an entity storing a value) or abstract data type (an entity grouping several variables that may or may not be numerical) which constitutes the classic method for restricting access to shared resources, such as shared memory, in a multiprogramming environment. Semaphores exist in many variants, though usually the term refers to a counting semaphore, since a binary semaphore is better known as a mutex. A counting semaphore is a counter for a set of available resources, rather than a locked/unlocked flag of a single resource. It was invented by Edsger Dijkstra. Semaphores are the classic solution to preventing race conditions in the dining philosophers problem, although they do not prevent resource deadlocks.

Sliding semaphores can be used for synchronizing multiple threads as well: one thread waiting for several other threads to touch (signal) the semaphore, or several threads waiting for one other thread to touch this semaphore. The difference to a counting semaphore is that a sliding semaphore will not limit the number of threads which are allowed to proceed, but will make sure that the difference between the (arbitrary) number passed to set and wait does not exceed a given threshold.

Public Functions

sliding_semaphore_var(std::int64_t max_difference, std::int64_t lower_limit = 0)

Construct a new sliding semaphore.

Parameters
  • max_difference: [in] The max difference between the upper limit (as set by wait()) and the lower limit (as set by signal()) which is allowed without suspending any thread calling wait().

  • lower_limit: [in] The initial lower limit.

void set_max_difference(std::int64_t max_difference, std::int64_t lower_limit = 0)

Set/Change the difference that will cause the semaphore to trigger.

Parameters
  • max_difference: [in] The max difference between the upper limit (as set by wait()) and the lower limit (as set by signal()) which is allowed without suspending any thread calling wait().

  • lower_limit: [in] The initial lower limit.

void wait(std::int64_t upper_limit)

Wait for the semaphore to be signaled.

Parameters
  • upper_limit: [in] The new upper limit. The calling thread will be suspended if the difference between this value and the largest lower_limit which was set by signal() is larger than the max_difference.

bool try_wait(std::int64_t upper_limit = 1)

Try to wait for the semaphore to be signaled.

Return

The function returns true if the calling thread would not block if it was calling wait().

Parameters
  • upper_limit: [in] The new upper limit. The calling thread will be suspended if the difference between this value and the largest lower_limit which was set by signal() is larger than the max_difference.

void signal(std::int64_t lower_limit)

Signal the semaphore.

Parameters
  • lower_limit: [in] The new lower limit. This will update the current lower limit of this semaphore. It will also re-schedule all suspended threads for which their associated upper limit is not larger than the lower limit plus the max_difference.

std::int64_t signal_all()

Private Types

typedef Mutex mutex_type

Private Members

mutex_type mtx_
detail::sliding_semaphore sem_
namespace hpx
namespace lcos
namespace local
struct spinlock

Public Functions

HPX_NON_COPYABLE(spinlock)
spinlock(char const *const desc = "hpx::lcos::local::spinlock")
~spinlock()
void lock()
bool try_lock()
void unlock()

Private Functions

bool acquire_lock()
void relinquish_lock()
bool is_locked() const

Private Members

std::atomic<bool> v_
namespace hpx
namespace lcos
namespace local
struct spinlock_no_backoff
#include <spinlock_no_backoff.hpp>

boost::mutex-compatible spinlock class

Public Functions

HPX_NON_COPYABLE(spinlock_no_backoff)
spinlock_no_backoff()
~spinlock_no_backoff()
void lock()
bool try_lock()
void unlock()

Private Functions

bool acquire_lock()
void relinquish_lock()
bool is_locked() const

Private Members

std::atomic<bool> v_
namespace hpx
namespace lcos
namespace local
template<typename Tag, std::size_t N = HPX_HAVE_SPINLOCK_POOL_NUM>
class spinlock_pool

Public Static Functions

static lcos::local::spinlock &spinlock_for(void const *pv)

Private Static Attributes

util::cache_aligned_data<lcos::local::spinlock> pool_
class scoped_lock

Public Functions

template<>
HPX_NON_COPYABLE(scoped_lock)
template<>
scoped_lock(void const *pv)
template<>
~scoped_lock()
template<>
void lock()
template<>
void unlock()

Private Members

template<>
hpx::lcos::local::spinlock &sp_
namespace hpx

Functions

template<typename Callback>
stop_callback<typename std::decay<Callback>::type> make_stop_callback(stop_token const &st, Callback &&cb)
template<typename Callback>
stop_callback<typename std::decay<Callback>::type> make_stop_callback(stop_token &&st, Callback &&cb)
void swap(stop_token &lhs, stop_token &rhs)
void swap(stop_source &lhs, stop_source &rhs)

Variables

HPX_INLINE_CONSTEXPR_VARIABLE nostopstate_t hpx::nostopstate = {}
struct nostopstate_t

Public Functions

nostopstate_t()
template<typename Callback>
class stop_callback : private hpx::detail::stop_callback_base

Public Types

template<>
using callback_type = Callback

Public Functions

template<typename CB, typename Enable = typename std::enable_if<std::is_constructible<Callback, CB>::value>::type>
stop_callback(stop_token const &st, CB &&cb)
template<typename CB, typename Enable = typename std::enable_if<std::is_constructible<Callback, CB>::value>::type>
stop_callback(stop_token &&st, CB &&cb)
~stop_callback()
stop_callback(stop_callback const&)
stop_callback(stop_callback&&)
stop_callback &operator=(stop_callback const&)
stop_callback &operator=(stop_callback&&)

Private Functions

void execute()

Private Members

Callback callback_
hpx::memory::intrusive_ptr<detail::stop_state> state_
class stop_source

Public Functions

stop_source()
stop_source(nostopstate_t)
stop_source(stop_source const &rhs)
stop_source(stop_source&&)
stop_source &operator=(stop_source const &rhs)
stop_source &operator=(stop_source&&)
~stop_source()
void swap(stop_source &s)
HPX_NODISCARD stop_token hpx::stop_source::get_token() const
HPX_NODISCARD bool hpx::stop_source::stop_possible() const
HPX_NODISCARD bool hpx::stop_source::stop_requested() const
bool request_stop()

Private Members

hpx::memory::intrusive_ptr<detail::stop_state> state_

Friends

HPX_NODISCARD friend bool operator==(stop_source  const & lhs, stop_source  const & rhs)
HPX_NODISCARD friend bool operator!=(stop_source  const & lhs, stop_source  const & rhs)
class stop_token

Public Functions

stop_token()
stop_token(stop_token const &rhs)
stop_token(stop_token&&)
stop_token &operator=(stop_token const &rhs)
stop_token &operator=(stop_token&&)
~stop_token()
void swap(stop_token &s)
HPX_NODISCARD bool hpx::stop_token::stop_requested() const
HPX_NODISCARD bool hpx::stop_token::stop_possible() const

Private Functions

stop_token(hpx::memory::intrusive_ptr<detail::stop_state> const &state)

Private Members

hpx::memory::intrusive_ptr<detail::stop_state> state_

Friends

friend hpx::stop_callback
friend hpx::stop_source
HPX_NODISCARD friend bool operator==(stop_token  const & lhs, stop_token  const & rhs)
HPX_NODISCARD friend bool operator!=(stop_token  const & lhs, stop_token  const & rhs)