node/deps/v8/test/mjsunit/wasm/atomic-wait-multi-memory.js
Michaël Zasso 9d7cd9b864
deps: update V8 to 12.8.374.13
PR-URL: https://github.com/nodejs/node/pull/54077
Reviewed-By: Jiawen Geng <technicalcute@gmail.com>
Reviewed-By: Richard Lau <rlau@redhat.com>
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Reviewed-By: Marco Ippolito <marcoippolito54@gmail.com>
2024-08-16 16:03:01 +02:00

120 lines
4.0 KiB
JavaScript

// Copyright 2023 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --experimental-wasm-multi-memory
d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js');
const builder = new WasmModuleBuilder();
const mem0_idx = builder.addImportedMemory('imp', 'mem0', 0, 20, 'shared');
const mem1_idx = builder.addImportedMemory('imp', 'mem1', 0, 20, 'shared');
for (let mem_idx of [mem0_idx, mem1_idx]) {
builder.addFunction(`notify${mem_idx}`, kSig_i_ii)
.addBody([
kExprLocalGet, 0, // -
kExprLocalGet, 1, // -
kAtomicPrefix, kExprAtomicNotify, 0x42, mem_idx, 0 // -
])
.exportFunc();
builder.addFunction(`wait${mem_idx}`, kSig_i_iii)
.addBody([
kExprLocalGet, 0, // -
kExprLocalGet, 1, // -
kExprLocalGet, 2, // -
// Convert to i64 and multiply by 1e6 (ms -> ns).
kExprI64UConvertI32, // -
...wasmI64Const(1e6), // -
kExprI64Mul, // -
kAtomicPrefix, kExprI32AtomicWait, 0x42, mem_idx, 0 // -
])
.exportFunc();
}
const module = builder.toModule();
const mem0 = new WebAssembly.Memory({initial: 1, maximum: 1, shared: true});
const mem1 = new WebAssembly.Memory({initial: 2, maximum: 2, shared: true});
const mem0_value = 0;
const mem1_value = 1;
new Uint32Array(mem1.buffer).fill(mem1_value);
const imports = {
imp: {mem0: mem0, mem1: mem1}
};
const instance = new WebAssembly.Instance(module, imports);
const {notify0, notify1, wait0, wait1} = instance.exports;
const k10Ms = 10;
const k10s = 10000;
(function TestWaitNotEqual() {
print(arguments.callee.name);
assertEquals(kAtomicWaitNotEqual, wait0(0, mem0_value + 1, k10Ms));
assertEquals(kAtomicWaitNotEqual, wait1(0, mem1_value + 1, k10Ms));
})();
(function TestWaitTimeout() {
print(arguments.callee.name);
assertEquals(kAtomicWaitTimedOut, wait0(0, mem0_value, k10Ms));
assertEquals(kAtomicWaitTimedOut, wait1(0, mem1_value, k10Ms));
})();
(function TestWakeUpWorker() {
print(arguments.callee.name);
function workerCode() {
instance = undefined;
onmessage = function({data:msg}) {
if (!instance) {
instance = new WebAssembly.Instance(msg.module, msg.imports);
postMessage('instantiated');
return;
}
if (msg.action === 'wait0' || msg.action === 'wait1') {
let result = instance.exports[msg.action](...msg.arguments);
print(`[worker] ${msg.action} ->: ${result}`);
postMessage(result);
return;
}
postMessage(`Invalid action: ${msg.action}`);
}
}
let worker = new Worker(workerCode, {type: 'function'});
worker.postMessage({module: module, imports: imports});
assertEquals('instantiated', worker.getMessage());
const offset = 48;
for (let [mem_idx, mem_value] of [
[mem0_idx, mem0_value], [mem1_idx, mem1_value]]) {
print(`- memory ${mem_idx}`);
// Test "not equals".
worker.postMessage(
{action: `wait${mem_idx}`, arguments: [offset, mem_value + 1, k10Ms]});
assertEquals(kAtomicWaitNotEqual, worker.getMessage());
// Test "timed out".
worker.postMessage(
{action: `wait${mem_idx}`, arguments: [offset, mem_value, k10Ms]});
assertEquals(kAtomicWaitTimedOut, worker.getMessage());
// Test "ok".
worker.postMessage(
{action: `wait${mem_idx}`, arguments: [offset, mem_value, k10s]});
const started = performance.now();
let notify = mem_idx == 0 ? notify0 : notify1;
let notified;
while ((notified = notify(offset, 1)) === 0) {
const now = performance.now();
if (now - started > k10s) {
throw new Error('Could not notify worker within 10s');
}
}
assertEquals(1, notified);
assertEquals(kAtomicWaitOk, worker.getMessage());
}
worker.terminate();
})();