aboutsummaryrefslogtreecommitdiffstats
path: root/internal-llmutex.h
blob: a6a3e783e2de84c1ef1d046bfee007385d44fe34 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
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)