xentara-utils v2.0.4
The Xentara Utility Library
Loading...
Searching...
No Matches
xentara::utils::lockFree::ConditionVariable Class Reference

A notification that can be sent to one or more threads. More...

#include <xentara/utils/lockFree/ConditionVariable.hpp>

Classes

struct  Tracker
 A helper class that tracks which changes have already been seen. More...
 

Public Member Functions

auto wait (Tracker &tracker) const noexcept -> void
 Waits for a notification.
 
template<std::invocable Predicate>
auto wait (Predicate &&stopWaiting) const noexcept(std::is_nothrow_invocable_r_v< bool, Predicate >) -> void
 Waits for a certain condition to become true.
 
auto waitCounted (Tracker &tracker) const noexcept -> void
 Waits for each notification exactly one.
 
auto notify_one () noexcept -> void
 Notifies at least one thread, if one is waiting.
 
auto notify_all () noexcept -> void
 Notifies at least one thread, if one is waiting.
 

Detailed Description

A notification that can be sent to one or more threads.

This class can be used to notify threads of a condition, similar to std::condition_variable. Contrary to std::condition_variable, this class does not use a mutex, and is thus lock-free.

Member Function Documentation

◆ notify_all()

auto xentara::utils::lockFree::ConditionVariable::notify_all ( ) -> void
noexcept

Notifies at least one thread, if one is waiting.

This funtion will wake all waiting threads.

◆ notify_one()

auto xentara::utils::lockFree::ConditionVariable::notify_one ( ) -> void
noexcept

Notifies at least one thread, if one is waiting.

This funtion will wake at leat one thread, but more than one thread may wake up, if more threads are waiting.

◆ wait() [1/2]

template<std::invocable Predicate>
auto xentara::utils::lockFree::ConditionVariable::wait ( Predicate &&  stopWaiting) const -> void
noexcept

Waits for a certain condition to become true.

This function checks the predicate stopWaiting, and returns once the predicate has become true. if the predicate is false when the function is called, it will wait until woken up by notify_one() or notify_all(), and check again.

The function is essentiall equivalent to the following:

Tracker tracker;
while(!stopWaiting())
{
wait(tracker);
}
auto wait(Tracker &tracker) const noexcept -> void
Waits for a notification.
A helper class that tracks which changes have already been seen.
Definition ConditionVariable.hpp:30
Parameters
stopWaitingThe predicate that must become true for the wait to stop. Since this class doesn't use a mutex for synchronization, the predicate should use atomic operations to check the condition.

◆ wait() [2/2]

auto xentara::utils::lockFree::ConditionVariable::wait ( Tracker tracker) const -> void
noexcept

Waits for a notification.

This function waits until the thread is woken up by notify_one() or notify_all(). To prevent missed notification, the function uses a tracker to keep track what the last received notification. If a notification has occurred between this wait and the last wait, this function will return immediately. This prevents race conditions where a notification that occurs between to wait() calls can be missed.

If multiple notifications have been received since the last wait() call, all but the last is ignored. This function cannot be used to count notifications. To have exactly one wake-up for each notification, use waitCounted().

The first time wait() is called with a particular tracker, the function returns immediately, regardless of whether any notifications were ever issued.

This function is typically be called like this:

for (;;)
{
_notification.wait(tracker);
doWhateverNeedsToBeDone();
}
Parameters
trackerThe tracker to use to track notifications.

◆ waitCounted()

auto xentara::utils::lockFree::ConditionVariable::waitCounted ( Tracker tracker) const -> void
noexcept

Waits for each notification exactly one.

This function waits until the thread is woken up by notify_one() or notify_all(). If any notifications were missed since the last wait, wait() will return immediately exactly as many times as there were missed notifications. If, for example, three notifications were issued since the last wait, this function will return immediately the next three times it is called, and only block on the fourth call.

This function is typically be called like this:

for (;;)
{
_notification.waitCounted(tracker);
doOneStep();
}
Parameters
trackerThe tracker to use to track notifications.