Skip to content

Commit 979d0fc

Browse files
authored
[threads][test][js-api] Add tests for wait/notify (#250)
Add JS API tests for Atomics.wait and Atomics.notify on WebAssembly.Memory. - On shared memory: Atomics.notify should return the number of notified waiters, and Atomics.wait should return the appropriate wait status. - On unshared memory: Atomics.notify should return 0, while Atomics.wait should trap (throwing a WebAssembly.RuntimeError).
1 parent f521d7b commit 979d0fc

2 files changed

Lines changed: 95 additions & 0 deletions

File tree

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
// META: global=window,dedicatedworker,jsshell
2+
// META: script=/wasm/jsapi/wasm-module-builder.js
3+
4+
function createModule() {
5+
const builder = new WasmModuleBuilder();
6+
// Import memory instead of creating a local one.
7+
builder.addImportedMemory('env', 'memory', 1, 1, true); // shared
8+
builder.exportMemoryAs('memory');
9+
10+
const kSig_i_iil = makeSig([kWasmI32, kWasmI32, kWasmI64], [kWasmI32]);
11+
builder.addFunction('wait', kSig_i_iil)
12+
.addBody([
13+
kExprLocalGet, 0, kExprLocalGet, 1, kExprLocalGet, 2,
14+
kAtomicPrefix, kExprI32AtomicWait, 2, 0
15+
])
16+
.exportFunc();
17+
18+
builder.addFunction('notify', kSig_i_ii)
19+
.addBody([
20+
kExprLocalGet, 0, kExprLocalGet, 1,
21+
kAtomicPrefix, kExprAtomicNotify, 2, 0
22+
])
23+
.exportFunc();
24+
25+
return builder.toModule();
26+
}
27+
28+
function createInstance(module, memory) {
29+
if (!memory) {
30+
memory = new WebAssembly.Memory({initial: 1, maximum: 1, shared: true});
31+
}
32+
return new WebAssembly.Instance(module, {env: {memory: memory}});
33+
}
34+
35+
const module = createModule();
36+
37+
test(() => {
38+
const instance = createInstance(module);
39+
const buffer = new Int32Array(instance.exports.memory.buffer);
40+
buffer[0] = 0;
41+
42+
const result = instance.exports.wait(0, 1, -1n);
43+
assert_equals(
44+
result, 1, 'Wait32 should return 1 (not-equal) if value doesn\'t match');
45+
}, 'Wait32 (not-equal) on shared memory');
46+
47+
test(() => {
48+
const instance = createInstance(module);
49+
const buffer = new Int32Array(instance.exports.memory.buffer);
50+
buffer[0] = 0;
51+
52+
const result = instance.exports.wait(0, 0, 1000000n); // 1ms timeout
53+
assert_equals(result, 2, 'Wait32 should return 2 (timed-out) after timeout');
54+
}, 'Wait32 (timed-out) on shared memory');
55+
56+
test(() => {
57+
const instance = createInstance(module);
58+
const result = instance.exports.notify(0, 1);
59+
assert_equals(
60+
result, 0, 'Notify should return 0 (number of waiters notified)');
61+
}, 'Notify on shared memory (0 waiters)');
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// META: global=window,dedicatedworker,jsshell
2+
// META: script=/wasm/jsapi/wasm-module-builder.js
3+
4+
test(() => {
5+
const builder = new WasmModuleBuilder();
6+
builder.addMemory(1, 1, false, false);
7+
builder.addFunction('notify', kSig_i_ii)
8+
.addBody([
9+
kExprLocalGet, 0, kExprLocalGet, 1, kAtomicPrefix, kExprAtomicNotify, 2,
10+
0
11+
])
12+
.exportFunc();
13+
const instance = builder.instantiate();
14+
const result = instance.exports.notify(0, 1);
15+
assert_equals(result, 0, 'Notify on unshared memory should return 0');
16+
}, 'Notify on unshared memory');
17+
18+
test(() => {
19+
const builder = new WasmModuleBuilder();
20+
builder.addMemory(1, 1, false, false);
21+
const kSig_i_iil = makeSig([kWasmI32, kWasmI32, kWasmI64], [kWasmI32]);
22+
builder.addFunction('wait', kSig_i_iil)
23+
.addBody([
24+
kExprLocalGet, 0, kExprLocalGet, 1, kExprLocalGet, 2, kAtomicPrefix,
25+
kExprI32AtomicWait, 2, 0
26+
])
27+
.exportFunc();
28+
const instance = builder.instantiate();
29+
// This should trap. We use a non-infinite timeout to avoid hanging if the
30+
// trap is not implemented.
31+
assert_throws_js(
32+
WebAssembly.RuntimeError, () => instance.exports.wait(0, 0, 1000n),
33+
'Wait on unshared memory should trap');
34+
}, 'Wait on unshared memory traps');

0 commit comments

Comments
 (0)