PatchworkOS
Loading...
Searching...
No Matches
rwmutex.c
Go to the documentation of this file.
2
3#include <kernel/log/panic.h>
4#include <kernel/sched/wait.h>
5#include <kernel/sync/lock.h>
6
7#include <assert.h>
8#include <errno.h>
9
11{
12 mtx->activeReaders = 0;
13 mtx->waitingWriters = 0;
14 mtx->hasWriter = false;
17 lock_init(&mtx->lock);
18}
19
21{
22 LOCK_SCOPE(&mtx->lock);
23 assert(mtx->activeReaders == 0);
24 assert(mtx->waitingWriters == 0);
25 assert(!mtx->hasWriter);
28}
29
31{
32 if (mtx == NULL)
33 {
34 return;
35 }
36
37 LOCK_SCOPE(&mtx->lock);
38
39 while (WAIT_BLOCK_LOCK(&mtx->readerQueue, &mtx->lock, !(mtx->hasWriter || mtx->waitingWriters > 0)) == ERR)
40 {
41 // Wait until unblocked.
42 }
43
44 mtx->activeReaders++;
45}
46
48{
49 if (mtx == NULL)
50 {
51 errno = EINVAL;
52 return ERR;
53 }
54
55 LOCK_SCOPE(&mtx->lock);
56
57 if (mtx->waitingWriters > 0 || mtx->hasWriter)
58 {
60 return ERR;
61 }
62
63 mtx->activeReaders++;
64 return 0;
65}
66
68{
69 if (mtx == NULL)
70 {
71 return;
72 }
73
74 LOCK_SCOPE(&mtx->lock);
75
76 assert(mtx->activeReaders > 0);
77 mtx->activeReaders--;
78
79 if (mtx->activeReaders == 0 && mtx->waitingWriters > 0)
80 {
81 wait_unblock(&mtx->writerQueue, 1, EOK);
82 }
83}
84
86{
87 if (mtx == NULL)
88 {
89 return;
90 }
91
92 LOCK_SCOPE(&mtx->lock);
93
94 mtx->waitingWriters++;
95 while (WAIT_BLOCK_LOCK(&mtx->writerQueue, &mtx->lock, !(mtx->activeReaders > 0 || mtx->hasWriter)) == ERR)
96 {
97 // Wait until unblocked
98 }
99
100 mtx->waitingWriters--;
101 mtx->hasWriter = true;
102}
103
105{
106 if (mtx == NULL)
107 {
108 errno = EINVAL;
109 return ERR;
110 }
111
112 LOCK_SCOPE(&mtx->lock);
113
114 if (mtx->activeReaders > 0 || mtx->hasWriter)
115 {
117 return ERR;
118 }
119
120 mtx->hasWriter = true;
121 return 0;
122}
123
125{
126 if (mtx == NULL)
127 {
128 return;
129 }
130
131 LOCK_SCOPE(&mtx->lock);
132
133 mtx->hasWriter = false;
134
135 if (mtx->waitingWriters > 0)
136 {
137 wait_unblock(&mtx->writerQueue, 1, EOK);
138 }
139 else
140 {
142 }
143}
#define assert(expression)
Definition assert.h:29
uint64_t wait_unblock(wait_queue_t *waitQueue, uint64_t amount, errno_t err)
Unblock threads waiting on a wait queue.
Definition wait.c:168
void wait_queue_init(wait_queue_t *waitQueue)
Initialize wait queue.
Definition wait.c:71
#define WAIT_ALL
Wait for all.
Definition wait.h:26
#define WAIT_BLOCK_LOCK(waitQueue, lock, condition)
Block with a spinlock.
Definition wait.h:101
void wait_queue_deinit(wait_queue_t *waitQueue)
Deinitialize wait queue.
Definition wait.c:77
static void lock_init(lock_t *lock)
Initializes a lock.
Definition lock.h:80
#define LOCK_SCOPE(lock)
Acquires a lock for the reminder of the current scope.
Definition lock.h:57
void rwmutex_write_acquire(rwmutex_t *mtx)
Acquires a rwmutex for writing, blocking until it is available.
Definition rwmutex.c:85
void rwmutex_init(rwmutex_t *mtx)
Initializes a rwmutex.
Definition rwmutex.c:10
uint64_t rwmutex_write_try_acquire(rwmutex_t *mtx)
Tries to acquire a rwmutex for writing.
Definition rwmutex.c:104
void rwmutex_read_acquire(rwmutex_t *mtx)
Acquires a rwmutex for reading, blocking until it is available.
Definition rwmutex.c:30
uint64_t rwmutex_read_try_acquire(rwmutex_t *mtx)
Tries to acquire a rwmutex for reading.
Definition rwmutex.c:47
void rwmutex_read_release(rwmutex_t *mtx)
Releases a rwmutex from reading.
Definition rwmutex.c:67
void rwmutex_deinit(rwmutex_t *mtx)
Deinitializes a rwmutex.
Definition rwmutex.c:20
void rwmutex_write_release(rwmutex_t *mtx)
Releases a rwmutex from writing.
Definition rwmutex.c:124
#define EINVAL
Invalid argument.
Definition errno.h:142
#define EWOULDBLOCK
Operation would block.
Definition errno.h:237
#define errno
Error number variable.
Definition errno.h:27
#define EOK
No error.
Definition errno.h:32
#define NULL
Pointer error value.
Definition NULL.h:23
#define ERR
Integer error value.
Definition ERR.h:17
__UINT64_TYPE__ uint64_t
Definition stdint.h:17
Read-Write Mutex structure.
Definition rwmutex.h:42
wait_queue_t writerQueue
Definition rwmutex.h:46
bool hasWriter
Definition rwmutex.h:47
wait_queue_t readerQueue
Definition rwmutex.h:45
uint16_t waitingWriters
Definition rwmutex.h:44
uint16_t activeReaders
Definition rwmutex.h:43
lock_t lock
Definition rwmutex.h:48