locks wip
This commit is contained in:
parent
a9bcab1b78
commit
32b82f4417
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user