aboutsummaryrefslogtreecommitdiff
path: root/core/sync/sync_windows.odin
diff options
context:
space:
mode:
authorgingerBill <gingerBill@users.noreply.github.com>2019-12-01 11:33:23 +0000
committerGitHub <noreply@github.com>2019-12-01 11:33:23 +0000
commit3fd5c3cd851d8f4dfd441141ca7e96889f069933 (patch)
tree67f47e79f5c5bb80a3ed1b1e9d79a61c08c0a29d /core/sync/sync_windows.odin
parent0c0c83ee295fe8787a4bdc8b826a5432abba2ca9 (diff)
parent99121d6ff2b02f3d16b791eb103bb9f9e8b96475 (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.odin71
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