Implement lock IRQ nesting via stack variables/contexts
All checks were successful
Build documentation / build-and-deploy (push) Successful in 21s

This commit is contained in:
2026-01-14 22:11:56 +01:00
parent 55166f9d5f
commit 270ff507d4
22 changed files with 197 additions and 145 deletions

View File

@@ -2,14 +2,17 @@
#include <libk/std.h>
#include <sync/rw_spin_lock.h>
#include <sys/debug.h>
#include <sys/irq.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) {
void rw_spin_read_lock (rw_spin_lock_t* rw, spin_lock_ctx_t* ctx) {
uint32_t value;
irq_save (ctx);
for (;;) {
value = atomic_load_explicit (rw, memory_order_relaxed);
@@ -24,14 +27,17 @@ void rw_spin_read_lock (rw_spin_lock_t* rw) {
}
}
void rw_spin_read_unlock (rw_spin_lock_t* rw) {
void rw_spin_read_unlock (rw_spin_lock_t* rw, spin_lock_ctx_t* ctx) {
uint32_t old = atomic_fetch_sub_explicit (rw, 1, memory_order_release);
assert ((old & READER_MASK) > 0);
irq_restore (ctx);
}
void rw_spin_write_lock (rw_spin_lock_t* rw) {
void rw_spin_write_lock (rw_spin_lock_t* rw, spin_lock_ctx_t* ctx) {
uint32_t value;
irq_save (ctx);
/* announce writer */
for (;;) {
value = atomic_load_explicit (rw, memory_order_relaxed);
@@ -40,8 +46,9 @@ void rw_spin_write_lock (rw_spin_lock_t* rw) {
if (atomic_compare_exchange_weak_explicit (rw, &value, (value | WRITER_WAIT),
memory_order_acquire, memory_order_relaxed))
break;
} else
} else {
spin_lock_relax ();
}
}
/* wait for readers */
@@ -54,6 +61,7 @@ void rw_spin_write_lock (rw_spin_lock_t* rw) {
}
}
void rw_spin_write_unlock (rw_spin_lock_t* rw) {
void rw_spin_write_unlock (rw_spin_lock_t* rw, spin_lock_ctx_t* ctx) {
atomic_store_explicit (rw, 0, memory_order_release);
irq_restore (ctx);
}

View File

@@ -3,14 +3,15 @@
#include <libk/std.h>
#include <sync/spin_lock.h>
#include <sys/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);
void rw_spin_read_lock (rw_spin_lock_t* rw, spin_lock_ctx_t* ctx);
void rw_spin_read_unlock (rw_spin_lock_t* rw, spin_lock_ctx_t* ctx);
void rw_spin_write_lock (rw_spin_lock_t* rw, spin_lock_ctx_t* ctx);
void rw_spin_write_unlock (rw_spin_lock_t* rw, spin_lock_ctx_t* ctx);
#endif // _KERNEL_SYNC_RW_SPIN_LOCK_H

View File

@@ -3,15 +3,15 @@
#include <sys/irq.h>
#include <sys/spin_lock.h>
void spin_lock (spin_lock_t* sl) {
irq_save ();
void spin_lock (spin_lock_t* sl, spin_lock_ctx_t* ctx) {
irq_save (ctx);
while (atomic_flag_test_and_set_explicit (sl, memory_order_acquire))
spin_lock_relax ();
}
void spin_unlock (spin_lock_t* sl) {
void spin_unlock (spin_lock_t* sl, spin_lock_ctx_t* ctx) {
atomic_flag_clear_explicit (sl, memory_order_release);
irq_restore ();
irq_restore (ctx);
}

View File

@@ -2,12 +2,13 @@
#define _KERNEL_SYNC_SPIN_LOCK_H
#include <libk/std.h>
#include <sys/spin_lock.h>
#define SPIN_LOCK_INIT ATOMIC_FLAG_INIT
typedef atomic_flag spin_lock_t;
void spin_lock (spin_lock_t* sl);
void spin_unlock (spin_lock_t* sl);
void spin_lock (spin_lock_t* sl, spin_lock_ctx_t* ctx);
void spin_unlock (spin_lock_t* sl, spin_lock_ctx_t* ctx);
#endif // _KERNEL_SYNC_SPIN_LOCK_H