From da8b1c1d1baafb9cf4a0cc9a88362f161f8d1319 Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Mon, 20 Apr 2020 18:58:00 +0200 Subject: First commit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- internal-llmutex.h | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 internal-llmutex.h (limited to 'internal-llmutex.h') 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) -- cgit v1.2.3-70-g09d2