locks wip

This commit is contained in:
jacob 2025-07-06 15:21:33 -05:00
parent a9bcab1b78
commit 32b82f4417

View File

@ -35,7 +35,7 @@
#define FIBER_STACK_SIZE MEGABYTE(4) #define FIBER_STACK_SIZE MEGABYTE(4)
struct win32_mutex { struct win32_mutex {
volatile LONG state; /* Lower 30 bits = reader count, bit 30 = writer waiting, bit 31 = writer held */ struct atomic_i32 v; /* Bits 0-30 = shared lock count, bit 30 = is exclusive lock pending, bit 31 = is exclusive locked */
struct win32_mutex *next_free; struct win32_mutex *next_free;
}; };
@ -2552,20 +2552,23 @@ struct sys_lock sys_mutex_lock_e(struct sys_mutex *mutex)
{ {
__prof; __prof;
struct win32_mutex *m = (struct win32_mutex *)mutex; struct win32_mutex *m = (struct win32_mutex *)mutex;
{ b32 locked = false;
while (true) { while (!locked) {
//LONG expected = 0; i32 v = atomic_i32_fetch_test_set(&m->v, 0, (1 << 31));
if (InterlockedCompareExchange(&m->state, 0x80000000, 0) == 0) { if (v == 0) {
break; /* Acquired exclusive */ locked = true;
} else { } else {
/* Set writer pending */ /* Set pending */
LONG old; if ((v & (1 << 30)) == 0) {
do { i32 old = atomic_i32_fetch_test_set(&m->v, v | (1 << 30), v);
old = m->state; while (old != v && (old & (1 << 30)) == 0) {
if (old & 0x40000000) break; /* Already pending */ v = old;
} while (InterlockedCompareExchange(&m->state, old | 0x40000000, old) != old); old = atomic_i32_fetch_test_set(&m->v, v | (1 << 30), v);
sys_wait((void *)&m->state, (void *)&old, sizeof(old));
} }
v = old;
}
/* Wait for change */
sys_wait(&m->v, &v, 4);
} }
} }
struct sys_lock lock = ZI; struct sys_lock lock = ZI;
@ -2578,17 +2581,18 @@ struct sys_lock sys_mutex_lock_s(struct sys_mutex *mutex)
{ {
__prof; __prof;
struct win32_mutex *m = (struct win32_mutex *)mutex; struct win32_mutex *m = (struct win32_mutex *)mutex;
{ b32 locked = false;
while (true) { while (!locked) {
LONG old = m->state; i32 v = atomic_i32_fetch(&m->v);
/* If writer not held or pending */ while (!locked && (v & 0xC0000000) == 0) {
if ((old & 0xC0000000) == 0) { /* Increment shared lock count */
if (InterlockedCompareExchange(&m->state, old + 1, old) == old) { i32 old = atomic_i32_fetch_test_set(&m->v, v, v + 1);
break; /* Acquired shared */ if (v == old) {
locked = true;
} }
} else {
sys_wait((void *)&m->state, &old, sizeof(old));
} }
if (!locked) {
sys_wait(&m->v, &v, 4);
} }
} }
struct sys_lock lock = ZI; struct sys_lock lock = ZI;
@ -2601,15 +2605,11 @@ void sys_mutex_unlock(struct sys_lock *lock)
__prof; __prof;
struct win32_mutex *m = (struct win32_mutex *)lock->mutex; struct win32_mutex *m = (struct win32_mutex *)lock->mutex;
if (lock->exclusive) { if (lock->exclusive) {
//LONG old = m->state; atomic_i32_fetch_set(&m->v, 0);
InterlockedExchange(&m->state, 0); /* Clear all bits */
sys_wake_all((void *)&m->state);
} else { } else {
LONG old = InterlockedDecrement(&m->state); atomic_i32_fetch_add(&m->v, -1);
if (old == 1) {
sys_wake_all((void *)&m->state);
}
} }
sys_wake_all(&m->v);
MEMZERO_STRUCT(lock); MEMZERO_STRUCT(lock);
} }