module
CnxSharedMutexCnxSharedMutex
provides several higher-level reader-writer mutex types comparable to those provided in C++'s <shared_mutex>
, to make working with multi-threaded code simpler and easier.
A shared mutex is a reader-writer mutex that allows for different categories of locking, either exclusively, for writing/mutation, or non-exclusively/shared for reading. This can allow for significant throughput improvements in applications where many threads need to read the same data often, but only a comparatively small number of threads will ever try to mutate the data, by allowing the reading threads to share a lock on the mutex, while forcing a writing thread to gain an exclusive lock on the mutex to perform its mutation.
Example:
// MyThing.h #include <Cnx/sync/SharedMutex.h> static MyType my_very_important_thing; static CnxSharedMutex* my_thing_mutex; void init_my_thing(void); void update_my_thing(u64 value); u64 get_value_from_my_thing(void); // MyThing.c #include <Cnx/Allocators.h> #include "MyThing.h" void init_my_thing(void) { if(my_thing_mutex == nullptr) { my_thing_mutex = cnx_allocator_allocate_t(CnxSharedMutex, DEFAULT_ALLOCATOR); *my_thing_mutex = cnx_shared_mutex_new(); cnx_shared_mutex_lock(my_thing_mutex); my_very_important_thing = { // important intialization }; cnx_shared_mutex_unlock(my_thing_mutex); } } // only one thread at a time can `update_my_thing`, because it uses exclusive locking void update_my_thing(u64 value) { cnx_shared_mutex_lock(my_thing_mutex); my_very_important_thing.value = value; cnx_shared_mutex_unlock(my_thing_mutex); } // any number of threads can `get_value_from_my_thing` without blocking eachother, // because it uses shared locking. u64 get_value_from_my_thing(void) { cnx_shared_mutex_lock_shared(my_thing_mutex); let val = my_very_important_thing.value; cnx_shared_mutex_unlock_shared(my_thing_mutex); return val; } // do some compute intensive task... // update the value update_my_thing(new_value); my_val = get_value_from_my_thing(); // do something with my_val let_mut newval = get_value_from_my_thing(); while(newval == my_val) { cnx_this_thread_sleep_for(cnx_milliseconds(100)); newval = get_value_from_my_thing(); } my_val = newval; // do something with new value
Classes
- struct CnxSharedMutex
CnxSharedMutex
is the generic (it's not timed or recursive) reader-writer mutex provided by Cnx. It's directly comparable to C++'sstd::shared_mutex
and is suitable for any situation where a reader-writer mutex is necessary.- struct CnxSharedTimedMutex
CnxSharedTimedMutex
is a higher-level reader-writer mutex type for use when timed backoff of mutex locking is required, and is directly comparable to C++'sstd::shared_timed_mutex
. It allows for specifying a timeout, which if reached will cause execution to stop attempting to acquire the lock and signal failure to the caller, instead of blocking indefinitely until the lock was successfully acquired like a tradition mutex. For example, if an algorithm needs reader-writer synchronization, but blocking for longer than X milliseconds when trying to acquire the lock would be problematic, aCnxSharedTimedMutex
would be the appropriate mutex type to use.- struct CnxSharedMutexInterface
Functions
- CnxSharedMutex cnx_shared_mutex_new(void)
- Creates a new shared mutex.
- void cnx_shared_mutex_lock(CnxSharedMutex*restrict mutex)
- Unconditionally locks the mutex pointed to by
mutex
exclusively (aka for writing) - bool cnx_shared_mutex_try_lock(CnxSharedMutex*restrict mutex)
- Attempts to lock the mutex pointed to by
mutex
exclusively (aka for writing) - void cnx_shared_mutex_lock_shared(CnxSharedMutex*restrict mutex)
- Unconditionally locks the mutex pointed to by
mutex
non-exclusively (shared, aka for reading) - bool cnx_shared_mutex_try_lock_shared(CnxSharedMutex*restrict mutex)
- Attempts to lock the mutex pointed to by
mutex
non-exclusively (shared, aka for reading) - void cnx_shared_mutex_unlock(CnxSharedMutex*restrict mutex)
- Unlocks the exclusively locked mutex pointed to by
mutex
- void cnx_shared_mutex_unlock_shared(CnxSharedMutex*restrict mutex)
- Unlocks the non-exclusively (aka shared) locked mutex pointed to by
mutex
- void cnx_shared_mutex_free(CnxSharedMutex*restrict mutex)
- Destroys the mutex pointed to by
mutex
- CnxSharedTimedMutex cnx_shared_timed_mutex_new(void)
- Creates a new shared timed mutex.
- void cnx_shared_timed_mutex_lock(CnxSharedTimedMutex*restrict mutex)
- Unconditionally locks the mutex pointed to by
mutex
exclusively (aka for writing) - bool cnx_shared_timed_mutex_try_lock(CnxSharedTimedMutex*restrict mutex)
- Attempts to lock the mutex pointed to by
mutex
exclusively (aka for writing) - bool cnx_shared_timed_mutex_try_lock_for(CnxSharedTimedMutex*restrict mutex, CnxDuration duration)
- Attempts to lock the mutex pointed to by
mutex
exclusively (aka for writing) - bool cnx_shared_timed_mutex_try_lock_until(CnxSharedTimedMutex*restrict mutex, CnxTimePoint stop_point)
- Attempts to lock the mutex pointed to by
mutex
exclusively (aka for writing) - void cnx_shared_timed_mutex_lock_shared(CnxSharedTimedMutex*restrict mutex)
- Unconditionally locks the mutex pointed to by
mutex
non-exclusively (shared, aka for reading) - bool cnx_shared_timed_mutex_try_lock_shared(CnxSharedTimedMutex*restrict mutex)
- Attempts to lock the mutex pointed to by
mutex
non-exclusively (shared, aka for reading) - bool cnx_shared_timed_mutex_try_lock_shared_for(CnxSharedTimedMutex*restrict mutex, CnxDuration duration)
- Attempts to lock the mutex pointed to by
mutex
non-exclusively (aka shared, for reading) - bool cnx_shared_timed_mutex_try_lock_shared_until(CnxSharedTimedMutex*restrict mutex, CnxTimePoint stop_point)
- Attempts to lock the mutex pointed to by
mutex
non-exclusively (aka shared, for reading) - void cnx_shared_timed_mutex_unlock(CnxSharedTimedMutex*restrict mutex)
- Unlocks the exclusively locked mutex pointed to by
mutex
- void cnx_shared_timed_mutex_unlock_shared(CnxSharedTimedMutex*restrict mutex)
- Unlocks the non-exclusively (aka shared) locked mutex pointed to by
mutex
- void cnx_shared_timed_mutex_free(CnxSharedTimedMutex*restrict mutex)
- Destroys the mutex pointed to by
mutex
Function documentation
CnxSharedMutex cnx_shared_mutex_new(void)
#include <include/Cnx/sync/SharedMutex.h>
Creates a new shared mutex.
Returns | A CnxSharedMutex |
---|
void cnx_shared_mutex_lock(CnxSharedMutex*restrict mutex)
#include <include/Cnx/sync/SharedMutex.h>
Unconditionally locks the mutex pointed to by mutex
exclusively (aka for writing)
Parameters | |
---|---|
mutex | - The mutex to lock exclusively (aka for writing) |
bool cnx_shared_mutex_try_lock(CnxSharedMutex*restrict mutex)
#include <include/Cnx/sync/SharedMutex.h>
Attempts to lock the mutex pointed to by mutex
exclusively (aka for writing)
Parameters | |
---|---|
mutex | - The mutex to lock exclusively (aka for writing) |
Returns | true if successful |
If locking the mutex is successful, return true
.
void cnx_shared_mutex_lock_shared(CnxSharedMutex*restrict mutex)
#include <include/Cnx/sync/SharedMutex.h>
Unconditionally locks the mutex pointed to by mutex
non-exclusively (shared, aka for reading)
Parameters | |
---|---|
mutex | - The mutex to lock non-exclusively (aka shared, for reading) |
bool cnx_shared_mutex_try_lock_shared(CnxSharedMutex*restrict mutex)
#include <include/Cnx/sync/SharedMutex.h>
Attempts to lock the mutex pointed to by mutex
non-exclusively (shared, aka for reading)
Parameters | |
---|---|
mutex | - The mutex to lock non-exclusively (aka shared, for reading) |
Returns | true if successful |
If locking the mutex is successful, return true
.
void cnx_shared_mutex_unlock(CnxSharedMutex*restrict mutex)
#include <include/Cnx/sync/SharedMutex.h>
Unlocks the exclusively locked mutex pointed to by mutex
Parameters | |
---|---|
mutex | - The mutex to unlock exclusively |
void cnx_shared_mutex_unlock_shared(CnxSharedMutex*restrict mutex)
#include <include/Cnx/sync/SharedMutex.h>
Unlocks the non-exclusively (aka shared) locked mutex pointed to by mutex
Parameters | |
---|---|
mutex | - The mutex to unlock non-exclusively |
void cnx_shared_mutex_free(CnxSharedMutex*restrict mutex)
#include <include/Cnx/sync/SharedMutex.h>
Destroys the mutex pointed to by mutex
Parameters | |
---|---|
mutex | - The mutex to free |
CnxSharedTimedMutex cnx_shared_timed_mutex_new(void)
#include <include/Cnx/sync/SharedMutex.h>
Creates a new shared timed mutex.
Returns | A CnxSharedTimedMutex |
---|
void cnx_shared_timed_mutex_lock(CnxSharedTimedMutex*restrict mutex)
#include <include/Cnx/sync/SharedMutex.h>
Unconditionally locks the mutex pointed to by mutex
exclusively (aka for writing)
Parameters | |
---|---|
mutex | - The mutex to lock exclusively (aka for writing) |
bool cnx_shared_timed_mutex_try_lock(CnxSharedTimedMutex*restrict mutex)
#include <include/Cnx/sync/SharedMutex.h>
Attempts to lock the mutex pointed to by mutex
exclusively (aka for writing)
Parameters | |
---|---|
mutex | - The mutex to lock exclusively (aka for writing) |
Returns | true if successful |
If locking the mutex is successful, return true
.
bool cnx_shared_timed_mutex_try_lock_for(CnxSharedTimedMutex*restrict mutex,
CnxDuration duration)
#include <include/Cnx/sync/SharedMutex.h>
Attempts to lock the mutex pointed to by mutex
exclusively (aka for writing)
Parameters | |
---|---|
mutex | - The mutex to lock |
duration | - The amount to time spend trying to lock the mutex |
Returns | true if successful |
Tries to lock the mutex
until the amount of time specified by duration
has passed. If locking is successful before duration
has elapsed, returns true
. Otherwise stops trying to acquire the lock and returns false
.
bool cnx_shared_timed_mutex_try_lock_until(CnxSharedTimedMutex*restrict mutex,
CnxTimePoint stop_point)
#include <include/Cnx/sync/SharedMutex.h>
Attempts to lock the mutex pointed to by mutex
exclusively (aka for writing)
Parameters | |
---|---|
mutex | - The mutex to lock |
stop_point | - The point in time at which to quit trying to lock the mutex |
Returns | true if successful |
Tries to lock the mutex
until the the point in time specified by stop_point
. If locking is successful before stop_point
has occurred, returns true
. Otherwise stops trying to acquire the lock and returns false
.
void cnx_shared_timed_mutex_lock_shared(CnxSharedTimedMutex*restrict mutex)
#include <include/Cnx/sync/SharedMutex.h>
Unconditionally locks the mutex pointed to by mutex
non-exclusively (shared, aka for reading)
Parameters | |
---|---|
mutex | - The mutex to lock non-exclusively (aka shared, for reading) |
bool cnx_shared_timed_mutex_try_lock_shared(CnxSharedTimedMutex*restrict mutex)
#include <include/Cnx/sync/SharedMutex.h>
Attempts to lock the mutex pointed to by mutex
non-exclusively (shared, aka for reading)
Parameters | |
---|---|
mutex | - The mutex to lock non-exclusively (aka shared, for reading) |
Returns | true if successful |
If locking the mutex is successful, return true
.
bool cnx_shared_timed_mutex_try_lock_shared_for(CnxSharedTimedMutex*restrict mutex,
CnxDuration duration)
#include <include/Cnx/sync/SharedMutex.h>
Attempts to lock the mutex pointed to by mutex
non-exclusively (aka shared, for reading)
Parameters | |
---|---|
mutex | - The mutex to lock |
duration | - The amount to time spend trying to lock the mutex |
Returns | true if successful |
Tries to lock the mutex
until the amount of time specified by duration
has passed. If locking is successful before duration
has elapsed, returns true
. Otherwise stops trying to acquire the lock and returns false
.
bool cnx_shared_timed_mutex_try_lock_shared_until(CnxSharedTimedMutex*restrict mutex,
CnxTimePoint stop_point)
#include <include/Cnx/sync/SharedMutex.h>
Attempts to lock the mutex pointed to by mutex
non-exclusively (aka shared, for reading)
Parameters | |
---|---|
mutex | - The mutex to lock |
stop_point | - The point in time at which to quit trying to lock the mutex |
Returns | true if successful |
Tries to lock the mutex
until the the point in time specified by stop_point
. If locking is successful before stop_point
has occurred, returns true
. Otherwise stops trying to acquire the lock and returns false
.
void cnx_shared_timed_mutex_unlock(CnxSharedTimedMutex*restrict mutex)
#include <include/Cnx/sync/SharedMutex.h>
Unlocks the exclusively locked mutex pointed to by mutex
Parameters | |
---|---|
mutex | - The mutex to unlock exclusively |
void cnx_shared_timed_mutex_unlock_shared(CnxSharedTimedMutex*restrict mutex)
#include <include/Cnx/sync/SharedMutex.h>
Unlocks the non-exclusively (aka shared) locked mutex pointed to by mutex
Parameters | |
---|---|
mutex | - The mutex to unlock non-exclusively |
void cnx_shared_timed_mutex_free(CnxSharedTimedMutex*restrict mutex)
#include <include/Cnx/sync/SharedMutex.h>
Destroys the mutex pointed to by mutex
Parameters | |
---|---|
mutex | - The mutex to free |