hpx::counting_semaphore#

Defined in header hpx/semaphore.hpp.

See Public API for a list of names and headers that are part of the public HPX API.

namespace hpx
template<std::ptrdiff_t LeastMaxValue = PTRDIFF_MAX>
class counting_semaphore#
#include <counting_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.

Counting 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. Unlike hpx::mutex a counting_semaphore is not tied to threads of execution &#8212; acquiring a semaphore can occur on a different thread than releasing the semaphore, for example. All operations on counting_semaphore can be performed concurrently and without any relation to specific threads of execution, with the exception of the destructor which cannot be performed concurrently but can be performed on a different thread.

Semaphores are lightweight synchronization primitives used to constrain concurrent access to a shared resource. They are widely used to implement other synchronization primitives and, whenever both are applicable, can be more efficient than condition variables.

A counting semaphore is a semaphore object that models a non-negative resource count.

Class template counting_semaphore maintains an internal counter that is initialized when the semaphore is created. The counter is decremented when a thread acquires the semaphore, and is incremented when a thread releases the semaphore. If a thread tries to acquire the semaphore when the counter is zero, the thread will block until another thread increments the counter by releasing the semaphore.

Specializations of hpx::counting_semaphore are not DefaultConstructible, CopyConstructible, MoveConstructible, CopyAssignable, or MoveAssignable.

Note

counting_semaphore’s try_acquire() can spuriously fail.

Template Parameters

LeastMaxValuecounting_semaphore allows more than one concurrent access to the same resource, for at least LeastMaxValue concurrent accessors. As its name indicates, the LeastMaxValue is the minimum max value, not the actual max value. Thus max() can yield a number larger than LeastMaxValue.

Public Functions

counting_semaphore(counting_semaphore const&) = delete#
counting_semaphore &operator=(counting_semaphore const&) = delete#
counting_semaphore(counting_semaphore&&) = delete#
counting_semaphore &operator=(counting_semaphore&&) = delete#
explicit counting_semaphore(std::ptrdiff_t value)#

Constructs an object of type hpx::counting_semaphore with the internal counter initialized to value.

Parameters

value – The initial value of the internal semaphore lock count. Normally this value should be zero (which is the default), values greater than zero are equivalent to the same number of signals pre-set, and negative values are equivalent to the same number of waits pre-set.

~counting_semaphore() = default#
void release(std::ptrdiff_t update = 1)#

Atomically increments the internal counter by the value of update. Any thread(s) waiting for the counter to be greater than 0, such as due to being blocked in acquire, will subsequently be unblocked.

Note

Synchronization: Strongly happens before invocations of try_acquire that observe the result of the effects.

Throws

std::system_error

Parameters

update – the amount to increment the internal counter by

Pre

Both update >= 0 and update <= max() - counter are true, where counter is the value of the internal counter.

bool try_acquire() noexcept#

Tries to atomically decrement the internal counter by 1 if it is greater than 0; no blocking occurs regardless.

Returns

true if it decremented the internal counter, otherwise false

void acquire()#

Repeatedly performs the following steps, in order:

  • Evaluates try_acquire. If the result is true, returns.

  • Blocks on *this until counter is greater than zero.

Throws

std::system_error

Returns

void.

bool try_acquire_until(hpx::chrono::steady_time_point const &abs_time)#

Tries to atomically decrement the internal counter by 1 if it is greater than 0; otherwise blocks until it is greater than 0 and can successfully decrement the internal counter, or the abs_time time point has been passed.

Parameters

abs_time – the earliest time the function must wait until in order to fail

Throws

std::system_error

Returns

true if it decremented the internal counter, otherwise false.

bool try_acquire_for(hpx::chrono::steady_duration const &rel_time)#

Tries to atomically decrement the internal counter by 1 if it is greater than 0; otherwise blocks until it is greater than 0 and can successfully decrement the internal counter, or the rel_time duration has been exceeded.

Throws

std::system_error

Parameters

rel_time – the minimum duration the function must wait for to fail

Returns

true if it decremented the internal counter, otherwise false

Public Static Functions

static constexpr std::ptrdiff_t max() noexcept#

Returns The maximum value of counter. This value is greater than or equal to LeastMaxValue.

Returns

The internal counter’s maximum possible value, as a std::ptrdiff_t.

template<typename Mutex = hpx::spinlock, int N = 0>
class counting_semaphore_var#
#include <counting_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.

Counting 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. Unlike hpx::mutex a counting_semaphore_var is not tied to threads of execution &#8212; acquiring a semaphore can occur on a different thread than releasing the semaphore, for example. All operations on counting_semaphore_var can be performed concurrently and without any relation to specific threads of execution, with the exception of the destructor which cannot be performed concurrently but can be performed on a different thread.

Semaphores are lightweight synchronization primitives used to constrain concurrent access to a shared resource. They are widely used to implement other synchronization primitives and, whenever both are applicable, can be more efficient than condition variables.

A counting semaphore is a semaphore object that models a non-negative resource count.

Class template counting_semaphore_var maintains an internal counter that is initialized when the semaphore is created. The counter is decremented when a thread acquires the semaphore, and is incremented when a thread releases the semaphore. If a thread tries to acquire the semaphore when the counter is zero, the thread will block until another thread increments the counter by releasing the semaphore.

Specializations of hpx::counting_semaphore_var are not DefaultConstructible, CopyConstructible, MoveConstructible, CopyAssignable, or MoveAssignable.

Note

counting_semaphore_var’s try_acquire() can spuriously fail.

Template Parameters
  • Mutex – Type of mutex

  • N – The initial value of the internal semaphore lock count.

Public Functions

explicit counting_semaphore_var(std::ptrdiff_t value = N)#

Constructs an object of type hpx::counting_semaphore_value with the internal counter initialized to N.

Parameters

value – The initial value of the internal semaphore lock count. Normally this value should be zero, values greater than zero are equivalent to the same number of signals pre-set, and negative values are equivalent to the same number of waits pre-set. Defaults to N (which in turn defaults to zero).

counting_semaphore_var(counting_semaphore_var const&) = delete#
counting_semaphore_var &operator=(counting_semaphore_var const&) = delete#
void wait(std::ptrdiff_t count = 1)#

Wait for the semaphore to be signaled.

Parameters

count – The value by which the internal lock count will be decremented. At the same time this is the minimum value of the lock count at which the thread is not yielded.

bool try_wait(std::ptrdiff_t count = 1)#

Try to wait for the semaphore to be signaled.

Parameters

count – The value by which the internal lock count will be decremented. At the same time this is the minimum value of the lock count at which the thread is not yielded.

Returns

try_wait returns true if the calling thread was able to acquire the requested amount of credits. try_wait returns false if not sufficient credits are available at this point in time.

void signal(std::ptrdiff_t count = 1)#

Signal the semaphore.

Parameters

count – The value by which the internal lock count will be incremented.

std::ptrdiff_t signal_all()#

Unblock all acquirers.

Returns

std::ptrdiff_t internal lock count after the operation.

void release(std::ptrdiff_t update = 1)#

Atomically increments the internal counter by the value of update. Any thread(s) waiting for the counter to be greater than 0, such as due to being blocked in acquire, will subsequently be unblocked.

Note

Synchronization: Strongly happens before invocations of try_acquire that observe the result of the effects.

Throws

std::system_error

Parameters

update – the amount to increment the internal counter by

Pre

Both update >= 0 and update <= max() - counter are true, where counter is the value of the internal counter.

bool try_acquire() noexcept#

Tries to atomically decrement the internal counter by 1 if it is greater than 0; no blocking occurs regardless.

Returns

true if it decremented the internal counter, otherwise false

void acquire()#

Repeatedly performs the following steps, in order:

  • Evaluates try_acquire. If the result is true, returns.

Blocks on *this until counter is greater than zero.

Throws

std::system_error

Returns

void.

bool try_acquire_until(hpx::chrono::steady_time_point const &abs_time)#

Tries to atomically decrement the internal counter by 1 if it is greater than 0; otherwise blocks until it is greater than 0 and can successfully decrement the internal counter, or the abs_time time point has been passed.

Parameters

abs_time – the earliest time the function must wait until in order to fail

Throws

std::system_error

Returns

true if it decremented the internal counter, otherwise false.

bool try_acquire_for(hpx::chrono::steady_duration const &rel_time)#

Tries to atomically decrement the internal counter by 1 if it is greater than 0; otherwise blocks until it is greater than 0 and can successfully decrement the internal counter, or the rel_time duration has been exceeded.

Throws

std::system_error

Parameters

rel_time – the minimum duration the function must wait for to fail

Returns

true if it decremented the internal counter, otherwise false

Public Static Functions

static constexpr std::ptrdiff_t max() noexcept#

Returns The maximum value of counter. This value is greater than or equal to LeastMaxValue.

Returns

The internal counter’s maximum possible value, as a std::ptrdiff_t.

Private Types

using mutex_type = Mutex#