P99
|
A simple to use integer valued conditional for user code. More...
Data Structures | |
struct | p99_cm |
struct | p99_count |
A counter that allows atomic increment and decrement and a wait for the value 0. More... | |
struct | p99_event |
struct | p99_futex |
A counter similar to a conditional variable that allows atomic increment and decrement and to wait for the atomic compare and exchange for a specific value. More... | |
struct | p99_iterator |
Iterate over a series events that are signaled by other threads. More... | |
struct | p99_notifier |
Set a flag and notify other threads that an event has occurred. More... | |
struct | p99_rwl |
A simple rwlock implementation. More... | |
Macros | |
#define | P99_ACCOUNT(COUNT) |
Account the p99_count COUNT during execution of a dependent block or statement. More... | |
#define | P99_CM_EXCLUDE(CMP) P00_CM_EXCLUDE(CMP, P99_UNIQ(cm)) |
Protect the following block or statement as a critical section of the program by using CMP as a condition-mutex. More... | |
#define | P99_CM_INITIALIZER P99_FUTEX_INITIALIZER(p99_cm_unlocked) |
Initialize an p99_cm object. More... | |
#define | p99_count_init(...) P99_CALL_DEFARG(p99_count_init, 2, __VA_ARGS__) |
#define | P99_COUNT_INITIALIZER P99_FUTEX_INITIALIZER |
Initialize an p99_count object. More... | |
#define | P99_NOTIFIER_INITIALIZER P99_FUTEX_INITIALIZER(0u) |
Initialize an p99_notifier object. More... | |
#define | P99_RDLOCK(RWLOCK) |
#define | P99_RWL_INITIALIZER |
Initialize an p99_rwl object. More... | |
#define | P99_WRLOCK(RWLOCK) |
Typedefs | |
typedef struct p99_cm | p99_cm |
A simple condition-mutex data structure. More... | |
typedef struct p99_event | p99_event |
typedef struct p99_iterator | p99_iterator |
Enumerations | |
enum | |
Functions | |
void | p99_cm_destroy (p99_cm *p00_cm) |
destroy a cm More... | |
p99_cm * | p99_cm_init (p99_cm *p00_cm) |
Initialize a cm. More... | |
void | p99_cm_lock (p99_cm volatile *p00_cm) |
Acquire p00_cm. More... | |
bool | p99_cm_trylock (p99_cm volatile *p00_cm) |
Acquire p00_cm. More... | |
void | p99_cm_unlock (p99_cm volatile *p00_cm) |
Unconditionally unlock p00_cm and wake up a waiter, if any. More... | |
void | p99_cm_wait (p99_cm volatile *p00_cm) |
Wait until another thread successfully locks and unlocks p00_cm. More... | |
void | p99_count_destroy (p99_count *p00_c) |
p99_count * | p99_count_init (p99_count *p00_c, unsigned p00_v) |
Initialize an p99_count object. More... | |
unsigned | p99_count_value (p99_count volatile *p00_c) |
Obtain the value of counter p00_c atomically. More... | |
void | p99_count_wait (p99_count volatile *p00_c) |
wait until the p00_c counter falls to 0 . More... | |
void | p99_event_destroy (p99_event *p00_e) |
destroy an event More... | |
p99_event * | p99_event_init (p99_event *p00_e, unsigned p00_n) |
Initialize an event. More... | |
void * | p99_event_next (p99_event volatile *p00_e) |
Block until an event has been signaled that has not yet been accounted for. More... | |
void | p99_event_signal (p99_event volatile *p00_e, void *p00_w) |
Signal the event. p00_w. More... | |
unsigned | p99_futex_add (p99_futex volatile *p00_fut, unsigned p00_hmuch, unsigned p00_cstart, unsigned p00_clen, unsigned p00_wmin, unsigned p00_wmax) |
increment the counter of p00_fut atomically by p00_hmuch. More... | |
void | p99_futex_destroy (p99_futex *p00_c) |
Destroy an p99_futex object. More... | |
unsigned | p99_futex_exchange (p99_futex volatile *p00_fut, unsigned p00_desired, unsigned p00_cstart, unsigned p00_clen, unsigned p00_wmin, unsigned p00_wmax) |
Unconditionally and atomically set the futex p00_fut to value p00_desired. More... | |
p99_futex * | p99_futex_init (p99_futex *p00_c, unsigned p00_ini) |
Initialize an p99_futex object. More... | |
unsigned | p99_futex_load (p99_futex volatile *p00_fut) |
Obtain the value of futex p00_fut atomically. More... | |
void | p99_futex_wait (p99_futex volatile *p00_fut) |
Unconditionally wait for futex p00_fut. More... | |
void | p99_futex_wakeup (p99_futex volatile *p00_fut, unsigned p00_wmin, unsigned p00_wmax) |
Wake up threads that are waiting for a futex. More... | |
void | p99_iterator_destroy (p99_iterator *p00_i) |
destroy a iterator More... | |
p99_iterator * | p99_iterator_init (p99_iterator *p00_i) |
Initialize an iterator. More... | |
unsigned | p99_iterator_next (p99_iterator volatile *p00_i) |
Block until an event has been signaled that has not yet been accounted for. More... | |
unsigned | p99_iterator_signal (p99_iterator volatile *p00_i) |
Signal an event. More... | |
void | p99_notifier_block (p99_notifier volatile *p00_n, unsigned p00_v) |
Block until the notification flag has been set to the indicated value. More... | |
void | p99_notifier_destroy (p99_notifier *p00_n) |
destroy a notifier More... | |
p99_notifier * | p99_notifier_init (p99_notifier *p00_n, unsigned p00_v) |
Initialize a notifier to value p00_v. More... | |
unsigned | p99_notifier_load (p99_notifier volatile *p00_n) |
Return the value of the notifier. Non blocking. More... | |
void | p99_rwl_destroy (p99_rwl *p00_r) |
bool | p99_rwl_haswaiters (p99_rwl volatile *p00_r) |
Tell if has waiters. More... | |
p99_rwl * | p99_rwl_init (p99_rwl *p00_r) |
Initialize an p99_rwl object. More... | |
bool | p99_rwl_islocked (p99_rwl volatile *p00_r) |
Tell if is locked. More... | |
int | p99_rwl_rdlock (p99_rwl volatile *p00_r) |
establish a shared lock for rwlock p00_c. More... | |
int | p99_rwl_unlock (p99_rwl volatile *p00_r) |
release a lock on rwlock p00_r. More... | |
int | p99_rwl_wrlock (p99_rwl volatile *p00_r) |
establish an exclusive lock for rwlock p00_r. More... | |
A simple to use integer valued conditional for user code.
Most C11 or POSIX lock-and-wait structures have the disadvantage that they may have so-called spurious wakeups. These are wakeups that are not related to the application code signaling changes, but wakeups that are related to some internal OS events in which the programmer (that is not a system programmer) usually is not interested.
Starting from a brilliant idea in the Linux kernel, this implements a feature that can be seen as a primitive for locks and wakeup control structure. In fact it could be used to build up all other usual control structures (mutexes, conditional variables, read-write locks, barriers, semaphores ...)
There is only one feature that is yet missing, here, which is wait calls that would time out, such as ::mtx_timedlock or ::cnd_timedwait provide it, e.g. There is no principal hurdle to overcome for the addition of such a feature, I just don't use these often, and so I am not yet sure about what interface I would provide for this.