-
-
Notifications
You must be signed in to change notification settings - Fork 687
Expand file tree
/
Copy pathatomics.ts
More file actions
127 lines (114 loc) · 4.6 KB
/
atomics.ts
File metadata and controls
127 lines (114 loc) · 4.6 KB
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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
import { ArrayBufferView } from "./arraybuffer";
import { E_INDEXOUTOFRANGE } from "./util/error";
export namespace Atomics {
// @ts-ignore: decorator
@inline
export function load<T extends ArrayBufferView>(array: T, index: i32): valueof<T> {
const align = alignof<valueof<T>>();
if (index < 0 || (index << align) >= array.byteLength) throw new RangeError(E_INDEXOUTOFRANGE);
return atomic.load<valueof<T>>(
changetype<usize>(array.buffer) + (index << align) + array.byteOffset
);
}
// @ts-ignore: decorator
@inline
export function store<T extends ArrayBufferView>(array: T, index: i32, value: valueof<T>): void {
const align = alignof<valueof<T>>();
if (index < 0 || (index << align) >= array.byteLength) throw new RangeError(E_INDEXOUTOFRANGE);
atomic.store<valueof<T>>(
changetype<usize>(array.buffer) + (index << align) + array.byteOffset,
value
);
}
// @ts-ignore: decorator
@inline
export function add<T extends ArrayBufferView>(array: T, index: i32, value: valueof<T>): valueof<T> {
const align = alignof<valueof<T>>();
if (index < 0 || (index << align) >= array.byteLength) throw new RangeError(E_INDEXOUTOFRANGE);
return atomic.add<valueof<T>>(
changetype<usize>(array.buffer) + (index << align) + array.byteOffset,
value
);
}
// @ts-ignore: decorator
@inline
export function sub<T extends ArrayBufferView>(array: T, index: i32, value: valueof<T>): valueof<T> {
const align = alignof<valueof<T>>();
if (index < 0 || (index << align) >= array.byteLength) throw new RangeError(E_INDEXOUTOFRANGE);
return atomic.sub<valueof<T>>(
changetype<usize>(array.buffer) + (index << align) + array.byteOffset,
value
);
}
// @ts-ignore: decorator
@inline
export function and<T extends ArrayBufferView>(array: T, index: i32, value: valueof<T>): valueof<T> {
const align = alignof<valueof<T>>();
if (index < 0 || (index << align) >= array.byteLength) throw new RangeError(E_INDEXOUTOFRANGE);
return atomic.and<valueof<T>>(
changetype<usize>(array.buffer) + (index << align) + array.byteOffset,
value
);
}
// @ts-ignore: decorator
@inline
export function or<T extends ArrayBufferView>(array: T, index: i32, value: valueof<T>): valueof<T> {
const align = alignof<valueof<T>>();
if (index < 0 || (index << align) >= array.byteLength) throw new RangeError(E_INDEXOUTOFRANGE);
return atomic.or<valueof<T>>(
changetype<usize>(array.buffer) + (index << align) + array.byteOffset,
value
);
}
// @ts-ignore: decorator
@inline
export function xor<T extends ArrayBufferView>(array: T, index: i32, value: valueof<T>): valueof<T> {
const align = alignof<valueof<T>>();
if (index < 0 || (index << align) >= array.byteLength) throw new RangeError(E_INDEXOUTOFRANGE);
return atomic.xor<valueof<T>>(
changetype<usize>(array.buffer) + (index << align) + array.byteOffset,
value
);
}
// @ts-ignore: decorator
@inline
export function exchange<T extends ArrayBufferView>(array: T, index: i32, value: valueof<T>): valueof<T> {
const align = alignof<valueof<T>>();
if (index < 0 || (index << align) >= array.byteLength) throw new RangeError(E_INDEXOUTOFRANGE);
return atomic.xchg<valueof<T>>(
changetype<usize>(array.buffer) + (index << align) + array.byteOffset,
value
);
}
// @ts-ignore: decorator
@inline
export function compareExchange<T extends ArrayBufferView>(
array: T,
index: i32,
expectedValue: valueof<T>,
replacementValue: valueof<T>
): valueof<T> {
const align = alignof<valueof<T>>();
if (index < 0 || (index << align) >= array.byteLength) throw new RangeError(E_INDEXOUTOFRANGE);
return atomic.cmpxchg<valueof<T>>(
changetype<usize>(array.buffer) + (index << align) + array.byteOffset,
expectedValue,
replacementValue
);
}
// @ts-ignore: decorator
@inline
export function wait<T extends ArrayBufferView>(array: T, value: valueof<T>, timeout: i64 = -1): AtomicWaitResult {
return atomic.wait<valueof<T>>(changetype<usize>(array.buffer) + array.byteOffset, value, timeout);
}
// @ts-ignore: decorator
@inline
export function notify<T extends ArrayBufferView>(array: T, index: i32, count: i32 = -1): i32 {
const align = alignof<valueof<T>>();
if (index < 0 || (index << align) >= array.byteLength) throw new RangeError(E_INDEXOUTOFRANGE);
return atomic.notify(changetype<usize>(array.buffer) + (index << align) + array.byteOffset, count);
}
export function isLockFree(size: usize): bool {
return size == 1 || size == 2 || size == 4;
}
}