diff options
| author | gingerBill <gingerBill@users.noreply.github.com> | 2019-12-01 11:33:23 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-12-01 11:33:23 +0000 |
| commit | 3fd5c3cd851d8f4dfd441141ca7e96889f069933 (patch) | |
| tree | 67f47e79f5c5bb80a3ed1b1e9d79a61c08c0a29d /core/sync/sync_windows.odin | |
| parent | 0c0c83ee295fe8787a4bdc8b826a5432abba2ca9 (diff) | |
| parent | 99121d6ff2b02f3d16b791eb103bb9f9e8b96475 (diff) | |
Merge pull request #458 from Tetralux/linux-threads
Implement core:thread and core:sync on Unix using pthreads
Diffstat (limited to 'core/sync/sync_windows.odin')
| -rw-r--r-- | core/sync/sync_windows.odin | 71 |
1 files changed, 23 insertions, 48 deletions
diff --git a/core/sync/sync_windows.odin b/core/sync/sync_windows.odin index b0a9d944c..a99ac8497 100644 --- a/core/sync/sync_windows.odin +++ b/core/sync/sync_windows.odin @@ -1,51 +1,40 @@ +// +build windows package sync import "core:sys/win32" -foreign { - @(link_name="llvm.x86.sse2.pause") - yield_processor :: proc() --- -} - -Semaphore :: struct { - _handle: win32.Handle, -} - +// A lock that can only be held by one thread at once. Mutex :: struct { _critical_section: win32.Critical_Section, } +// Blocks until signalled. +// When signalled, awakens exactly one waiting thread. Condition :: struct { event: win32.Handle, } -Ticket_Mutex :: struct { - ticket: u64, - serving: u64, +// When waited upon, blocks until the internal count is greater than zero, then subtracts one. +// Posting to the semaphore increases the count by one, or the provided amount. +Semaphore :: struct { + _handle: win32.Handle, } -current_thread_id :: proc() -> i32 { - return i32(win32.get_current_thread_id()); -} - -semaphore_init :: proc(s: ^Semaphore) { - s._handle = win32.create_semaphore_w(nil, 0, 1<<31-1, nil); +semaphore_init :: proc(s: ^Semaphore, initial_count := 0) { + s._handle = win32.create_semaphore_w(nil, i32(initial_count), 1<<31-1, nil); } semaphore_destroy :: proc(s: ^Semaphore) { win32.close_handle(s._handle); } -semaphore_post :: proc(s: ^Semaphore, count: int) { +semaphore_post :: proc(s: ^Semaphore, count := 1) { win32.release_semaphore(s._handle, i32(count), nil); } -semaphore_release :: inline proc(s: ^Semaphore) { - semaphore_post(s, 1); -} - -semaphore_wait :: proc(s: ^Semaphore) { +semaphore_wait_for :: proc(s: ^Semaphore) { + // NOTE(tetra, 2019-10-30): wait_for_single_object decrements the count before it returns. result := win32.wait_for_single_object(s._handle, win32.INFINITE); assert(result != win32.WAIT_FAILED); } @@ -73,39 +62,25 @@ mutex_unlock :: proc(m: ^Mutex) { condition_init :: proc(using c: ^Condition) { + // create an auto-reset event. + // NOTE(tetra, 2019-10-30): this will, when signalled, signal exactly one waiting thread + // and then reset itself automatically. event = win32.create_event_w(nil, false, false, nil); assert(event != nil); } -condition_signal :: proc(using c: ^Condition) { - ok := win32.set_event(event); - assert(bool(ok)); -} - -condition_wait_for :: proc(using c: ^Condition) { - result := win32.wait_for_single_object(event, win32.INFINITE); - assert(result != win32.WAIT_FAILED); -} - condition_destroy :: proc(using c: ^Condition) { if event != nil { win32.close_handle(event); } } - -ticket_mutex_init :: proc(m: ^Ticket_Mutex) { - atomic_store(&m.ticket, 0, Ordering.Relaxed); - atomic_store(&m.serving, 0, Ordering.Relaxed); -} - -ticket_mutex_lock :: inline proc(m: ^Ticket_Mutex) { - ticket := atomic_add(&m.ticket, 1, Ordering.Relaxed); - for ticket != m.serving { - yield_processor(); - } +condition_signal :: proc(using c: ^Condition) { + ok := win32.set_event(event); + assert(bool(ok)); } -ticket_mutex_unlock :: inline proc(m: ^Ticket_Mutex) { - atomic_add(&m.serving, 1, Ordering.Relaxed); -} +condition_wait_for :: proc(using c: ^Condition) { + result := win32.wait_for_single_object(event, win32.INFINITE); + assert(result != win32.WAIT_FAILED); +}
\ No newline at end of file |