mirror of
https://github.com/odin-lang/Odin.git
synced 2026-04-19 04:50:29 +00:00
Update sys/windows; Add sync.Blocking_Mutex (windows only at the moment)
This commit is contained in:
@@ -2,19 +2,25 @@
|
||||
package sync
|
||||
|
||||
import win32 "core:sys/windows"
|
||||
import "core:time"
|
||||
|
||||
// A lock that can only be held by one thread at once.
|
||||
Mutex :: struct {
|
||||
_critical_section: win32.CRITICAL_SECTION,
|
||||
}
|
||||
|
||||
Blocking_Mutex :: struct {
|
||||
_handle: win32.SRWLOCK,
|
||||
}
|
||||
|
||||
|
||||
Condition_Mutex_Ptr :: union{^Mutex, ^Blocking_Mutex};
|
||||
|
||||
// Blocks until signalled.
|
||||
// When signalled, awakens exactly one waiting thread.
|
||||
Condition :: struct {
|
||||
_handle: win32.CONDITION_VARIABLE,
|
||||
|
||||
mutex: ^Mutex,
|
||||
mutex: Condition_Mutex_Ptr,
|
||||
}
|
||||
|
||||
// When waited upon, blocks until the internal count is greater than zero, then subtracts one.
|
||||
@@ -23,6 +29,10 @@ Semaphore :: struct {
|
||||
_handle: win32.HANDLE,
|
||||
}
|
||||
|
||||
RW_Lock :: struct {
|
||||
_handle: win32.SRWLOCK,
|
||||
}
|
||||
|
||||
|
||||
semaphore_init :: proc(s: ^Semaphore, initial_count := 0) {
|
||||
s._handle = win32.CreateSemaphoreW(nil, i32(initial_count), 1<<31-1, nil);
|
||||
@@ -63,7 +73,28 @@ mutex_unlock :: proc(m: ^Mutex) {
|
||||
win32.LeaveCriticalSection(&m._critical_section);
|
||||
}
|
||||
|
||||
condition_init :: proc(c: ^Condition, mutex: ^Mutex) -> bool {
|
||||
blocking_mutex_init :: proc(m: ^Blocking_Mutex) {
|
||||
//
|
||||
}
|
||||
|
||||
blocking_mutex_destroy :: proc(m: ^Blocking_Mutex) {
|
||||
//
|
||||
}
|
||||
|
||||
blocking_mutex_lock :: proc(m: ^Blocking_Mutex) {
|
||||
win32.AcquireSRWLockExclusive(&m._handle);
|
||||
}
|
||||
|
||||
blocking_mutex_try_lock :: proc(m: ^Blocking_Mutex) -> bool {
|
||||
return bool(win32.TryAcquireSRWLockExclusive(&m._handle));
|
||||
}
|
||||
|
||||
blocking_mutex_unlock :: proc(m: ^Blocking_Mutex) {
|
||||
win32.ReleaseSRWLockExclusive(&m._handle);
|
||||
}
|
||||
|
||||
|
||||
condition_init :: proc(c: ^Condition, mutex: Condition_Mutex_Ptr) -> bool {
|
||||
assert(mutex != nil);
|
||||
win32.InitializeConditionVariable(&c._handle);
|
||||
c.mutex = mutex;
|
||||
@@ -71,9 +102,7 @@ condition_init :: proc(c: ^Condition, mutex: ^Mutex) -> bool {
|
||||
}
|
||||
|
||||
condition_destroy :: proc(c: ^Condition) {
|
||||
if c._handle.ptr != nil {
|
||||
win32.WakeAllConditionVariable(&c._handle);
|
||||
}
|
||||
//
|
||||
}
|
||||
|
||||
condition_signal :: proc(c: ^Condition) -> bool {
|
||||
@@ -93,5 +122,51 @@ condition_broadcast :: proc(c: ^Condition) -> bool {
|
||||
}
|
||||
|
||||
condition_wait_for :: proc(c: ^Condition) -> bool {
|
||||
return cast(bool)win32.SleepConditionVariableCS(&c._handle, &c.mutex._critical_section, win32.INFINITE);
|
||||
switch m in &c.mutex {
|
||||
case ^Mutex:
|
||||
return cast(bool)win32.SleepConditionVariableCS(&c._handle, &m._critical_section, win32.INFINITE);
|
||||
case ^Blocking_Mutex:
|
||||
return cast(bool)win32.SleepConditionVariableSRW(&c._handle, &m._handle, win32.INFINITE, 0);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
condition_wait_for_timeout :: proc(c: ^Condition, duration: time.Duration) -> bool {
|
||||
ms := win32.DWORD((time.duration_nanoseconds(duration) + 999999)/1000000);
|
||||
switch m in &c.mutex {
|
||||
case ^Mutex:
|
||||
return cast(bool)win32.SleepConditionVariableCS(&c._handle, &m._critical_section, ms);
|
||||
case ^Blocking_Mutex:
|
||||
return cast(bool)win32.SleepConditionVariableSRW(&c._handle, &m._handle, ms, 0);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
rw_lock_init :: proc(l: ^RW_Lock) {
|
||||
l._handle = win32.SRWLOCK_INIT;
|
||||
}
|
||||
rw_lock_destroy :: proc(l: ^RW_Lock) {
|
||||
//
|
||||
}
|
||||
rw_lock_read :: proc(l: ^RW_Lock) {
|
||||
win32.AcquireSRWLockShared(&l._handle);
|
||||
}
|
||||
rw_lock_try_read :: proc(l: ^RW_Lock) -> bool {
|
||||
return bool(win32.TryAcquireSRWLockShared(&l._handle));
|
||||
}
|
||||
rw_lock_write :: proc(l: ^RW_Lock) {
|
||||
win32.AcquireSRWLockExclusive(&l._handle);
|
||||
}
|
||||
rw_lock_try_write :: proc(l: ^RW_Lock) -> bool {
|
||||
return bool(win32.TryAcquireSRWLockExclusive(&l._handle));
|
||||
}
|
||||
rw_lock_read_unlock :: proc(l: ^RW_Lock) {
|
||||
win32.ReleaseSRWLockShared(&l._handle);
|
||||
}
|
||||
rw_lock_write_unlock :: proc(l: ^RW_Lock) {
|
||||
win32.ReleaseSRWLockExclusive(&l._handle);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -245,6 +245,9 @@ foreign kernel32 {
|
||||
AcquireSRWLockExclusive :: proc(SRWLock: ^SRWLOCK) ---
|
||||
TryAcquireSRWLockExclusive :: proc(SRWLock: ^SRWLOCK) -> BOOL ---
|
||||
ReleaseSRWLockExclusive :: proc(SRWLock: ^SRWLOCK) ---
|
||||
AcquireSRWLockShared :: proc(SRWLock: ^SRWLOCK) ---
|
||||
TryAcquireSRWLockShared :: proc(SRWLock: ^SRWLOCK) -> BOOL ---
|
||||
ReleaseSRWLockShared :: proc(SRWLock: ^SRWLOCK) ---
|
||||
|
||||
InitializeConditionVariable :: proc(ConditionVariable: ^CONDITION_VARIABLE) ---
|
||||
WakeConditionVariable :: proc(ConditionVariable: ^CONDITION_VARIABLE) ---
|
||||
|
||||
@@ -63,7 +63,7 @@ PCONDITION_VARIABLE :: ^CONDITION_VARIABLE;
|
||||
PLARGE_INTEGER :: ^LARGE_INTEGER;
|
||||
PSRWLOCK :: ^SRWLOCK;
|
||||
|
||||
SOCKET :: distinct rawptr; // TODO
|
||||
SOCKET :: distinct uintptr; // TODO
|
||||
socklen_t :: c_int;
|
||||
ADDRESS_FAMILY :: USHORT;
|
||||
|
||||
@@ -147,7 +147,7 @@ WSA_FLAG_NO_HANDLE_INHERIT: DWORD : 0x80;
|
||||
WSADESCRIPTION_LEN :: 256;
|
||||
WSASYS_STATUS_LEN :: 128;
|
||||
WSAPROTOCOL_LEN: DWORD : 255;
|
||||
INVALID_SOCKET :: SOCKET(~uintptr(0));
|
||||
INVALID_SOCKET :: ~SOCKET(0);
|
||||
|
||||
WSAEACCES: c_int : 10013;
|
||||
WSAEINVAL: c_int : 10022;
|
||||
|
||||
@@ -95,5 +95,5 @@ terminate :: proc(using thread : ^Thread, exit_code: u32) {
|
||||
}
|
||||
|
||||
yield :: proc() {
|
||||
win32.Sleep(0);
|
||||
win32.SwitchToThread();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user