mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-05 15:18:49 +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
|
package sync
|
||||||
|
|
||||||
import win32 "core:sys/windows"
|
import win32 "core:sys/windows"
|
||||||
|
import "core:time"
|
||||||
|
|
||||||
// A lock that can only be held by one thread at once.
|
|
||||||
Mutex :: struct {
|
Mutex :: struct {
|
||||||
_critical_section: win32.CRITICAL_SECTION,
|
_critical_section: win32.CRITICAL_SECTION,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Blocking_Mutex :: struct {
|
||||||
|
_handle: win32.SRWLOCK,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Condition_Mutex_Ptr :: union{^Mutex, ^Blocking_Mutex};
|
||||||
|
|
||||||
// Blocks until signalled.
|
// Blocks until signalled.
|
||||||
// When signalled, awakens exactly one waiting thread.
|
// When signalled, awakens exactly one waiting thread.
|
||||||
Condition :: struct {
|
Condition :: struct {
|
||||||
_handle: win32.CONDITION_VARIABLE,
|
_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.
|
// When waited upon, blocks until the internal count is greater than zero, then subtracts one.
|
||||||
@@ -23,6 +29,10 @@ Semaphore :: struct {
|
|||||||
_handle: win32.HANDLE,
|
_handle: win32.HANDLE,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RW_Lock :: struct {
|
||||||
|
_handle: win32.SRWLOCK,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
semaphore_init :: proc(s: ^Semaphore, initial_count := 0) {
|
semaphore_init :: proc(s: ^Semaphore, initial_count := 0) {
|
||||||
s._handle = win32.CreateSemaphoreW(nil, i32(initial_count), 1<<31-1, nil);
|
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);
|
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);
|
assert(mutex != nil);
|
||||||
win32.InitializeConditionVariable(&c._handle);
|
win32.InitializeConditionVariable(&c._handle);
|
||||||
c.mutex = mutex;
|
c.mutex = mutex;
|
||||||
@@ -71,9 +102,7 @@ condition_init :: proc(c: ^Condition, mutex: ^Mutex) -> bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
condition_destroy :: proc(c: ^Condition) {
|
condition_destroy :: proc(c: ^Condition) {
|
||||||
if c._handle.ptr != nil {
|
//
|
||||||
win32.WakeAllConditionVariable(&c._handle);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
condition_signal :: proc(c: ^Condition) -> bool {
|
condition_signal :: proc(c: ^Condition) -> bool {
|
||||||
@@ -93,5 +122,51 @@ condition_broadcast :: proc(c: ^Condition) -> bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
condition_wait_for :: 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) ---
|
AcquireSRWLockExclusive :: proc(SRWLock: ^SRWLOCK) ---
|
||||||
TryAcquireSRWLockExclusive :: proc(SRWLock: ^SRWLOCK) -> BOOL ---
|
TryAcquireSRWLockExclusive :: proc(SRWLock: ^SRWLOCK) -> BOOL ---
|
||||||
ReleaseSRWLockExclusive :: proc(SRWLock: ^SRWLOCK) ---
|
ReleaseSRWLockExclusive :: proc(SRWLock: ^SRWLOCK) ---
|
||||||
|
AcquireSRWLockShared :: proc(SRWLock: ^SRWLOCK) ---
|
||||||
|
TryAcquireSRWLockShared :: proc(SRWLock: ^SRWLOCK) -> BOOL ---
|
||||||
|
ReleaseSRWLockShared :: proc(SRWLock: ^SRWLOCK) ---
|
||||||
|
|
||||||
InitializeConditionVariable :: proc(ConditionVariable: ^CONDITION_VARIABLE) ---
|
InitializeConditionVariable :: proc(ConditionVariable: ^CONDITION_VARIABLE) ---
|
||||||
WakeConditionVariable :: proc(ConditionVariable: ^CONDITION_VARIABLE) ---
|
WakeConditionVariable :: proc(ConditionVariable: ^CONDITION_VARIABLE) ---
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ PCONDITION_VARIABLE :: ^CONDITION_VARIABLE;
|
|||||||
PLARGE_INTEGER :: ^LARGE_INTEGER;
|
PLARGE_INTEGER :: ^LARGE_INTEGER;
|
||||||
PSRWLOCK :: ^SRWLOCK;
|
PSRWLOCK :: ^SRWLOCK;
|
||||||
|
|
||||||
SOCKET :: distinct rawptr; // TODO
|
SOCKET :: distinct uintptr; // TODO
|
||||||
socklen_t :: c_int;
|
socklen_t :: c_int;
|
||||||
ADDRESS_FAMILY :: USHORT;
|
ADDRESS_FAMILY :: USHORT;
|
||||||
|
|
||||||
@@ -147,7 +147,7 @@ WSA_FLAG_NO_HANDLE_INHERIT: DWORD : 0x80;
|
|||||||
WSADESCRIPTION_LEN :: 256;
|
WSADESCRIPTION_LEN :: 256;
|
||||||
WSASYS_STATUS_LEN :: 128;
|
WSASYS_STATUS_LEN :: 128;
|
||||||
WSAPROTOCOL_LEN: DWORD : 255;
|
WSAPROTOCOL_LEN: DWORD : 255;
|
||||||
INVALID_SOCKET :: SOCKET(~uintptr(0));
|
INVALID_SOCKET :: ~SOCKET(0);
|
||||||
|
|
||||||
WSAEACCES: c_int : 10013;
|
WSAEACCES: c_int : 10013;
|
||||||
WSAEINVAL: c_int : 10022;
|
WSAEINVAL: c_int : 10022;
|
||||||
|
|||||||
@@ -95,5 +95,5 @@ terminate :: proc(using thread : ^Thread, exit_code: u32) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
yield :: proc() {
|
yield :: proc() {
|
||||||
win32.Sleep(0);
|
win32.SwitchToThread();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user