From 32b82f44176f7bb89a8872f54fa9af1e9a088855 Mon Sep 17 00:00:00 2001 From: jacob Date: Sun, 6 Jul 2025 15:21:33 -0500 Subject: [PATCH] locks wip --- src/sys_win32.c | 62 ++++++++++++++++++++++++------------------------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/src/sys_win32.c b/src/sys_win32.c index 6b0f80d5..7d34cbe0 100644 --- a/src/sys_win32.c +++ b/src/sys_win32.c @@ -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 */ - } 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)); + b32 locked = false; + while (!locked) { + i32 v = atomic_i32_fetch_test_set(&m->v, 0, (1 << 31)); + if (v == 0) { + locked = true; + } else { + /* 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,18 +2581,19 @@ 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 */ - } - } else { - sys_wait((void *)&m->state, &old, sizeof(old)); + 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; } } + if (!locked) { + sys_wait(&m->v, &v, 4); + } } struct sys_lock lock = ZI; lock.mutex = mutex; @@ -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); }