aboutsummaryrefslogtreecommitdiff
path: root/core/sync/futex_wasm.odin
blob: de88e8198a199611a20455f9695950c767c9b270 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
//+private
//+build wasm32, wasm64p32
package sync

import "base:intrinsics"
import "core:time"

// NOTE: because `core:sync` is in the dependency chain of a lot of the core packages (mostly through `core:mem`)
// without actually calling into it much, I opted for a runtime panic instead of a compile error here.

_futex_wait :: proc "contextless" (f: ^Futex, expected: u32) -> bool {
	when !intrinsics.has_target_feature("atomics") {
		_panic("usage of `core:sync` requires the `-target-feature:\"atomics\"` or a `-microarch` that supports it")
	} else {
		s := intrinsics.wasm_memory_atomic_wait32((^u32)(f), expected, -1)
		return s != 0
	}
}

_futex_wait_with_timeout :: proc "contextless" (f: ^Futex, expected: u32, duration: time.Duration) -> bool {
	when !intrinsics.has_target_feature("atomics") {
		_panic("usage of `core:sync` requires the `-target-feature:\"atomics\"` or a `-microarch` that supports it")
	} else {
		s := intrinsics.wasm_memory_atomic_wait32((^u32)(f), expected, i64(duration))
		return s != 0
	}
}

_futex_signal :: proc "contextless" (f: ^Futex) {
	when !intrinsics.has_target_feature("atomics") {
		_panic("usage of `core:sync` requires the `-target-feature:\"atomics\"` or a `-microarch` that supports it")
	} else {
		loop: for {
			s := intrinsics.wasm_memory_atomic_notify32((^u32)(f), 1)
			if s >= 1 {
				return
			}
		}
	}
}

_futex_broadcast :: proc "contextless" (f: ^Futex) {
	when !intrinsics.has_target_feature("atomics") {
		_panic("usage of `core:sync` requires the `-target-feature:\"atomics\"` or a `-microarch` that supports it")
	} else {
		loop: for {
			s := intrinsics.wasm_memory_atomic_notify32((^u32)(f), ~u32(0))
			if s >= 0 {
				return
			}
		}
	}
}