1 #include <lunaix/ds/rwlock.h>
2 #include <lunaix/spike.h>
5 rwlock_init(rwlock_t* rwlock)
7 waitq_init(&rwlock->waiting_readers);
8 waitq_init(&rwlock->waiting_writers);
9 atomic_init(&rwlock->readers, 0);
10 atomic_flag_clear(&rwlock->writer);
14 rwlock_begin_read(rwlock_t* rwlock)
16 while (atomic_flag_test_and_set(&rwlock->writer)) {
17 pwait(&rwlock->waiting_readers);
19 atomic_fetch_add(&rwlock->readers, 1);
20 atomic_flag_clear(&rwlock->writer);
21 pwake_all(&rwlock->waiting_readers);
25 rwlock_end_read(rwlock_t* rwlock)
27 assert(atomic_load(&rwlock->readers) > 0);
28 atomic_fetch_sub(&rwlock->readers, 1);
30 if (!atomic_load(&rwlock->readers)) {
31 pwake_one(&rwlock->waiting_writers);
36 rwlock_begin_write(rwlock_t* rwlock)
38 // first, acquire writer lock, prevent any incoming readers
39 while (atomic_flag_test_and_set(&rwlock->writer)) {
40 pwait(&rwlock->waiting_writers);
43 // then, wait for reader finish the read.
44 while (atomic_load(&rwlock->readers)) {
45 pwait(&rwlock->waiting_writers);
50 rwlock_end_write(rwlock_t* rwlock)
52 atomic_flag_clear(&rwlock->writer);
53 if (waitq_empty(&rwlock->waiting_writers)) {
54 pwake_all(&rwlock->waiting_readers);
56 pwake_one(&rwlock->waiting_writers);