Use RW spin locks
All checks were successful
Build documentation / build-and-deploy (push) Successful in 39s

This commit is contained in:
2026-01-09 19:53:08 +01:00
parent a5283283f6
commit 6a474c21a0
9 changed files with 198 additions and 39 deletions

View File

@@ -0,0 +1,59 @@
#include <libk/assert.h>
#include <libk/std.h>
#include <sync/rw_spin_lock.h>
#include <sys/debug.h>
#include <sys/spin_lock.h>
#define WRITER_WAIT (1U << 31)
#define READER_MASK (~WRITER_WAIT)
void rw_spin_read_lock (rw_spin_lock_t* rw) {
uint32_t value;
for (;;) {
value = atomic_load_explicit (rw, memory_order_relaxed);
if ((value & WRITER_WAIT) == 0) {
if (atomic_compare_exchange_weak_explicit (rw, &value, value + 1, memory_order_acquire,
memory_order_relaxed)) {
return;
}
}
spin_lock_relax ();
}
}
void rw_spin_read_unlock (rw_spin_lock_t* rw) {
uint32_t old = atomic_fetch_sub_explicit (rw, 1, memory_order_release);
assert ((old & READER_MASK) > 0);
}
void rw_spin_write_lock (rw_spin_lock_t* rw) {
uint32_t value;
/* announce writer */
for (;;) {
value = atomic_load_explicit (rw, memory_order_relaxed);
if ((value & WRITER_WAIT) == 0) {
if (atomic_compare_exchange_weak_explicit (rw, &value, (value | WRITER_WAIT),
memory_order_acquire, memory_order_relaxed))
break;
} else
spin_lock_relax ();
}
/* wait for readers */
for (;;) {
value = atomic_load_explicit (rw, memory_order_acquire);
if ((value & READER_MASK) == 0)
return;
spin_lock_relax ();
}
}
void rw_spin_write_unlock (rw_spin_lock_t* rw) {
atomic_store_explicit (rw, 0, memory_order_release);
}

View File

@@ -0,0 +1,16 @@
#ifndef _KERNEL_SYNC_RW_SPIN_LOCK_H
#define _KERNEL_SYNC_RW_SPIN_LOCK_H
#include <libk/std.h>
#include <sync/spin_lock.h>
#define RW_SPIN_LOCK_INIT 0
typedef _Atomic (uint32_t) rw_spin_lock_t;
void rw_spin_read_lock (rw_spin_lock_t* rw);
void rw_spin_read_unlock (rw_spin_lock_t* rw);
void rw_spin_write_lock (rw_spin_lock_t* rw);
void rw_spin_write_unlock (rw_spin_lock_t* rw);
#endif // _KERNEL_SYNC_RW_SPIN_LOCK_H

View File

@@ -1,3 +1,5 @@
c += sync/spin_lock.c
c += sync/spin_lock.c \
sync/rw_spin_lock.c
o += sync/spin_lock.o
o += sync/spin_lock.o \
sync/rw_spin_lock.o