Threading and Synchronization Primitives module
Cnx provides a set of cross-platform multithreading and synchronization facilities to make working with concurrent code as simple and straightforward as possible. The API is similar to C++'s and that added by the C11 standard, but is supported on platforms and compilers where implementations of C11's threading may not be available (like Windows, for example).
Example:
#include <Cnx/Thread.h> #include <Cnx/IO.h> #include <Cnx/Atomic.h> #include <Cnx/Assert.h> // A lambda that captures a `CnxBasicMutex*`, two `i32*`s and an `atomic_bool`* void LambdaFunction(example_print, void) { let bindings = LambdaBinding(CnxBasicMutex*, i32*, i32*, atomic_bool*); // run until the exit flag is set let exit_flag_ptr = bindings._4; while(!atomic_load(exit_flag_ptr)) { let_mut mutex_ptr = bindings._1; let locked = cnx_basic_mutex_lock(mutex_ptr); cnx_assert(cnx_result_is_ok(locked), "Failed to lock the mutex"); if(cnx_result_is_ok(locked)) { let num1 = *(bindings._2); let num2 = *(bindings._3); println("Values: [{}, {}]", num1, num2); } } } // A lambda that captures a `CnxBasicMutex*`, two `i32*`s and an `atomic_bool`* void LambdaFunction(example_add, void) { let bindings = LambdaBinding(CnxBasicMutex*, i32*, i32*, atomic_bool*); // run until the exit flag is set let exit_flag_ptr = bindings._4; while(!atomic_load(exit_flag_ptr)) { let_mut mutex_ptr = bindings._1; let locked = cnx_basic_mutex_lock(mutex_ptr); // cnx_assert(cnx_result_is_ok(locked), "Failed to lock the mutex"); if(cnx_result_is_ok(locked)) { let_mut num1_ptr = bindings._2; let_mut num2_ptr = bindings._3; (*(num1_ptr))++; (*(num2_ptr))++; } } } // Spawns one thread that continuosly prints two `i32`s for 60 seconds. // Spawns a second thread that continuously increments said `i32`s. // After 60 seconds, joins both threads. void example(void) { i32 val1 = 0; i32 val2 = 0; atomic_bool exit_flag = false; let_mut maybe_mutex = cnx_basic_mutex_new(); cnx_assert(cnx_result_is_ok(maybe_mutex), "Failed to create a new mutex"); let_mut mutex = cnx_result_unwrap(maybe_mutex); // creates a new thread whose startup routine is the `LambdaFunction` `example_print` // the lambda will be automatically freed when the thread completes execution let_mut maybe_print_thread = cnx_thread_new(lambda(example_print, &mutex, &val1, &val2, &exit_flag)); cnx_assert(cnx_result_is_ok(maybe_print_thread), "Failed to create print thread"); let_mut print_thread = cnx_result_unwrap(maybe_print_thread); // creates a new thread whose startup routine is the `LambdaFunction` `example_add` // the lambda will be automatically freed when the thread completes execution let_mut maybe_add_thread = cnx_thread_new(lambda(example_add, &mutex, &val1, &val2, &exit_flag)); cnx_assert(cnx_result_is_ok(maybe_add_thread), "Failed to create add thread"); let_mut add_thread = cnx_result_unwrap(maybe_add_thread); cnx_this_thread_sleep_for(cnx_seconds(60)); atomic_store(&exit_flag, true); let print_joined = cnx_thread_join(&print_thread); let add_joined = cnx_thread_join(&add_thread); cnx_assert(cnx_result_is_ok(print_joined), "Print thread failed to join"); cnx_assert(cnx_result_is_ok(add_joined), "Adding thread failed to join"); cnx_basic_mutex_free(&mutex); println("Finshed printing the numbers!"); }
Classes
- struct CnxJThread
- A
CnxJThread
is the handle type for OS-level threads which are automatically joined when their handle goes out of scope and use a dedicated stop token to signal to the thread when its execution should end.
Typedefs
- using CnxBasicMutex = __cnx_basic_mutex
CnxBasicMutex
is the basic mutual exclusion object type provided by Cnx's threading and synchronization API. Using aCnxBasicMutex
to control access to shared resources will ensure that all access is synchronized and mutually exclusive between threads.- using CnxRecursiveBasicMutex = __cnx_recursive_basic_mutex
CnxRecursiveBasicMutex
is the basic reentrant mutual exclusion object type provided by Cnx's threading and synchronization API. Using aCnxRecursiveBasicMutex
to control access to shared resources will ensure that all access is synchronized and mutually exclusive between threads, and allows for rentrant ownership of the lock on that access.- using CnxBasicCondvar = __cnx_condvar
CnxBasicCondvar
is the Condition Variable object type provided by Cnx's threading and synchronization API. Using aCnxBasicCondvar
allows to block one or more threads until an event is triggered, without wasting CPU resources.- using CnxThreadID = __cnx_thread_id
- A
CnxThreadID
uniquely identifies an indiviual thread. - using CnxThread = __cnx_thread
- A
CnxThread
is the handle type for basic OS-level threads provided by Cnx's threading and synchronization API.CnxThread
provides the facilities for creating multiple threads and ending their execution, enabling concurrent tasks and operations to be performed. - using CnxStopToken = atomic_bool
- A
CnxStopToken
is associated with aCnxJThread
and is used to signal to it when it should end its execution. - using CnxTLSKey = __cnx_tls_key
- A
CnxTLSKey
is the key type for creating, accessing, and modifying a thread-local storage object. - using CnxOnceFlag = __cnx_exec_once_flag
- A
CnxOnceFlag
is a synchronization flag type for use withcnx_execute_once
to ensure a given function is executed exactly once, regardless of how many threads attempt to call it, as long as all threads do so through the sameCnxOnceFlag
andcnx_execute_once
Functions
- CnxResult(CnxBasicMutex)
- Creates a new mutex.
- CnxResult cnx_basic_mutex_init(CnxBasicMutex*restrict mutex)
- Initializes the mutex pointed to by
mutex
- CnxResult cnx_basic_mutex_lock(CnxBasicMutex*restrict mutex)
- Unconditionally locks the mutex pointed to by
mutex
- bool cnx_basic_mutex_try_lock(CnxBasicMutex*restrict mutex)
- Attempts to lock the mutex pointed to by
mutex
- CnxResult cnx_basic_mutex_unlock(CnxBasicMutex*restrict mutex)
- Unlocks the mutex pointed to by
mutex
- CnxResult cnx_basic_mutex_free(CnxBasicMutex*restrict mutex)
- Destroys the mutex pointed to by
mutex
- CnxResult(CnxRecursiveBasicMutex)
- Creates a new recursive mutex.
- CnxResult cnx_recursive_basic_mutex_init(CnxRecursiveBasicMutex*restrict mutex)
- Initializes the recursive mutex pointed to by
mutex
- CnxResult cnx_recursive_basic_mutex_lock(CnxRecursiveBasicMutex*restrict mutex)
- Unconditionally locks the recursive mutex pointed to by
mutex
- bool cnx_recursive_basic_mutex_try_lock(CnxRecursiveBasicMutex*restrict mutex)
- Attempts to lock the recursive mutex pointed to by
mutex
- CnxResult cnx_recursive_basic_mutex_unlock(CnxRecursiveBasicMutex*restrict mutex)
- Unlocks the recursive mutex pointed to by
mutex
- CnxResult cnx_recursive_basic_mutex_free(CnxRecursiveBasicMutex*restrict mutex)
- Destroys the recursive mutex pointed to by
mutex
- CnxResult(CnxBasicCondvar)
- Creates a new condition variable, returning the result in a
CnxResult
- CnxResult cnx_basic_condvar_init(CnxBasicCondvar*restrict condvar)
- Initializes the condition variable pointed to by
condvar
- CnxResult cnx_basic_condvar_signal(CnxBasicCondvar*restrict condvar)
- Signals to the first thread waiting on the condition variable pointed to by
condvar
to wake and continue execution. - CnxResult cnx_basic_condvar_broadcast(CnxBasicCondvar*restrict condvar)
- Signals to every thread waiting on the condition variable pointed to by
condvar
to wake and continue execution. - CnxResult cnx_basic_condvar_wait(CnxBasicCondvar*restrict condvar, CnxBasicMutex*restrict mutex)
- Blocks on the condition variable pointed to by
condvar
until the thread is signalled by it. - CnxResult cnx_basic_condvar_wait_for(CnxBasicCondvar*restrict condvar, CnxBasicMutex*restrict mutex, CnxDuration to_wait) cnx_disable_if(!mutex
- Blocks on the condition variable pointed to by
condvar
until the thread is signalled by it, orto_wait
time has elapsed. - CnxResult cnx_basic_condvar_wait_until(CnxBasicCondvar*restrict condvar, CnxBasicMutex*restrict mutex, CnxTimePoint stop_point) cnx_disable_if(!mutex
- Blocks on the condition variable pointed to by
condvar
until the thread is signalled by it, or the point in time indicated bystop_point
time has been reached. - CnxResult cnx_basic_condvar_free(CnxBasicCondvar*restrict condvar)
- Destroys the condition variable pointed to by
condvar
- CnxResult cnx_execute_once(CnxOnceFlag*restrict flag, void(*)(void) function) cnx_disable_if(!flag
- Executes the given function exactly once.
- CnxCompare cnx_thread_id_compare(CnxThreadID lhs, CnxThreadID rhs)
- Compares the two
CnxThreadID
s. - bool cnx_thread_id_equal(CnxThreadID lhs, CnxThreadID rhs)
- Returns whether the two
CnxThreadID
s are equal. - bool cnx_thread_id_less_than(CnxThreadID lhs, CnxThreadID rhs)
- Returns whether the first
CnxThreadID
is less than the second. - bool cnx_thread_id_less_than_or_equal(CnxThreadID lhs, CnxThreadID rhs)
- Returns whether the first
CnxThreadID
is less than or equal to the second. - bool cnx_thread_id_greater_than(CnxThreadID lhs, CnxThreadID rhs)
- Returns whether the first
CnxThreadID
is greater than the second. - bool cnx_thread_id_greater_than_or_equal(CnxThreadID lhs, CnxThreadID rhs)
- Returns whether the first
CnxThreadID
is greater than or equal to the second. - typedef Lambda(void) CnxThreadLambda
- When spawning a new thread, a
Lambda(void)
is used as its startup routine. This typedef allows for receiving that startup routine as a function parameter. - CnxResult(CnxThread)
- Spawns a new thread, with the given
CnxThreadLambda
as its startup routine. - CnxResult cnx_thread_init(CnxThread*restrict thread, CnxThreadLambda lambda)
- Spawns a new thread, with the given
CnxThreadLambda
as its startup routine. - bool cnx_thread_is_null(const CnxThread*restrict thread)
- Checks if the given thread handle is null (if it has been initialized)
- CnxThreadID cnx_thread_get_id(const CnxThread*restrict thread)
- Gets the ID of the current thread.
- CnxResult cnx_thread_join(CnxThread*restrict thread)
- Joins the given thread, blocking until its execution has completed.
- CnxResult cnx_thread_detach(CnxThread*restrict thread)
- Separates execution of the thread associated with the given thread handle from the handle.
- void cnx_thread_free(void* thread)
- Frees the given thread, blocking until it's joined or joining fails.
- void cnx_this_thread_yield(void)
- Yields execution of the current thread, allowing the operating system to execute other threads until it decides to return execution to this one.
- void cnx_this_thread_sleep_for(CnxDuration duration)
- Yields execution of the current thread until at least the given
duration
of time has passed. - CnxThreadID cnx_this_thread_get_id(void)
- Returns the ID of the current thread.
- void cnx_stop_token_request_stop(CnxStopToken*restrict token)
- Requests the thread associated with the given stop token to end execution.
- bool cnx_stop_token_stop_requested(const CnxStopToken*restrict token)
- Returns whether the thread associated with the given stop token has been requested to end execution.
- typedef Lambda(void, const CnxStopToken*) CnxJThreadLambda
- When spawning a new
CnxJThread
, aLambda(void, const CnxStopToken*)
is used as its startup routine. This typedef allows for receiving that startup routine as a function parameter. - CnxResult(CnxJThread)
- Spawns a new
CnxJThread
, with the givenCnxJThreadLambda
as its startup routine. - CnxResult cnx_jthread_init(CnxJThread*restrict thread, CnxJThreadLambda lambda)
- Spawns a new
CnxJThread
, with the givenCnxJThreadLambda
as its startup routine. - CnxResult cnx_jthread_join(CnxJThread*restrict thread)
- Joins the given
CnxJThread
, blocking until its execution has completed. - void cnx_jthread_free(void* thread)
- Frees the given
CnxJThread
, blocking until it's joined or joining fails. - CnxResult(CnxTLSKey) cnx_tls_new(void *data
- Creates a new thread-local storage.
- CnxResult cnx_tls_init(CnxTLSKey*restrict key, void* data, void(__CNX_TLS_DESTRUCTOR_TAG*destructor)(void*))
- Initializes a thread-local storage and associates it with the key pointed to by
key
- void* cnx_tls_get(CnxTLSKey key)
- Retrieves the current value of the thread-local storage associated with
key
- CnxResult cnx_tls_set(CnxTLSKey key, void* data)
- Sets the value of the thread-local storage associated with
key
todata
Defines
- #define thread_local
- A variable declared as
thread_local
is local to the current thread and guaranteed to not be accessible by other threads. - #define cnx_jthread_is_null(thread)
- Checks if the given thread handle is null (if it has been initialized)
- #define cnx_jthread_get_id(thread)
- Gets the ID of the current thread.
- #define cnx_jthread_detach(thread)
- Separates execution of the thread associated with the
CnxJThread
thread handle from the handle.
Typedef documentation
typedef __cnx_basic_mutex CnxBasicMutex
#include <include/Cnx/Thread.h>
CnxBasicMutex
is the basic mutual exclusion object type provided by Cnx's threading and synchronization API. Using a CnxBasicMutex
to control access to shared resources will ensure that all access is synchronized and mutually exclusive between threads.
typedef __cnx_recursive_basic_mutex CnxRecursiveBasicMutex
#include <include/Cnx/Thread.h>
CnxRecursiveBasicMutex
is the basic reentrant mutual exclusion object type provided by Cnx's threading and synchronization API. Using a CnxRecursiveBasicMutex
to control access to shared resources will ensure that all access is synchronized and mutually exclusive between threads, and allows for rentrant ownership of the lock on that access.
typedef __cnx_condvar CnxBasicCondvar
#include <include/Cnx/Thread.h>
CnxBasicCondvar
is the Condition Variable object type provided by Cnx's threading and synchronization API. Using a CnxBasicCondvar
allows to block one or more threads until an event is triggered, without wasting CPU resources.
typedef __cnx_thread_id CnxThreadID
#include <include/Cnx/Thread.h>
A CnxThreadID
uniquely identifies an indiviual thread.
typedef __cnx_thread CnxThread
#include <include/Cnx/Thread.h>
A CnxThread
is the handle type for basic OS-level threads provided by Cnx's threading and synchronization API. CnxThread
provides the facilities for creating multiple threads and ending their execution, enabling concurrent tasks and operations to be performed.
typedef atomic_bool CnxStopToken
#include <include/Cnx/Thread.h>
A CnxStopToken
is associated with a CnxJThread
and is used to signal to it when it should end its execution.
typedef __cnx_tls_key CnxTLSKey
#include <include/Cnx/Thread.h>
A CnxTLSKey
is the key type for creating, accessing, and modifying a thread-local storage object.
typedef __cnx_exec_once_flag CnxOnceFlag
#include <include/Cnx/Thread.h>
A CnxOnceFlag
is a synchronization flag type for use with cnx_execute_once
to ensure a given function is executed exactly once, regardless of how many threads attempt to call it, as long as all threads do so through the same CnxOnceFlag
and cnx_execute_once
Function documentation
CnxResult(CnxBasicMutex)
#include <include/Cnx/Thread.h>
Creates a new mutex.
Returns | A CnxBasicMutex if successful |
---|
Creating a mutex can fail, depending on memory and operating system level constraints. If creating the mutex is successful, returns a CnxBasicMutex
, otherwise returns an error.
CnxResult cnx_basic_mutex_init(CnxBasicMutex*restrict mutex)
#include <include/Cnx/Thread.h>
Initializes the mutex pointed to by mutex
Parameters | |
---|---|
mutex | - The mutex to initalize |
Returns | Ok if successful |
Initializing a mutex can fail, depending on memory and operating system level constraints. If initializing the mutex is successful, returns Ok
, otherwise returns an error.
CnxResult cnx_basic_mutex_lock(CnxBasicMutex*restrict mutex)
#include <include/Cnx/Thread.h>
Unconditionally locks the mutex pointed to by mutex
Parameters | |
---|---|
mutex | - The mutex to lock |
Returns | Ok if successful |
Locking a mutex can fail (for example, if it's already locked on the calling thread). If locking the mutex is successful, returns Ok
, otherwise returns an error.
bool cnx_basic_mutex_try_lock(CnxBasicMutex*restrict mutex)
#include <include/Cnx/Thread.h>
Attempts to lock the mutex pointed to by mutex
Parameters | |
---|---|
mutex | - The mutex to lock |
Returns | true if successful |
If locking the mutex is successful, return true
.
CnxResult cnx_basic_mutex_unlock(CnxBasicMutex*restrict mutex)
#include <include/Cnx/Thread.h>
Unlocks the mutex pointed to by mutex
Parameters | |
---|---|
mutex | - The mutex to unlock |
Returns | Ok if successful |
Unlocking a mutex can fail (for example, if it's already unlocked). If unlocking the mutex is successful, returns Ok
, otherwise returns an error.
CnxResult cnx_basic_mutex_free(CnxBasicMutex*restrict mutex)
#include <include/Cnx/Thread.h>
Destroys the mutex pointed to by mutex
Parameters | |
---|---|
mutex | - The mutex to free |
Returns | Ok if successful |
Destroying a mutex can fail (for example, it it's still in use by other threads). If destroying the mutex is successful, returns Ok
, otherwise returns an error.
CnxResult(CnxRecursiveBasicMutex)
#include <include/Cnx/Thread.h>
Creates a new recursive mutex.
Returns | A CnxRecursiveBasicMutex if successful |
---|
Creating a mutex can fail, depending on memory and operating system level constraints. If creating the recursive mutex is successful, returns a CnxRecursiveBasicMutex
, otherwise returns an error.
CnxResult cnx_recursive_basic_mutex_init(CnxRecursiveBasicMutex*restrict mutex)
#include <include/Cnx/Thread.h>
Initializes the recursive mutex pointed to by mutex
Parameters | |
---|---|
mutex | - The mutex to initialize |
Returns | Ok if successful |
Initializing a mutex can fail, depending on memory and operating system level constraints. If initializing the mutex is successful, returns Ok
, otherwise returns an error.
CnxResult cnx_recursive_basic_mutex_lock(CnxRecursiveBasicMutex*restrict mutex)
#include <include/Cnx/Thread.h>
Unconditionally locks the recursive mutex pointed to by mutex
Parameters | |
---|---|
mutex | - The mutex to lock |
Returns | Ok if successful |
Locking a mutex can fail. If locking the recursive mutex is successful, returns Ok
, otherwise returns an error.
bool cnx_recursive_basic_mutex_try_lock(CnxRecursiveBasicMutex*restrict mutex)
#include <include/Cnx/Thread.h>
Attempts to lock the recursive mutex pointed to by mutex
Parameters | |
---|---|
mutex | - The mutex to lock |
Returns | true if successful |
If locking the recursive mutex is successful, return true
.
CnxResult cnx_recursive_basic_mutex_unlock(CnxRecursiveBasicMutex*restrict mutex)
#include <include/Cnx/Thread.h>
Unlocks the recursive mutex pointed to by mutex
Parameters | |
---|---|
mutex | - The mutex to unlock |
Returns | Ok if successful |
Unlocking a mutex can fail (for example, if it's already unlocked). If unlocking the recursive mutex is successful, returns Ok
, otherwise returns an error.
CnxResult cnx_recursive_basic_mutex_free(CnxRecursiveBasicMutex*restrict mutex)
#include <include/Cnx/Thread.h>
Destroys the recursive mutex pointed to by mutex
Parameters | |
---|---|
mutex | - The mutex to free |
Returns | Ok if successful |
Destroying a mutex can fail (for example, it it's still in use by other threads). If destroying the recursive mutex is successful, returns Ok
, otherwise returns an error.
CnxResult(CnxBasicCondvar)
#include <include/Cnx/Thread.h>
Creates a new condition variable, returning the result in a CnxResult
Returns | A CnxRecursiveBasicMutex if successful |
---|
Creating a condition variable can fail, depending on memory and operating system level constraints. If creating the condition variable is successful, returns a CnxBasicCondvar
, otherwise returns an error
CnxResult cnx_basic_condvar_init(CnxBasicCondvar*restrict condvar)
#include <include/Cnx/Thread.h>
Initializes the condition variable pointed to by condvar
Parameters | |
---|---|
condvar | - The condvar to initialize |
Returns | Ok if successful |
Initializing a condition variable can fail, depending on memory and operating system level constraints. If initializing the condition variable is successful, returns Ok
, otherwise returns an error
CnxResult cnx_basic_condvar_signal(CnxBasicCondvar*restrict condvar)
#include <include/Cnx/Thread.h>
Signals to the first thread waiting on the condition variable pointed to by condvar
to wake and continue execution.
Parameters | |
---|---|
condvar | - The condvar to signal on |
Returns | Ok if successful |
Signalling with a condition variable can fail. If signalling with the condition variable is successful, returns Ok
, otherwise returns an error.
CnxResult cnx_basic_condvar_broadcast(CnxBasicCondvar*restrict condvar)
#include <include/Cnx/Thread.h>
Signals to every thread waiting on the condition variable pointed to by condvar
to wake and continue execution.
Parameters | |
---|---|
condvar | - The condvar to broadcast on |
Returns | Ok if successful |
Signalling with a condition variable can fail. If signalling with the condition variable is successful, returns Ok
, otherwise returns an error.
CnxResult cnx_basic_condvar_wait(CnxBasicCondvar*restrict condvar,
CnxBasicMutex*restrict mutex)
#include <include/Cnx/Thread.h>
Blocks on the condition variable pointed to by condvar
until the thread is signalled by it.
Parameters | |
---|---|
condvar | - The condvar to wait on |
mutex | - The mutex associated with the condvar |
Returns | Ok if successful |
Unlocks the mutex pointed to by mutex
and blocks on the condition variable pointed to by condvar
until the thread is signalled by it. The mutex is re-locked again before the function returns. The mutex must be locked by the calling thread prior to calling this.
Waiting on a condition variable can fail. If waiting on the condition variable is successful, returns Ok
, otherwise returns an error.
CnxResult cnx_basic_condvar_wait_for(CnxBasicCondvar*restrict condvar,
CnxBasicMutex*restrict mutex,
CnxDuration to_wait) cnx_disable_if(!mutex
#include <include/Cnx/Thread.h>
Blocks on the condition variable pointed to by condvar
until the thread is signalled by it, or to_wait
time has elapsed.
Parameters | |
---|---|
condvar | - The condvar to wait on |
mutex | - The mutex associated with the condvar |
to_wait | - The amount of time to wait on the condvar |
Returns | Ok if successful |
Unlocks the mutex pointed to by mutex
and blocks on the condition variable pointed to by condvar
until the thread is signalled by it, or to_wait
time has elapsed. The mutex is re-locked again before the function returns. The mutex must be locked by the calling thread prior to calling this.
Waiting on a condition variable can fail. Returns Ok
if a signal is received from the condition variable before to_wait
has elapsed, otherwise returns an error.
CnxResult cnx_basic_condvar_wait_until(CnxBasicCondvar*restrict condvar,
CnxBasicMutex*restrict mutex,
CnxTimePoint stop_point) cnx_disable_if(!mutex
#include <include/Cnx/Thread.h>
Blocks on the condition variable pointed to by condvar
until the thread is signalled by it, or the point in time indicated by stop_point
time has been reached.
Parameters | |
---|---|
condvar | - The condvar to wait on |
mutex | - The mutex associated with the condvar |
stop_point | - The point in time to stop waiting on the condvar |
Returns | Ok if successful |
Unlocks the mutex pointed to by mutex
and blocks on the condition variable pointed to by condvar
until the thread is signalled by it, or the time indicated by stop_point
has been reached. The mutex is re-locked again before the function returns. The mutex must be locked by the calling thread prior to calling this.
Waiting on a condition variable can fail. Returns Ok
if a signal is received from the condition variable before to_wait
has elapsed, otherwise returns an error.
CnxResult cnx_basic_condvar_free(CnxBasicCondvar*restrict condvar)
#include <include/Cnx/Thread.h>
Destroys the condition variable pointed to by condvar
Parameters | |
---|---|
condvar | - The condvar to free |
Returns | Ok if successful |
Destroying a condition variable can fail (for example, if its still in use by another thread). If destroying the condition variable is successful, returns Ok
, otherwise, returns an error.
CnxResult cnx_execute_once(CnxOnceFlag*restrict flag,
void(*)(void) function) cnx_disable_if(!flag
#include <include/Cnx/Thread.h>
Executes the given function exactly once.
Parameters | |
---|---|
flag | - The execute once flag associated with function 's execution |
function | - The function to execute exactly once |
Returns | Ok if successful |
Executes the given function exactly once, regardless how many threads attempt to execute it, or if they attempt to execute it multiple times, as long as all attempts to call it go through cnx_execute_once
using the same CnxOnceFlag
Executing the function can fail (for example, on Windows). If execution is successful, return Ok
, otherwise returns an error.
CnxCompare cnx_thread_id_compare(CnxThreadID lhs,
CnxThreadID rhs)
#include <include/Cnx/Thread.h>
Compares the two CnxThreadID
s.
Parameters | |
---|---|
lhs | - The id to compare |
rhs | - The id to compare lhs to |
Returns | A CnxCompare indicating how lhs compares to rhs |
bool cnx_thread_id_equal(CnxThreadID lhs,
CnxThreadID rhs)
#include <include/Cnx/Thread.h>
Returns whether the two CnxThreadID
s are equal.
Parameters | |
---|---|
lhs | - The id to compare |
rhs | - The id to compare lhs to |
Returns | whether the two IDs are equal |
bool cnx_thread_id_less_than(CnxThreadID lhs,
CnxThreadID rhs)
#include <include/Cnx/Thread.h>
Returns whether the first CnxThreadID
is less than the second.
Parameters | |
---|---|
lhs | - The id to compare |
rhs | - The id to compare lhs to |
Returns | whether lhs is less than rhs |
bool cnx_thread_id_less_than_or_equal(CnxThreadID lhs,
CnxThreadID rhs)
#include <include/Cnx/Thread.h>
Returns whether the first CnxThreadID
is less than or equal to the second.
Parameters | |
---|---|
lhs | - The id to compare |
rhs | - The id to compare lhs to |
Returns | whether lhs is less than or equal to rhs |
bool cnx_thread_id_greater_than(CnxThreadID lhs,
CnxThreadID rhs)
#include <include/Cnx/Thread.h>
Returns whether the first CnxThreadID
is greater than the second.
Parameters | |
---|---|
lhs | - The id to compare |
rhs | - The id to compare lhs to |
Returns | whether lhs is greater than rhs |
bool cnx_thread_id_greater_than_or_equal(CnxThreadID lhs,
CnxThreadID rhs)
#include <include/Cnx/Thread.h>
Returns whether the first CnxThreadID
is greater than or equal to the second.
Parameters | |
---|---|
lhs | - The id to compare |
rhs | - The id to compare lhs to |
Returns | whether lhs is greater than or equal to rhs |
typedef Lambda(void) CnxThreadLambda
#include <include/Cnx/Thread.h>
When spawning a new thread, a Lambda(void)
is used as its startup routine. This typedef allows for receiving that startup routine as a function parameter.
CnxResult(CnxThread)
#include <include/Cnx/Thread.h>
Spawns a new thread, with the given CnxThreadLambda
as its startup routine.
Returns | A CnxThread on success |
---|
Spawns a new thread, with the given CnxThreadLambda
as its startup routine. The given lambda will be automatically freed after the thread's execution completes.
Spawning a thread can fail due to memory or operating system level constraints. If spawning the thread is successful, returns a handle to the spawned thread. Otherwise, returns an error.
CnxResult cnx_thread_init(CnxThread*restrict thread,
CnxThreadLambda lambda)
#include <include/Cnx/Thread.h>
Spawns a new thread, with the given CnxThreadLambda
as its startup routine.
Parameters | |
---|---|
thread | - The pointer to thread handle to set as the handle to the spawned thread |
lambda | - The lambda to invoke as the spawned thread's startup routine |
Returns | Ok on success |
Spawns a new thread, with the given CnxThreadLambda
as its startup routine. The given lambda will be automatically freed after the thread's execution completes.
Spawning a thread can fail due to memory or operating system level constraints. If spawning the thread is successful, the CnxThread
pointed to by thread
will be initialized with the handle to the spawned thread, and Ok
will be returned. Otherwise, returns an error.
bool cnx_thread_is_null(const CnxThread*restrict thread)
#include <include/Cnx/Thread.h>
Checks if the given thread handle is null (if it has been initialized)
Parameters | |
---|---|
thread | - The thread to check if is null |
Returns | whether the thread is null |
CnxThreadID cnx_thread_get_id(const CnxThread*restrict thread)
#include <include/Cnx/Thread.h>
Gets the ID of the current thread.
Parameters | |
---|---|
thread | - The thread to get the ID of |
Returns | The ID of the given thread |
CnxResult cnx_thread_join(CnxThread*restrict thread)
#include <include/Cnx/Thread.h>
Joins the given thread, blocking until its execution has completed.
Parameters | |
---|---|
thread | - The thread to join |
Returns | Ok if successful |
Joining a thread can fail. Returns Ok
if joining the thread is successful. Otherwise, returns an error.
CnxResult cnx_thread_detach(CnxThread*restrict thread)
#include <include/Cnx/Thread.h>
Separates execution of the thread associated with the given thread handle from the handle.
Parameters | |
---|---|
thread | - The thread to detach |
Returns | Ok if successful |
Separates execution of the thread associated with the given handle from that handle. When successfully detached, the associated thread will continue execution independently and will no longer be associated with any handle.
Detaching a thread can fail. Returns Ok
if detaching the thread is successful. Otherwise, returns an error.
void cnx_thread_free(void* thread)
#include <include/Cnx/Thread.h>
Frees the given thread, blocking until it's joined or joining fails.
Parameters | |
---|---|
thread | - The thread to free |
void cnx_this_thread_yield(void)
#include <include/Cnx/Thread.h>
Yields execution of the current thread, allowing the operating system to execute other threads until it decides to return execution to this one.
void cnx_this_thread_sleep_for(CnxDuration duration)
#include <include/Cnx/Thread.h>
Yields execution of the current thread until at least the given duration
of time has passed.
Parameters | |
---|---|
duration | - The minimum amount of time to yield execution for |
CnxThreadID cnx_this_thread_get_id(void)
#include <include/Cnx/Thread.h>
Returns the ID of the current thread.
Returns | The ID of the current thread |
---|
void cnx_stop_token_request_stop(CnxStopToken*restrict token)
#include <include/Cnx/Thread.h>
Requests the thread associated with the given stop token to end execution.
Parameters | |
---|---|
token | - The token associated with the thread to end |
bool cnx_stop_token_stop_requested(const CnxStopToken*restrict token)
#include <include/Cnx/Thread.h>
Returns whether the thread associated with the given stop token has been requested to end execution.
Parameters | |
---|---|
token | - The token associated with the thread to end |
Returns | whether the thread has been requested to end |
typedef Lambda(void,
const CnxStopToken*) CnxJThreadLambda
#include <include/Cnx/Thread.h>
When spawning a new CnxJThread
, a Lambda(void, const CnxStopToken*)
is used as its startup routine. This typedef allows for receiving that startup routine as a function parameter.
CnxResult(CnxJThread)
#include <include/Cnx/Thread.h>
Spawns a new CnxJThread
, with the given CnxJThreadLambda
as its startup routine.
Returns | A CnxJThread on success |
---|
Spawns a new thread, with the given CnxJThreadLambda
as its startup routine. The given lambda will be automatically freed after the thread's execution completes.
Spawning a thread can fail due to memory or operating system level constraints. If spawning the thread is successful, returns a handle to the spawned thread. Otherwise, returns an error.
CnxResult cnx_jthread_init(CnxJThread*restrict thread,
CnxJThreadLambda lambda)
#include <include/Cnx/Thread.h>
Spawns a new CnxJThread
, with the given CnxJThreadLambda
as its startup routine.
Parameters | |
---|---|
thread | - The pointer to thread handle to set as the handle to the spawned thread |
lambda | - The lambda to invoke as the spawned thread's startup routine |
Returns | Ok on success |
Spawns a new thread, with the given CnxJThreadLambda
as its startup routine. The given lambda will be automatically freed after the thread's execution completes.
Spawning a thread can fail due to memory or operating system level constraints. If spawning the thread is successful, the CnxThread
pointed to by thread
will be initialized with the handle to the spawned thread, and Ok
will be returned. Otherwise, returns an error.
CnxResult cnx_jthread_join(CnxJThread*restrict thread)
#include <include/Cnx/Thread.h>
Joins the given CnxJThread
, blocking until its execution has completed.
Parameters | |
---|---|
thread | - The thread to join |
Returns | Ok if successful |
Joining a thread can fail. Returns Ok
if joining the thread is successful. Otherwise, returns an error.
void cnx_jthread_free(void* thread)
#include <include/Cnx/Thread.h>
Frees the given CnxJThread
, blocking until it's joined or joining fails.
Parameters | |
---|---|
thread | - The thread to free |
CnxResult(CnxTLSKey) cnx_tls_new(void *data
#include <include/Cnx/Thread.h>
Creates a new thread-local storage.
Returns | A CnxTLSKey on success |
---|
Creates a new thread-local storage that will be destroyed by the given destructor
function at thread exit.
Creating a thread-local storage can fail. If creation is successful, the storage will be set to data
and the CnxTLSKey
associated with the storage will be returned. Otherwise, an error will be returned.
CnxResult cnx_tls_init(CnxTLSKey*restrict key,
void* data,
void(__CNX_TLS_DESTRUCTOR_TAG*destructor)(void*))
#include <include/Cnx/Thread.h>
Initializes a thread-local storage and associates it with the key pointed to by key
Parameters | |
---|---|
key | |
data | - The value to initialize the TLS to |
Returns | A CnxTLSKey on success |
Initializes a new thread-local storage that will be destroyed by the given destructor
function at thread exit, and associates the thread-local storage with the key pointed to by key
.
Creating a thread-local storage can fail. If creation is successful, the storage will be set to data
and the CnxTLSKey
associated with the storage will be returned. Otherwise, an error will be returned.
void* cnx_tls_get(CnxTLSKey key)
#include <include/Cnx/Thread.h>
Retrieves the current value of the thread-local storage associated with key
Parameters | |
---|---|
key | - The thread-local storage key to get the currently associated value of |
Returns | The current value of the TLS, or nullptr |
If key is a key to a valid TLS, returns the current value of the TLS, otherwise returns a nullptr
CnxResult cnx_tls_set(CnxTLSKey key,
void* data)
#include <include/Cnx/Thread.h>
Sets the value of the thread-local storage associated with key
to data
Parameters | |
---|---|
key | - The thread-local storage key to set the associated value of |
data | - The value to set the TLS to |
Returns | Ok on successful |
Setting the value of a thread-local storage can fail. If setting the thread-local storage is successful, returns Ok
. Otherwise, an error is returned
Define documentation
#define thread_local
#include <include/Cnx/Thread.h>
A variable declared as thread_local
is local to the current thread and guaranteed to not be accessible by other threads.
#define cnx_jthread_is_null(thread)
#include <include/Cnx/Thread.h>
Checks if the given thread handle is null (if it has been initialized)
Parameters | |
---|---|
thread | - The thread to check if is null |
Returns | whether the thread is null |
#define cnx_jthread_get_id(thread)
#include <include/Cnx/Thread.h>
Gets the ID of the current thread.
Parameters | |
---|---|
thread | - The thread to get the ID of |
Returns | The ID of the given thread |
#define cnx_jthread_detach(thread)
#include <include/Cnx/Thread.h>
Separates execution of the thread associated with the CnxJThread
thread handle from the handle.
Parameters | |
---|---|
thread | - The thread to detach |
Returns | Ok if successful |
Separates execution of the thread associated with the given handle from that handle. When successfully detached, the associated thread will continue execution independently and will no longer be associated with any handle.
Detaching a thread can fail. Returns Ok
if detaching the thread is successful. Otherwise, returns an error.