diff --git a/core/sync/channel_unix.odin b/core/sync/channel_unix.odin new file mode 100644 index 000000000..6fe84f2d3 --- /dev/null +++ b/core/sync/channel_unix.odin @@ -0,0 +1,20 @@ +// +build linux, darwin +package sync + +import "core:time" + +raw_channel_wait_queue_wait_on :: proc(state: ^uintptr, timeout: time.Duration) { + // stub +} + +raw_channel_wait_queue_signal :: proc(q: ^Raw_Channel_Wait_Queue) { + // stub +} + + +raw_channel_wait_queue_broadcast :: proc(q: ^Raw_Channel_Wait_Queue) { + for x := q^; x != nil; x = x.next { + q^ = x.next; + // stub + } +} diff --git a/core/sync/channel_windows.odin b/core/sync/channel_windows.odin new file mode 100644 index 000000000..fac316300 --- /dev/null +++ b/core/sync/channel_windows.odin @@ -0,0 +1,33 @@ +package sync + +import "intrinsics" +import win32 "core:sys/windows" +import "core:time" + +raw_channel_wait_queue_wait_on :: proc(state: ^uintptr, timeout: time.Duration) { + ms := win32.DWORD(win32.INFINITE); + if max(time.Duration) != SELECT_MAX_TIMEOUT { + ms = win32.DWORD((max(time.duration_nanoseconds(timeout), 0) + 999999)/1000000); + } + + v := intrinsics.atomic_load(state); + for v == 0 { + win32.WaitOnAddress(state, &v, size_of(state^), ms); + v = intrinsics.atomic_load(state); + } + intrinsics.atomic_store(state, 0); +} + +raw_channel_wait_queue_signal :: proc(q: ^Raw_Channel_Wait_Queue) { + for x := q; x != nil; x = x.next { + intrinsics.atomic_add(x.state, 1); + win32.WakeByAddressSingle(x.state); + } +} + +raw_channel_wait_queue_broadcast :: proc(q: ^Raw_Channel_Wait_Queue) { + for x := q; x != nil; x = x.next { + intrinsics.atomic_add(x.state, 1); + win32.WakeByAddressAll(x.state); + } +}