aboutsummaryrefslogtreecommitdiffstats
path: root/internal-llmutex.h
diff options
context:
space:
mode:
authorMattias Andrée <maandree@kth.se>2020-04-20 18:58:00 +0200
committerMattias Andrée <maandree@kth.se>2020-04-20 18:58:00 +0200
commitda8b1c1d1baafb9cf4a0cc9a88362f161f8d1319 (patch)
tree0fb0676b127996064ccb75b695e9aaf9657ce9f1 /internal-llmutex.h
downloadlibaxl-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 'internal-llmutex.h')
-rw-r--r--internal-llmutex.h74
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)