xentara-utils v2.1
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<typename Rep , typename Period >
auto waitFor (Tracker &tracker, const std::chrono::duration< Rep, Period > &timeout) const noexcept -> bool
 Waits for a notification using a relative timeout.
 
template<typename Clock , typename Duration >
auto waitUntil (Tracker &tracker, const std::chrono::time_point< Clock, Duration > &timeoutTime) const noexcept -> bool
 Waits for a notification using an absolute timeout.
 
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.
 
template<std::invocable Predicate, typename Rep , typename Period >
auto waitFor (Predicate &&stopWaiting, const std::chrono::duration< Rep, Period > &timeout) const noexcept(std::is_nothrow_invocable_r_v< bool, Predicate >) -> bool
 Waits for a certain condition to become true using a relative timeout.
 
template<std::invocable Predicate, typename Clock , typename Duration >
auto waitUntil (Predicate &&stopWaiting, const std::chrono::time_point< Clock, Duration > &timeoutTime) const noexcept(std::is_nothrow_invocable_r_v< bool, Predicate >) -> bool
 Waits for a certain condition to become true using an absolute timeout.
 
auto waitCounted (Tracker &tracker) const noexcept -> void
 Waits for each notification exactly once.
 
template<typename Rep , typename Period >
auto waitCountedFor (Tracker &tracker, const std::chrono::duration< Rep, Period > &timeout) const noexcept -> bool
 Waits for each notification exactly once using a relative timeout.
 
template<typename Clock , typename Duration >
auto waitCountedUntil (Tracker &tracker, const std::chrono::time_point< Clock, Duration > &timeoutTime) const noexcept -> bool
 Waits for each notification exactly one using an absolute timeout.
 
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 function 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 function will wake at least 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 essentially equivalent to the following:

Tracker tracker;
while (!stopWaiting())
{
wait(tracker);
}
auto wait(Tracker &tracker) const noexcept -> void
Waits for a notification.
Definition ConditionVariable.hpp:459
A helper class that tracks which changes have already been seen.
Definition ConditionVariable.hpp:32
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 a wait function 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 once.

This function waits until the thread is woken up by notify_one() or notify_all(). If any notifications were missed since the last wait, waitCounted() 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 blocks 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.

◆ waitCountedFor()

template<typename Rep , typename Period >
auto xentara::utils::lockFree::ConditionVariable::waitCountedFor ( Tracker &  tracker,
const std::chrono::duration< Rep, Period > &  timeout 
) const -> bool
noexcept

Waits for each notification exactly once using a relative timeout.

This function waits until the thread is woken up by notify_one() or notify_all(), or until a specific time has elapsed. If any notifications were missed since the last wait, waitCountedFor() 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 (;;)
{
if (!_notification.waitCountedFor(tracker, timeout))
{
break;
}
doOneStep();
}
Parameters
trackerThe tracker to use to track notifications.
timeoutThe timeout.
Returns
Return true if a notification was received, or false on timeout.

◆ waitCountedUntil()

template<typename Clock , typename Duration >
auto xentara::utils::lockFree::ConditionVariable::waitCountedUntil ( Tracker &  tracker,
const std::chrono::time_point< Clock, Duration > &  timeoutTime 
) const -> bool
noexcept

Waits for each notification exactly one using an absolute timeout.

This function waits until the thread is woken up by notify_one() or notify_all(), or until a specific time point has been reached. If any notifications were missed since the last wait, waitCountedUntil() 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 (;;)
{
if (!_notification.waitCountedUntil(tracker, timeoutTime))
{
break;
}
doOneStep();
}
Parameters
trackerThe tracker to use to track notifications.
timeoutTimeThe timeout time.
Returns
Return true if a notification was received, or false on timeout.

◆ waitFor() [1/2]

template<std::invocable Predicate, typename Rep , typename Period >
auto xentara::utils::lockFree::ConditionVariable::waitFor ( Predicate &&  stopWaiting,
const std::chrono::duration< Rep, Period > &  timeout 
) const -> bool
noexcept

Waits for a certain condition to become true using a relative timeout.

This function checks the predicate stopWaiting, and returns once the predicate has become true, or until a specific time has elapsed. 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 essentially equivalent to the following:

Tracker tracker;
while (!stopWaiting())
{
wait(tracker);
}
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.
timeoutThe timeout.
Returns
Return true if the condition became true, or false on timeout.

◆ waitFor() [2/2]

template<typename Rep , typename Period >
auto xentara::utils::lockFree::ConditionVariable::waitFor ( Tracker &  tracker,
const std::chrono::duration< Rep, Period > &  timeout 
) const -> bool
noexcept

Waits for a notification using a relative timeout.

This function waits until the thread is woken up by notify_one() or notify_all(), or until a specific time has elapsed. 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 waitCountedFor().

The first time a wait function 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 (;;)
{
if (!_notification.waitFor(tracker, timeout))
{
break;
}
doWhateverNeedsToBeDone();
}
Parameters
trackerThe tracker to use to track notifications.
timeoutThe timeout.
Returns
Return true if a notification was received, or false on timeout. If this is the first wait function called for the given tracker, then this the function returns true, regardless of whether any notifications were ever issued.

◆ waitUntil() [1/2]

template<std::invocable Predicate, typename Clock , typename Duration >
auto xentara::utils::lockFree::ConditionVariable::waitUntil ( Predicate &&  stopWaiting,
const std::chrono::time_point< Clock, Duration > &  timeoutTime 
) const -> bool
noexcept

Waits for a certain condition to become true using an absolute timeout.

This function checks the predicate stopWaiting, and returns once the predicate has become true, or until a specific time point has been reached. 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 essentially equivalent to the following:

Tracker tracker;
while (!stopWaiting())
{
wait(tracker);
}
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.
timeoutTimeThe timeout time.
Returns
Return true if the condition became true, or false on timeout.

◆ waitUntil() [2/2]

template<typename Clock , typename Duration >
auto xentara::utils::lockFree::ConditionVariable::waitUntil ( Tracker &  tracker,
const std::chrono::time_point< Clock, Duration > &  timeoutTime 
) const -> bool
noexcept

Waits for a notification using an absolute timeout.

This function waits until the thread is woken up by notify_one() or notify_all(), or until a specific time point has been reached. 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 waitCountedFor().

The first time a wait function 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 (;;)
{
if (!_notification.waitUntil(tracker, timeoutTime))
{
break;
}
doWhateverNeedsToBeDone();
}
Parameters
trackerThe tracker to use to track notifications.
timeoutTimeThe timeout time.
Returns
Return true if a notification was received, or false on timeout. If this is the first wait function called for the given tracker, then this the function returns true, regardless of whether any notifications were ever issued.