diff options
author | Mattias Andrée <maandree@kth.se> | 2020-04-20 18:58:00 +0200 |
---|---|---|
committer | Mattias Andrée <maandree@kth.se> | 2020-04-20 18:58:00 +0200 |
commit | da8b1c1d1baafb9cf4a0cc9a88362f161f8d1319 (patch) | |
tree | 0fb0676b127996064ccb75b695e9aaf9657ce9f1 /internal-llmutex.h | |
download | libaxl-da8b1c1d1baafb9cf4a0cc9a88362f161f8d1319.tar.gz libaxl-da8b1c1d1baafb9cf4a0cc9a88362f161f8d1319.tar.bz2 libaxl-da8b1c1d1baafb9cf4a0cc9a88362f161f8d1319.tar.xz |
First commit
Signed-off-by: Mattias Andrée <maandree@kth.se>
Diffstat (limited to '')
-rw-r--r-- | internal-llmutex.h | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/internal-llmutex.h b/internal-llmutex.h new file mode 100644 index 0000000..b75a449 --- /dev/null +++ b/internal-llmutex.h @@ -0,0 +1,74 @@ +/* See LICENSE file for copyright and license details. */ + +#define LIBAXL_CONNECTION_RWLOCK\ + volatile _Atomic char nrguard_send;\ + volatile _Atomic char nrguard_recv;\ + MUTEX exguard_send;\ + MUTEX exguard_recv;\ + MUTEX exwait_send;\ + MUTEX exwait_recv;\ + volatile size_t nreaders_send;\ + volatile size_t nreaders_recv + +#define INIT_LIBAXL_CONNECTION_RWLOCK(CONN)\ + do {\ + atomic_init(&(CONN)->nrguard_send, 0);\ + atomic_init(&(CONN)->nrguard_recv, 0);\ + INIT_MUTEX((CONN)->exguard_send);\ + INIT_MUTEX((CONN)->exguard_recv);\ + INIT_MUTEX((CONN)->exwait_send);\ + INIT_MUTEX((CONN)->exwait_recv);\ + (CONN)->nreaders_send = 0;\ + (CONN)->nreaders_recv = 0;\ + } while (0) + +#define WLOCK_CONNECTION_(CONN, SUFFIX) _LOCK((CONN)->exguard_##SUFFIX) +#define WTRYLOCK_CONNECTION_(CONN, SUFFIX) _TRYLOCK((CONN)->exguard_##SUFFIX) +#define WUNLOCK_CONNECTION_(CONN, SUFFIX) _UNLOCK((CONN)->exguard_##SUFFIX) + +#define RLOCK_CONNECTION_(CONN, SUFFIX)\ + do {\ + char old_val__;\ + do {\ + do {\ + old_val__ = atomic_fetch_or(&(CONN)->nrguard_##SUFFIX, 1);\ + } while (old_val__ == 1);\ + if (old_val__ == 0) {\ + if (!(CONN)->nreaders_##SUFFIX++) {\ + if (WTRYLOCK_CONNECTION_(CONN, SUFFIX)) {\ + atomic_store(&(CONN)->nrguard_##SUFFIX, 2);\ + } else {\ + _LOCK((CONN)->exwait_##SUFFIX);\ + atomic_store(&(CONN)->nrguard_##SUFFIX, 2);\ + WLOCK_CONNECTION_(CONN, SUFFIX);\ + _UNLOCK((CONN)->exwait_##SUFFIX);\ + }\ + }\ + atomic_store(&(CONN)->nrguard_##SUFFIX, 0);\ + break;\ + } else {\ + _WAIT((CONN)->exwait_##SUFFIX);\ + }\ + } while (old_val__ == 2);\ + } while (0) + +#define RUNLOCK_CONNECTION_(CONN, SUFFIX)\ + do {\ + char old_val__;\ + do {\ + old_val__ = atomic_fetch_or(&(CONN)->nrguard_##SUFFIX, 1);\ + } while (old_val__);\ + if (!--(CONN)->nreaders_##SUFFIX)\ + WUNLOCK_CONNECTION_((CONN), SUFFIX);\ + atomic_store(&(CONN)->nrguard_##SUFFIX, 0);\ + } while (0) + +#define WLOCK_CONNECTION_SEND(CONN) WLOCK_CONNECTION_(CONN, send) +#define WUNLOCK_CONNECTION_SEND(CONN) WUNLOCK_CONNECTION_(CONN, send) +#define RLOCK_CONNECTION_SEND(CONN) RLOCK_CONNECTION_(CONN, send) +#define RUNLOCK_CONNECTION_SEND(CONN) RUNLOCK_CONNECTION_(CONN, send) + +#define WLOCK_CONNECTION_RECV(CONN) WLOCK_CONNECTION_(CONN, recv) +#define WUNLOCK_CONNECTION_RECV(CONN) WUNLOCK_CONNECTION_(CONN, recv) +#define RLOCK_CONNECTION_RECV(CONN) RLOCK_CONNECTION_(CONN, recv) +#define RUNLOCK_CONNECTION_RECV(CONN) RUNLOCK_CONNECTION_(CONN, recv) |