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