v8/test/mjsunit/typedarray-growablesharedarraybuffer-atomics.js
Marja Hölttä a64bb79987 [rab/gsab] Atomics.*: Support RAB / GSAB
Bug: v8:11111
Change-Id: I3c350dd98b3da995b52c8366876d66b87fc47c28
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3605611
Commit-Queue: Marja Hölttä <marja@chromium.org>
Reviewed-by: Shu-yu Guo <syg@chromium.org>
Reviewed-by: Jakob Kummerow <jkummerow@chromium.org>
Cr-Commit-Position: refs/heads/main@{#80244}
2022-04-28 08:05:18 +00:00

169 lines
5.3 KiB
JavaScript

// Copyright 2022 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: --harmony-rab-gsab --allow-natives-syntax
"use strict";
d8.file.execute('test/mjsunit/typedarray-helpers.js');
(function AtomicsWait() {
const gsab = CreateGrowableSharedArrayBuffer(16, 32);
const i32a = new Int32Array(gsab);
const workerScript = function() {
onmessage = function(msg) {
const i32a = new Int32Array(msg.gsab, msg.offset);
const result = Atomics.wait(i32a, 0, 0, 5000);
postMessage(result);
};
}
const worker = new Worker(workerScript, {type: 'function'});
worker.postMessage({gsab: gsab, offset: 0});
// Spin until the worker is waiting on the futex.
while (%AtomicsNumWaitersForTesting(i32a, 0) != 1) {}
Atomics.notify(i32a, 0, 1);
assertEquals("ok", worker.getMessage());
worker.terminate();
})();
(function AtomicsWaitAfterGrowing() {
// Test that Atomics.wait works on indices that are valid only after growing.
const gsab = CreateGrowableSharedArrayBuffer(4 * 4, 8 * 4);
const i32a = new Int32Array(gsab);
gsab.grow(6 * 4);
const index = 5;
const workerScript = function() {
onmessage = function(msg) {
const i32a = new Int32Array(msg.gsab, msg.offset);
const result = Atomics.wait(i32a, 5, 0, 5000);
postMessage(result);
};
}
const worker = new Worker(workerScript, {type: 'function'});
worker.postMessage({gsab: gsab, offset: 0});
// Spin until the worker is waiting on the futex.
while (%AtomicsNumWaitersForTesting(i32a, index) != 1) {}
Atomics.notify(i32a, index, 1);
assertEquals("ok", worker.getMessage());
worker.terminate();
})();
(function AtomicsWaitAsync() {
for (let ctor of [Int32Array, BigInt64Array, MyBigInt64Array]) {
const gsab = CreateGrowableSharedArrayBuffer(4 * ctor.BYTES_PER_ELEMENT,
8 * ctor.BYTES_PER_ELEMENT);
const lengthTracking = new ctor(gsab, 0);
const initialValue = false; // Can be converted to both Number and BigInt.
const result = Atomics.waitAsync(lengthTracking, 0, initialValue);
let wokeUp = false;
result.value.then(
(value) => { assertEquals("ok", value); wokeUp = true; },
() => { assertUnreachable(); });
assertEquals(true, result.async);
gsab.grow(6 * ctor.BYTES_PER_ELEMENT);
const notifyReturnValue = Atomics.notify(lengthTracking, 0, 1);
assertEquals(1, notifyReturnValue);
function continuation() {
assertTrue(wokeUp);
}
setTimeout(continuation, 0);
}
})();
(function AtomicsWaitAsyncAfterGrowing() {
for (let ctor of [Int32Array, BigInt64Array, MyBigInt64Array]) {
const gsab = CreateGrowableSharedArrayBuffer(4 * ctor.BYTES_PER_ELEMENT,
8 * ctor.BYTES_PER_ELEMENT);
const lengthTracking = new ctor(gsab, 0);
gsab.grow(6 * ctor.BYTES_PER_ELEMENT);
const index = 5;
const initialValue = false; // Can be converted to both Number and BigInt.
const result = Atomics.waitAsync(lengthTracking, index, initialValue);
let wokeUp = false;
result.value.then(
(value) => { assertEquals("ok", value); wokeUp = true; },
() => { assertUnreachable(); });
assertEquals(true, result.async);
const notifyReturnValue = Atomics.notify(lengthTracking, index, 1);
assertEquals(1, notifyReturnValue);
function continuation() {
assertTrue(wokeUp);
}
setTimeout(continuation, 0);
}
})();
(function AtomicsWaitFailWithWrongArrayTypes() {
const gsab = CreateGrowableSharedArrayBuffer(400, 800);
const i8a = new Int8Array(gsab);
const i16a = new Int16Array(gsab);
const ui8a = new Uint8Array(gsab);
const ui8ca = new Uint8ClampedArray(gsab);
const ui16a = new Uint16Array(gsab);
const ui32a = new Uint32Array(gsab);
const f32a = new Float32Array(gsab);
const f64a = new Float64Array(gsab);
const myui8 = new MyUint8Array(gsab);
const bui64 = new BigUint64Array(gsab);
[i8a, i16a, ui8a, ui8ca, ui16a, ui32a, f32a, f64a, myui8, bui64].forEach(
function(ta) {
// Can be converted both to Number and BigInt.
const exampleValue = false;
assertThrows(() => { Atomics.wait(ta, 0, exampleValue); },
TypeError);
assertThrows(() => { Atomics.notify(ta, 0, 1); },
TypeError);
assertThrows(() => { Atomics.waitAsync(ta, 0, exampleValue); },
TypeError);
});
})();
(function TestAtomics() {
for (let ctor of intCtors) {
const gsab = CreateGrowableSharedArrayBuffer(4 * ctor.BYTES_PER_ELEMENT,
8 * ctor.BYTES_PER_ELEMENT);
const lengthTracking = new ctor(gsab, 0);
TestAtomicsOperations(lengthTracking, 0);
AssertAtomicsOperationsThrow(lengthTracking, 4, RangeError);
gsab.grow(6 * ctor.BYTES_PER_ELEMENT);
TestAtomicsOperations(lengthTracking, 4);
}
})();
(function AtomicsFailWithNonIntegerArray() {
const gsab = CreateGrowableSharedArrayBuffer(400, 800);
const ui8ca = new Uint8ClampedArray(gsab);
const f32a = new Float32Array(gsab);
const f64a = new Float64Array(gsab);
const mf32a = new MyFloat32Array(gsab);
[ui8ca, f32a, f64a, mf32a].forEach((ta) => {
AssertAtomicsOperationsThrow(ta, 0, TypeError); });
})();