Atomics: refactor atomicsHelper.js to extend $262.agent.*

This commit is contained in:
Rick Waldron 2018-06-27 11:13:23 -04:00
parent a1ff358a06
commit c29ae8effb
61 changed files with 239 additions and 238 deletions

View File

@ -5,25 +5,35 @@ description: >
Collection of functions used to interact with Atomics.* operations across agent boundaries.
---*/
var helper = helper || {};
/**
* The amount of slack allowed for testing time-related Atomics methods (i.e. wait and wake).
* The absolute value of the difference of the observed time and the expected time must
* be epsilon-close.
*/
var $ATOMICS_MAX_TIME_EPSILON = 100;
$262.agent.MAX_TIME_EPSILON = 100;
/**
*
* @return {String} A report sent from an agent.
*/
function getReport() {
var r;
while ((r = $262.agent.getReport()) == null) {
$262.agent.sleep(10);
}
return r;
{
// This is only necessary because the original
// $262.agent.getReport API was insufficient.
//
// All runtimes currently have their own
// $262.agent.getReport which is wrong, so we
// will pave over it with a corrected version.
//
// Binding $262.agent is necessary to prevent
// breaking SpiderMonkey's $262.agent.getReport
let getReport = $262.agent.getReport.bind($262.agent);
$262.agent.getReport = function() {
var r;
while ((r = getReport()) == null) {
$262.agent.sleep(1);
}
return r;
};
}
/**
* With a given Int32Array, wait until the expected number of agents have reported themselves by
@ -35,14 +45,10 @@ function getReport() {
* @param {Number} index The index of which all agents will report.
* @param {Number} expected The number of agents that are expected to report as active.
*/
function waitUntil(i32a, index, expected) {
$262.agent.waitUntil = function(i32a, index, expected) {
let agents = 0;
while ((agents = Atomics.load(i32a, index)) !== expected) {
/* nothing */
}
assert.sameValue(agents, expected, `'agents' equals the value of 'expected' (${expected})`);
}
helper.getReport = getReport;
helper.waitUntil = waitUntil;
assert.sameValue(agents, expected, `Reporting number of 'agents' equals the value of 'expected' (${expected})`);
};

View File

@ -32,7 +32,7 @@ var isLockFree8;
assert.sameValue(
Atomics.isLockFree(1),
isLockFree1,
'Atomics.isLockFree(1) equals the value of `isLockFree1` (Atomics.isLockFree(1))'
'Atomics.isLockFree(1) equals the value of `isLockFree1` (1)'
);
};
{
@ -47,7 +47,7 @@ var isLockFree8;
assert.sameValue(
Atomics.isLockFree(2),
isLockFree2,
'Atomics.isLockFree(2) equals the value of `isLockFree2` (Atomics.isLockFree(2))'
'Atomics.isLockFree(2) equals the value of `isLockFree2` (2)'
);
};
{
@ -71,7 +71,7 @@ var isLockFree8;
assert.sameValue(
Atomics.isLockFree(8),
isLockFree8,
'Atomics.isLockFree(8) equals the value of `isLockFree8` (Atomics.isLockFree(8))'
'Atomics.isLockFree(8) equals the value of `isLockFree8` (8)'
);
};
@ -86,17 +86,17 @@ var isLockFree8;
assert.sameValue(
Atomics.isLockFree(1),
isLockFree1,
'Later call to Atomics.isLockFree(1) equals the value of `isLockFree1` (Atomics.isLockFree(1))'
'Later call to Atomics.isLockFree(1) equals the value of `isLockFree1` (1)'
);
assert.sameValue(
Atomics.isLockFree(2),
isLockFree2,
'Later call to Atomics.isLockFree(2) equals the value of `isLockFree2` (Atomics.isLockFree(2))'
'Later call to Atomics.isLockFree(2) equals the value of `isLockFree2` (2)'
);
assert.sameValue(
Atomics.isLockFree(8),
isLockFree8,
'Later call to Atomics.isLockFree(8) equals the value of `isLockFree8` (Atomics.isLockFree(8))'
'Later call to Atomics.isLockFree(8) equals the value of `isLockFree8` (8)'
);
// Duplicates behavior created by loop from above

View File

@ -47,18 +47,18 @@ const i64a = new BigInt64Array(
$262.agent.broadcast(i64a.buffer);
$262.agent.sleep(100);
assert.sameValue(getReport(), 'timed-out');
assert.sameValue(getReport(), 'timed-out');
assert.sameValue(getReport(), 'timed-out');
assert.sameValue($262.agent.getReport(), 'timed-out');
assert.sameValue($262.agent.getReport(), 'timed-out');
assert.sameValue($262.agent.getReport(), 'timed-out');
const lapse = getReport();
const lapse = $262.agent.getReport();
assert(
lapse >= 0,
`${lapse} should be greater than, or equal to 0`
);
assert(
lapse <= $ATOMICS_MAX_TIME_EPSILON,
`${lapse} should be less than ${$ATOMICS_MAX_TIME_EPSILON}`
lapse <= $262.agent.MAX_TIME_EPSILON,
`${lapse} should be less than ${$262.agent.MAX_TIME_EPSILON}`
);
assert.sameValue(Atomics.wake(i64a, 0), 0);

View File

@ -44,10 +44,6 @@ $262.agent.start(`
$262.agent.leaving();
`);
assert.sameValue(getReport(), "A timed-out");
assert.sameValue(getReport(), "B not-equal"); // Even with zero timeout
var r;
while ((r = getReport()) != "done") {
assert.sameValue(r, "C not-equal");
}
assert.sameValue($262.agent.getReport(), 'A timed-out');
assert.sameValue($262.agent.getReport(), 'B not-equal');
assert.sameValue($262.agent.getReport(), 'C not-equal');

View File

@ -32,4 +32,4 @@ const i64a = new BigInt64Array(
$262.agent.broadcast(i64a.buffer);
$262.agent.sleep(100);
assert.sameValue(Atomics.wake(i64a, 0), 1);
assert.sameValue(getReport(), 'ok');
assert.sameValue($262.agent.getReport(), 'ok');

View File

@ -23,5 +23,5 @@ const i64a = new BigInt64Array(
$262.agent.broadcast(i64a.buffer);
$262.agent.sleep(10);
assert.sameValue(getReport(), 'timed-out');
assert.sameValue($262.agent.getReport(), 'timed-out');
assert.sameValue(Atomics.wake(i64a, 0), 0);

View File

@ -37,10 +37,10 @@ $262.agent.sleep(10);
// NO OPERATION OCCURS HERE!
const lapse = getReport();
const lapse = $262.agent.getReport();
assert(
lapse >= TIMEOUT,
`${lapse} should be at least ${TIMEOUT}`
);
assert.sameValue(getReport(), 'timed-out');
assert.sameValue($262.agent.getReport(), 'timed-out');
assert.sameValue(Atomics.wake(i64a, 0), 0);

View File

@ -30,12 +30,12 @@ $262.agent.sleep(10);
Atomics.add(i64a, 0, 1);
const lapse = getReport();
const lapse = $262.agent.getReport();
assert(
lapse >= TIMEOUT,
`${lapse} should be at least ${TIMEOUT}`
);
assert.sameValue(getReport(), 'timed-out');
assert.sameValue($262.agent.getReport(), 'timed-out');
assert.sameValue(Atomics.wake(i64a, 0), 0);

View File

@ -29,12 +29,12 @@ $262.agent.sleep(10);
Atomics.and(i64a, 0, 1);
const lapse = getReport();
const lapse = $262.agent.getReport();
assert(
lapse >= TIMEOUT,
`${lapse} should be at least ${TIMEOUT}`
);
assert.sameValue(getReport(), 'timed-out');
assert.sameValue($262.agent.getReport(), 'timed-out');
assert.sameValue(Atomics.wake(i64a, 0), 0);

View File

@ -29,10 +29,10 @@ $262.agent.sleep(10);
Atomics.compareExchange(i64a, 0, 0, 1);
const lapse = getReport();
const lapse = $262.agent.getReport();
assert(
lapse >= TIMEOUT,
`${lapse} should be at least ${TIMEOUT}`
);
assert.sameValue(getReport(), 'timed-out');
assert.sameValue($262.agent.getReport(), 'timed-out');
assert.sameValue(Atomics.wake(i64a, 0), 0);

View File

@ -29,11 +29,11 @@ $262.agent.sleep(10);
Atomics.exchange(i64a, 0, 1);
const lapse = getReport();
const lapse = $262.agent.getReport();
assert(
lapse >= TIMEOUT,
`${lapse} should be at least ${TIMEOUT}`
);
assert.sameValue(getReport(), 'timed-out');
assert.sameValue($262.agent.getReport(), 'timed-out');
assert.sameValue(Atomics.wake(i64a, 0), 0);

View File

@ -29,12 +29,12 @@ $262.agent.sleep(10);
Atomics.or(i64a, 0, 1);
const lapse = getReport();
const lapse = $262.agent.getReport();
assert(
lapse >= TIMEOUT,
`${lapse} should be at least ${TIMEOUT}`
);
assert.sameValue(getReport(), 'timed-out');
assert.sameValue($262.agent.getReport(), 'timed-out');
assert.sameValue(Atomics.wake(i64a, 0), 0);

View File

@ -29,11 +29,11 @@ $262.agent.sleep(10);
Atomics.store(i64a, 0, 0x111111);
const lapse = getReport();
const lapse = $262.agent.getReport();
assert(
lapse >= TIMEOUT,
`${lapse} should be at least ${TIMEOUT}`
);
assert.sameValue(getReport(), 'timed-out');
assert.sameValue($262.agent.getReport(), 'timed-out');
assert.sameValue(Atomics.wake(i64a, 0), 0);

View File

@ -29,10 +29,10 @@ $262.agent.sleep(10);
Atomics.sub(i64a, 0, 1);
const lapse = getReport();
const lapse = $262.agent.getReport();
assert(
lapse >= TIMEOUT,
`${lapse} should be at least ${TIMEOUT}`
);
assert.sameValue(getReport(), 'timed-out');
assert.sameValue($262.agent.getReport(), 'timed-out');
assert.sameValue(Atomics.wake(i64a, 0), 0);

View File

@ -29,12 +29,12 @@ $262.agent.sleep(10);
Atomics.xor(i64a, 0, 1);
const lapse = getReport();
const lapse = $262.agent.getReport();
assert(
lapse >= TIMEOUT,
`${lapse} should be at least ${TIMEOUT}`
);
assert.sameValue(getReport(), 'timed-out');
assert.sameValue($262.agent.getReport(), 'timed-out');
assert.sameValue(Atomics.wake(i64a, 0), 0);

View File

@ -37,6 +37,6 @@ const i64a = new BigInt64Array(
$262.agent.broadcast(i64a.buffer);
$262.agent.sleep(100);
assert.sameValue(getReport(), value.toString());
assert.sameValue(getReport(), 'not-equal');
assert.sameValue($262.agent.getReport(), value.toString());
assert.sameValue($262.agent.getReport(), 'not-equal');

View File

@ -60,8 +60,8 @@ assert.sameValue(Atomics.wake(i64a, 5), 0, 'Atomics.wake(i64a, 5) returns 0');
// Wake index 7, wakes 1
assert.sameValue(Atomics.wake(i64a, 7), 1, 'Atomics.wake(i64a, 7) returns 1');
assert.sameValue(getReport(), 'ok', 'getReport() returns "ok"');
assert.sameValue($262.agent.getReport(), 'ok', '$262.agent.getReport() returns "ok"');
// Wake index 0, wakes 1
assert.sameValue(Atomics.wake(i64a, 0), 1, 'Atomics.wake(i64a, 0) returns 1');
assert.sameValue(getReport(), 'ok', 'getReport() returns "ok"');
assert.sameValue($262.agent.getReport(), 'ok', '$262.agent.getReport() returns "ok"');

View File

@ -61,17 +61,17 @@ $262.agent.broadcast(i64a.buffer);
$262.agent.sleep(100);
// Agents may be started in any order...
const started = [getReport(), getReport(), getReport()];
const started = [$262.agent.getReport(), $262.agent.getReport(), $262.agent.getReport()];
// Agents must wake in the order they waited
assert.sameValue(Atomics.wake(i64a, 1, 1), 1);
assert.sameValue(getReport(), 'ok');
assert.sameValue(getReport(), started[0]);
assert.sameValue($262.agent.getReport(), 'ok');
assert.sameValue($262.agent.getReport(), started[0]);
assert.sameValue(Atomics.wake(i64a, 2, 1), 1);
assert.sameValue(getReport(), 'ok');
assert.sameValue(getReport(), started[1]);
assert.sameValue($262.agent.getReport(), 'ok');
assert.sameValue($262.agent.getReport(), started[1]);
assert.sameValue(Atomics.wake(i64a, 3, 1), 1);
assert.sameValue(getReport(), 'ok');
assert.sameValue(getReport(), started[2]);
assert.sameValue($262.agent.getReport(), 'ok');
assert.sameValue($262.agent.getReport(), started[2]);

View File

@ -45,12 +45,12 @@ $262.agent.sleep(sleeping);
assert.sameValue(Atomics.wake(i64a, 0), 1);
const lapse = getReport();
const lapse = $262.agent.getReport();
assert(
sleeping + lapse < timeout,
`${sleeping + lapse} should be less than ${timeout}`
);
assert.sameValue(getReport(), 'ok');
assert.sameValue($262.agent.getReport(), 'ok');

View File

@ -47,15 +47,15 @@ const i32a = new Int32Array(
$262.agent.broadcast(i32a.buffer);
$262.agent.sleep(100);
assert.sameValue(getReport(), 'timed-out');
assert.sameValue(getReport(), 'timed-out');
assert.sameValue(getReport(), 'timed-out');
assert.sameValue($262.agent.getReport(), 'timed-out');
assert.sameValue($262.agent.getReport(), 'timed-out');
assert.sameValue($262.agent.getReport(), 'timed-out');
var lapse = getReport();
var lapse = $262.agent.getReport();
assert(lapse >= 0, 'timeout should be a min of 0ms');
assert(lapse <= $ATOMICS_MAX_TIME_EPSILON, `timeout should be a max of ${$ATOMICS_MAX_TIME_EPSILON}`);
assert(lapse <= $262.agent.MAX_TIME_EPSILON, `timeout should be a max of ${$262.agent.MAX_TIME_EPSILON}`);
assert.sameValue(Atomics.wake(i32a, 0), 0);

View File

@ -44,10 +44,6 @@ $262.agent.start(`
$262.agent.leaving();
`);
assert.sameValue(getReport(), 'A timed-out');
assert.sameValue(getReport(), 'B not-equal'); // Even with zero timeout
var r;
while ((r = getReport()) != "done") {
assert.sameValue(r, "C not-equal");
}
assert.sameValue($262.agent.getReport(), 'A timed-out');
assert.sameValue($262.agent.getReport(), 'B not-equal');
assert.sameValue($262.agent.getReport(), 'C not-equal');

View File

@ -33,4 +33,4 @@ $262.agent.broadcast(i32a.buffer);
$262.agent.sleep(500); // Ample time
assert.sameValue(Atomics.wake(i32a, 0), 1);
assert.sameValue(getReport(), "ok");
assert.sameValue($262.agent.getReport(), "ok");

View File

@ -24,5 +24,5 @@ const i32a = new Int32Array(
$262.agent.broadcast(i32a.buffer);
$262.agent.sleep(100);
assert.sameValue(getReport(), 'timed-out');
assert.sameValue($262.agent.getReport(), 'timed-out');
assert.sameValue(Atomics.wake(i32a, 0), 0);

View File

@ -30,12 +30,12 @@ $262.agent.sleep(10);
Atomics.add(i32a, 0, 1);
const lapse = getReport();
const lapse = $262.agent.getReport();
assert(
lapse >= TIMEOUT,
`${lapse} should be at least ${TIMEOUT}`
);
assert.sameValue(getReport(), 'timed-out');
assert.sameValue($262.agent.getReport(), 'timed-out');
assert.sameValue(Atomics.wake(i32a, 0), 0);

View File

@ -30,12 +30,12 @@ $262.agent.sleep(10);
Atomics.and(i32a, 0, 1);
const lapse = getReport();
const lapse = $262.agent.getReport();
assert(
lapse >= TIMEOUT,
`${lapse} should be at least ${TIMEOUT}`
);
assert.sameValue(getReport(), 'timed-out');
assert.sameValue($262.agent.getReport(), 'timed-out');
assert.sameValue(Atomics.wake(i32a, 0), 0);

View File

@ -30,10 +30,10 @@ $262.agent.sleep(10);
Atomics.compareExchange(i32a, 0, 0, 1);
const lapse = getReport();
const lapse = $262.agent.getReport();
assert(
lapse >= TIMEOUT,
`${lapse} should be at least ${TIMEOUT}`
);
assert.sameValue(getReport(), 'timed-out');
assert.sameValue($262.agent.getReport(), 'timed-out');
assert.sameValue(Atomics.wake(i32a, 0), 0);

View File

@ -30,11 +30,11 @@ $262.agent.sleep(10);
Atomics.exchange(i32a, 0, 1);
const lapse = getReport();
const lapse = $262.agent.getReport();
assert(
lapse >= TIMEOUT,
`${lapse} should be at least ${TIMEOUT}`
);
assert.sameValue(getReport(), 'timed-out');
assert.sameValue($262.agent.getReport(), 'timed-out');
assert.sameValue(Atomics.wake(i32a, 0), 0);

View File

@ -30,12 +30,12 @@ $262.agent.sleep(10);
Atomics.or(i32a, 0, 1);
const lapse = getReport();
const lapse = $262.agent.getReport();
assert(
lapse >= TIMEOUT,
`${lapse} should be at least ${TIMEOUT}`
);
assert.sameValue(getReport(), 'timed-out');
assert.sameValue($262.agent.getReport(), 'timed-out');
assert.sameValue(Atomics.wake(i32a, 0), 0);

View File

@ -30,11 +30,11 @@ $262.agent.sleep(10);
Atomics.store(i32a, 0, 0x111111);
const lapse = getReport();
const lapse = $262.agent.getReport();
assert(
lapse >= TIMEOUT,
`${lapse} should be at least ${TIMEOUT}`
);
assert.sameValue(getReport(), 'timed-out');
assert.sameValue($262.agent.getReport(), 'timed-out');
assert.sameValue(Atomics.wake(i32a, 0), 0);

View File

@ -30,10 +30,10 @@ $262.agent.sleep(10);
Atomics.sub(i32a, 0, 1);
const lapse = getReport();
const lapse = $262.agent.getReport();
assert(
lapse >= TIMEOUT,
`${lapse} should be at least ${TIMEOUT}`
);
assert.sameValue(getReport(), 'timed-out');
assert.sameValue($262.agent.getReport(), 'timed-out');
assert.sameValue(Atomics.wake(i32a, 0), 0);

View File

@ -30,12 +30,12 @@ $262.agent.sleep(10);
Atomics.xor(i32a, 0, 1);
const lapse = getReport();
const lapse = $262.agent.getReport();
assert(
lapse >= TIMEOUT,
`${lapse} should be at least ${TIMEOUT}`
);
assert.sameValue(getReport(), 'timed-out');
assert.sameValue($262.agent.getReport(), 'timed-out');
assert.sameValue(Atomics.wake(i32a, 0), 0);

View File

@ -47,15 +47,15 @@ const i32a = new Int32Array(
$262.agent.broadcast(i32a.buffer);
$262.agent.sleep(150);
assert.sameValue(getReport(), 'timed-out');
assert.sameValue(getReport(), 'timed-out');
assert.sameValue(getReport(), 'timed-out');
assert.sameValue($262.agent.getReport(), 'timed-out');
assert.sameValue($262.agent.getReport(), 'timed-out');
assert.sameValue($262.agent.getReport(), 'timed-out');
const lapse = getReport();
const lapse = $262.agent.getReport();
assert(lapse >= 0, 'timeout should be a min of 0ms');
assert(lapse <= $ATOMICS_MAX_TIME_EPSILON, 'timeout should be a max of $ATOMICS_MAX_TIME_EPSILON');
assert(lapse <= $262.agent.MAX_TIME_EPSILON, 'timeout should be a max of $262.agent.MAX_TIME_EPSILON');
assert.sameValue(Atomics.wake(i32a, 0), 0);

View File

@ -52,15 +52,15 @@ const i32a = new Int32Array(
$262.agent.broadcast(i32a.buffer);
$262.agent.sleep(150);
assert.sameValue(getReport(), 'timed-out');
assert.sameValue(getReport(), 'timed-out');
assert.sameValue(getReport(), 'timed-out');
assert.sameValue($262.agent.getReport(), 'timed-out');
assert.sameValue($262.agent.getReport(), 'timed-out');
assert.sameValue($262.agent.getReport(), 'timed-out');
var lapse = getReport();
const lapse = $262.agent.getReport();
assert(lapse >= 0, 'timeout should be a min of 0ms');
assert(lapse <= $ATOMICS_MAX_TIME_EPSILON, 'timeout should be a max of $$ATOMICS_MAX_TIME_EPSILON');
assert(lapse <= $262.agent.MAX_TIME_EPSILON, 'timeout should be a max of $$262.agent.MAX_TIME_EPSILON');
assert.sameValue(Atomics.wake(i32a, 0), 0);

View File

@ -54,14 +54,14 @@ const i32a = new Int32Array(
$262.agent.broadcast(i32a.buffer);
$262.agent.sleep(150);
assert.sameValue(getReport(), 'poisonedValueOf');
assert.sameValue(getReport(), 'poisonedToPrimitive');
assert.sameValue($262.agent.getReport(), 'poisonedValueOf');
assert.sameValue($262.agent.getReport(), 'poisonedToPrimitive');
const lapse = getReport();
const lapse = $262.agent.getReport();
assert(lapse >= 0, 'timeout should be a min of 0ms');
assert(lapse <= $ATOMICS_MAX_TIME_EPSILON, 'timeout should be a max of $$ATOMICS_MAX_TIME_EPSILON');
assert(lapse <= $262.agent.MAX_TIME_EPSILON, 'timeout should be a max of $$262.agent.MAX_TIME_EPSILON');
assert.sameValue(Atomics.wake(i32a, 0), 0);

View File

@ -67,13 +67,13 @@ const i32a = new Int32Array(
$262.agent.broadcast(i32a.buffer);
$262.agent.sleep(150);
assert.sameValue(getReport(), 'Symbol("1")');
assert.sameValue(getReport(), 'Symbol("2")');
assert.sameValue($262.agent.getReport(), 'Symbol("1")');
assert.sameValue($262.agent.getReport(), 'Symbol("2")');
const lapse = getReport();
const lapse = $262.agent.getReport();
assert(lapse >= 0, 'timeout should be a min of 0ms');
assert(lapse <= $ATOMICS_MAX_TIME_EPSILON, 'timeout should be a max of $$ATOMICS_MAX_TIME_EPSILON');
assert(lapse <= $262.agent.MAX_TIME_EPSILON, 'timeout should be a max of $$262.agent.MAX_TIME_EPSILON');
assert.sameValue(Atomics.wake(i32a, 0), 0);

View File

@ -41,12 +41,12 @@ const i32a = new Int32Array(
$262.agent.broadcast(i32a.buffer);
$262.agent.sleep(150);
assert.sameValue(getReport(), 'Symbol("1")');
assert.sameValue(getReport(), 'Symbol("2")');
assert.sameValue($262.agent.getReport(), 'Symbol("1")');
assert.sameValue($262.agent.getReport(), 'Symbol("2")');
const lapse = getReport();
const lapse = $262.agent.getReport();
assert(lapse >= 0, 'timeout should be a min of 0ms');
assert(lapse <= $ATOMICS_MAX_TIME_EPSILON, 'timeout should be a max of $$ATOMICS_MAX_TIME_EPSILON');
assert(lapse <= $262.agent.MAX_TIME_EPSILON, 'timeout should be a max of $$262.agent.MAX_TIME_EPSILON');
assert.sameValue(Atomics.wake(i32a, 0), 0);

View File

@ -58,12 +58,12 @@ const i32a = new Int32Array(
$262.agent.broadcast(i32a.buffer);
$262.agent.sleep(150);
assert.sameValue(getReport(), 'Symbol("1")');
assert.sameValue(getReport(), 'Symbol("2")');
assert.sameValue($262.agent.getReport(), 'Symbol("1")');
assert.sameValue($262.agent.getReport(), 'Symbol("2")');
const lapse = getReport();
const lapse = $262.agent.getReport();
assert(lapse >= 0, 'timeout should be a min of 0ms');
assert(lapse <= $ATOMICS_MAX_TIME_EPSILON, 'timeout should be a max of $$ATOMICS_MAX_TIME_EPSILON');
assert(lapse <= $262.agent.MAX_TIME_EPSILON, 'timeout should be a max of $$262.agent.MAX_TIME_EPSILON');
assert.sameValue(Atomics.wake(i32a, 0), 0);

View File

@ -47,15 +47,15 @@ const i32a = new Int32Array(
$262.agent.broadcast(i32a.buffer);
$262.agent.sleep(150);
assert.sameValue(getReport(), 'timed-out');
assert.sameValue(getReport(), 'timed-out');
assert.sameValue(getReport(), 'timed-out');
assert.sameValue($262.agent.getReport(), 'timed-out');
assert.sameValue($262.agent.getReport(), 'timed-out');
assert.sameValue($262.agent.getReport(), 'timed-out');
const lapse = getReport();
const lapse = $262.agent.getReport();
assert(lapse >= 0, 'timeout should be a min of 0ms');
assert(lapse <= $ATOMICS_MAX_TIME_EPSILON, 'timeout should be a max of $$ATOMICS_MAX_TIME_EPSILON');
assert(lapse <= $262.agent.MAX_TIME_EPSILON, 'timeout should be a max of $$262.agent.MAX_TIME_EPSILON');
assert.sameValue(Atomics.wake(i32a, 0), 0);

View File

@ -17,14 +17,17 @@ includes: [atomicsHelper.js]
features: [Atomics, SharedArrayBuffer, TypedArray]
---*/
const NUMAGENT = 2; // Total number of agents started
const WAKEUP = 0; // Index all agents are waiting on
const WAKECOUNT = 2; // Total number of agents to wake up
const WAIT_INDEX = 0; // Index all agents are waiting on
const RUNNING = 1;
const NUMAGENT = 2; // Total number of agents started
const WAKECOUNT = 2; // Total number of agents to wake up
$262.agent.start(`
$262.agent.receiveBroadcast(function(sab) {
var i32a = new Int32Array(sab);
$262.agent.report("A " + Atomics.wait(i32a, 0, 0, undefined)); // undefined => NaN => +Infinity
// undefined => NaN => +Infinity
Atomics.add(i32a, ${RUNNING}, 1);
$262.agent.report("A " + Atomics.wait(i32a, 0, 0, undefined));
$262.agent.leaving();
});
`);
@ -32,7 +35,9 @@ $262.agent.start(`
$262.agent.start(`
$262.agent.receiveBroadcast(function(sab) {
var i32a = new Int32Array(sab);
$262.agent.report("B " + Atomics.wait(i32a, 0, 0)); // undefined timeout arg => NaN => +Infinity
// undefined timeout arg => NaN => +Infinity
Atomics.add(i32a, ${RUNNING}, 1);
$262.agent.report("B " + Atomics.wait(i32a, 0, 0));
$262.agent.leaving();
});
`);
@ -42,18 +47,15 @@ const i32a = new Int32Array(
);
$262.agent.broadcast(i32a.buffer);
$262.agent.sleep(500); // Ample time
$262.agent.waitUntil(i32a, RUNNING, NUMAGENT);
// No Reports made before wait
assert.sameValue(getReport(), null);
assert.sameValue(Atomics.wake(i32a, WAIT_INDEX, WAKECOUNT), WAKECOUNT);
assert.sameValue(Atomics.wake(i32a, WAKEUP, WAKECOUNT), WAKECOUNT);
const sortedReports = [];
const reports = [];
for (var i = 0; i < NUMAGENT; i++) {
sortedReports.push(getReport());
reports.push($262.agent.getReport());
}
sortedReports.sort();
reports.sort();
assert.sameValue(sortedReports[0], 'A ok');
assert.sameValue(sortedReports[1], 'B ok');
assert.sameValue(reports[0], 'A ok');
assert.sameValue(reports[1], 'B ok');

View File

@ -39,4 +39,4 @@ $262.agent.sleep(150);
assert.sameValue(Atomics.wake(i32a, 0), 1); // wake at index 0
assert.sameValue(Atomics.wake(i32a, 0), 0); // wake again at index 0, and 0 agents should be woken
assert.sameValue(getReport(), 'ok');
assert.sameValue($262.agent.getReport(), 'ok');

View File

@ -36,6 +36,6 @@ const i32a = new Int32Array(
$262.agent.broadcast(i32a.buffer);
$262.agent.sleep(100);
assert.sameValue(getReport(), value.toString());
assert.sameValue(getReport(), 'not-equal');
assert.sameValue($262.agent.getReport(), value.toString());
assert.sameValue($262.agent.getReport(), 'not-equal');

View File

@ -33,6 +33,6 @@ const i32a = new Int32Array(
$262.agent.broadcast(i32a.buffer);
$262.agent.sleep(100);
assert.sameValue(getReport(), 'not-equal');
assert.sameValue(getReport(), 'not-equal');
assert.sameValue($262.agent.getReport(), 'not-equal');
assert.sameValue($262.agent.getReport(), 'not-equal');
assert.sameValue(Atomics.wake(i32a, 0), 0);

View File

@ -56,8 +56,8 @@ assert.sameValue(Atomics.wake(i32a, 3), 0, 'Atomics.wake(i32a, 3) returns 0');
// Wake index 2, wakes 1
assert.sameValue(Atomics.wake(i32a, 2), 1, 'Atomics.wake(i32a, 2) returns 1');
assert.sameValue(getReport(), 'ok', 'getReport() returns "ok"');
assert.sameValue($262.agent.getReport(), 'ok', '$262.agent.getReport() returns "ok"');
// Wake index 0, wakes 1
assert.sameValue(Atomics.wake(i32a, 0), 1, 'Atomics.wake(i32a, 0) returns 1');
assert.sameValue(getReport(), 'ok', 'getReport() returns "ok"');
assert.sameValue($262.agent.getReport(), 'ok', '$262.agent.getReport() returns "ok"');

View File

@ -62,17 +62,17 @@ $262.agent.broadcast(i32a.buffer);
$262.agent.sleep(100);
// Agents may be started in any order...
const started = [getReport(), getReport(), getReport()];
const started = [$262.agent.getReport(), $262.agent.getReport(), $262.agent.getReport()];
// Agents must wake in the order they waited
assert.sameValue(Atomics.wake(i32a, 1, 1), 1);
assert.sameValue(getReport(), 'ok');
assert.sameValue(getReport(), started[0]);
assert.sameValue($262.agent.getReport(), 'ok');
assert.sameValue($262.agent.getReport(), started[0]);
assert.sameValue(Atomics.wake(i32a, 2, 1), 1);
assert.sameValue(getReport(), 'ok');
assert.sameValue(getReport(), started[1]);
assert.sameValue($262.agent.getReport(), 'ok');
assert.sameValue($262.agent.getReport(), started[1]);
assert.sameValue(Atomics.wake(i32a, 3, 1), 1);
assert.sameValue(getReport(), 'ok');
assert.sameValue(getReport(), started[2]);
assert.sameValue($262.agent.getReport(), 'ok');
assert.sameValue($262.agent.getReport(), started[2]);

View File

@ -45,12 +45,12 @@ $262.agent.sleep(sleeping);
assert.sameValue(Atomics.wake(i32a, 0), 1);
const lapse = getReport();
const lapse = $262.agent.getReport();
assert(
sleeping + lapse < timeout,
`${sleeping + lapse} should be less than ${timeout}`
);
assert.sameValue(getReport(), 'ok');
assert.sameValue($262.agent.getReport(), 'ok');

View File

@ -43,7 +43,7 @@ const i64a = new BigInt64Array(
$262.agent.broadcast(i64a.buffer);
// Wait for agents to be running.
waitUntil(i64a, RUNNING, BUFFER_SIZE);
$262.agent.waitUntil(i64a, RUNNING, BUFFER_SIZE);
// Then wait some more to give the agents a fair chance to wait. If we don't,
// we risk sending the wakeup before agents are sleeping, and we hang.
@ -56,14 +56,14 @@ assert.sameValue(
'Atomics.wake(i64a, WAIT_INDEX) equals the value of `NUMAGENT` (3)'
);
var rs = [];
var reports = [];
for (var i = 0; i < NUMAGENT + 1; i++) {
rs.push(getReport());
reports.push($262.agent.getReport());
}
rs.sort();
reports.sort();
for (var i = 0; i < NUMAGENT; i++) {
assert.sameValue(rs[i], 'A ok', 'The value of rs[i] is "A ok"');
assert.sameValue(reports[i], 'A ok', 'The value of reports[i] is "A ok"');
}
assert.sameValue(rs[NUMAGENT], 'B timed-out', 'The value of rs[NUMAGENT] is "B timed-out"');
assert.sameValue(reports[NUMAGENT], 'B timed-out', 'The value of reports[NUMAGENT] is "B timed-out"');

View File

@ -64,7 +64,7 @@ const i32a = new Int32Array(
$262.agent.broadcast(i32a.buffer);
// Wait for agents to be running.
waitUntil(i32a, RUNNING, NUMAGENT);
$262.agent.waitUntil(i32a, RUNNING, NUMAGENT);
assert.sameValue(
Atomics.wake(i32a, WAIT_INDEX /*, count missing */),
@ -72,13 +72,13 @@ assert.sameValue(
'Atomics.wake(i32a, WAIT_INDEX /*, count missing */) equals the value of `NUMAGENT` (4)'
);
const sortedReports = [];
const reports = [];
for (var i = 0; i < NUMAGENT; i++) {
sortedReports.push(getReport());
reports.push($262.agent.getReport());
}
sortedReports.sort();
reports.sort();
assert.sameValue(sortedReports[0], 'A ok', 'The value of sortedReports[0] is "A ok"');
assert.sameValue(sortedReports[1], 'B ok', 'The value of sortedReports[1] is "B ok"');
assert.sameValue(sortedReports[2], 'C ok', 'The value of sortedReports[2] is "C ok"');
assert.sameValue(sortedReports[3], 'D ok', 'The value of sortedReports[3] is "D ok"');
assert.sameValue(reports[0], 'A ok', 'The value of reports[0] is "A ok"');
assert.sameValue(reports[1], 'B ok', 'The value of reports[1] is "B ok"');
assert.sameValue(reports[2], 'C ok', 'The value of reports[2] is "C ok"');
assert.sameValue(reports[3], 'D ok', 'The value of reports[3] is "D ok"');

View File

@ -62,7 +62,7 @@ const i32a = new Int32Array(
$262.agent.broadcast(i32a.buffer);
// Wait for agents to be running.
waitUntil(i32a, RUNNING, NUMAGENT);
$262.agent.waitUntil(i32a, RUNNING, NUMAGENT);
assert.sameValue(
Atomics.wake(i32a, WAIT_INDEX, undefined),
@ -70,13 +70,13 @@ assert.sameValue(
'Atomics.wake(i32a, WAIT_INDEX, undefined) equals the value of `NUMAGENT` (4)'
);
const sortedReports = [];
const reports = [];
for (var i = 0; i < NUMAGENT; i++) {
sortedReports.push(getReport());
reports.push($262.agent.getReport());
}
sortedReports.sort();
reports.sort();
assert.sameValue(sortedReports[0], 'A ok', 'The value of sortedReports[0] is "A ok"');
assert.sameValue(sortedReports[1], 'B ok', 'The value of sortedReports[1] is "B ok"');
assert.sameValue(sortedReports[2], 'C ok', 'The value of sortedReports[2] is "C ok"');
assert.sameValue(sortedReports[3], 'D ok', 'The value of sortedReports[3] is "D ok"');
assert.sameValue(reports[0], 'A ok', 'The value of reports[0] is "A ok"');
assert.sameValue(reports[1], 'B ok', 'The value of reports[1] is "B ok"');
assert.sameValue(reports[2], 'C ok', 'The value of reports[2] is "C ok"');
assert.sameValue(reports[3], 'D ok', 'The value of reports[3] is "D ok"');

View File

@ -24,5 +24,5 @@ const i32a = new Int32Array(
$262.agent.broadcast(i32a.buffer);
$262.agent.sleep(500); // Give the agent a chance to wait
assert.sameValue(Atomics.wake(i32a, 0, -1), 0, 'Atomics.wake(i32a, 0, -1) returns 0'); // Don't actually wake it
assert.sameValue(getReport(), 'timed-out', 'getReport() returns "timed-out"');
assert.sameValue($262.agent.getReport(), 'timed-out', '$262.agent.getReport() returns "timed-out"');

View File

@ -51,7 +51,7 @@ assert.sameValue(
1,
'Atomics.wake(i32a, undefined, 1) returns 1'
);
assert.sameValue(getReport(), 'ok', 'getReport() returns "ok"');
assert.sameValue($262.agent.getReport(), 'ok', '$262.agent.getReport() returns "ok"');
// wake again at index 0, default => 0
@ -60,4 +60,4 @@ assert.sameValue(
1,
'Atomics.wake(i32a /*, default values used */) returns 1'
);
assert.sameValue(getReport(), 'ok', 'getReport() returns "ok"');
assert.sameValue($262.agent.getReport(), 'ok', '$262.agent.getReport() returns "ok"');

View File

@ -44,7 +44,7 @@ const i32a = new Int32Array(
$262.agent.broadcast(i32a.buffer);
// Wait for agents to be running.
waitUntil(i32a, RUNNING, BUFFER_SIZE);
$262.agent.waitUntil(i32a, RUNNING, BUFFER_SIZE);
// Then wait some more to give the agents a fair chance to wait. If we don't,
// we risk sending the wakeup before agents are sleeping, and we hang.
@ -57,13 +57,13 @@ assert.sameValue(
'Atomics.wake(i32a, WAIT_INDEX) equals the value of `NUMAGENT` (3)'
);
const rs = [];
const reports = [];
for (var i = 0; i < NUMAGENT + 1; i++) {
rs.push(getReport());
reports.push($262.agent.getReport());
}
rs.sort();
reports.sort();
for (var i = 0; i < NUMAGENT; i++) {
assert.sameValue(rs[i], "A ok", 'The value of rs[i] is "A ok"');
assert.sameValue(reports[i], "A ok", 'The value of reports[i] is "A ok"');
}
assert.sameValue(rs[NUMAGENT], "B timed-out", 'The value of rs[NUMAGENT] is "B timed-out"');
assert.sameValue(reports[NUMAGENT], "B timed-out", 'The value of reports[NUMAGENT] is "B timed-out"');

View File

@ -43,7 +43,7 @@ const i32a = new Int32Array(
$262.agent.broadcast(i32a.buffer);
// Wait for agents to be running.
waitUntil(i32a, RUNNING, NUMAGENT + 1);
$262.agent.waitUntil(i32a, RUNNING, NUMAGENT + 1);
// Then wait some more to give the agents a fair chance to wait. If we don't,
// we risk sending the wakeup before agents are sleeping, and we hang.
@ -56,13 +56,13 @@ assert.sameValue(
'Atomics.wake(i32a, WAIT_INDEX) equals the value of `NUMAGENT` (3)'
);
const rs = [];
const reports = [];
for (var i = 0; i < NUMAGENT + 1; i++) {
rs.push(getReport());
reports.push($262.agent.getReport());
}
rs.sort();
reports.sort();
for (var i = 0; i < NUMAGENT; i++) {
assert.sameValue(rs[i], 'A ok', 'The value of rs[i] is "A ok"');
assert.sameValue(reports[i], 'A ok', 'The value of reports[i] is "A ok"');
}
assert.sameValue(rs[NUMAGENT], 'B timed-out', 'The value of rs[NUMAGENT] is "B timed-out"');
assert.sameValue(reports[NUMAGENT], 'B timed-out', 'The value of reports[NUMAGENT] is "B timed-out"');

View File

@ -42,7 +42,7 @@ const i32a = new Int32Array(
$262.agent.broadcast(i32a.buffer);
// Wait for agents to be running.
waitUntil(i32a, RUNNING, NUMAGENT);
$262.agent.waitUntil(i32a, RUNNING, NUMAGENT);
// Sleep to allow the agents a fair chance to wait. If we don't,
// we risk sending the wakeup before agents are sleeping, and we hang.
@ -50,13 +50,13 @@ $262.agent.sleep(50);
var waiterlist = [];
assert.sameValue(Atomics.store(i32a, SPIN + 0, 1), 1);
waiterlist.push(getReport());
waiterlist.push($262.agent.getReport());
assert.sameValue(Atomics.store(i32a, SPIN + 1, 1), 1);
waiterlist.push(getReport());
waiterlist.push($262.agent.getReport());
assert.sameValue(Atomics.store(i32a, SPIN + 2, 1), 1);
waiterlist.push(getReport());
waiterlist.push($262.agent.getReport());
var notified = [];
assert.sameValue(
@ -64,21 +64,21 @@ assert.sameValue(
1,
`Notification #0: on WAIT_INDEX (0) of i32a must notify 1 waiter.`
);
notified.push(getReport());
notified.push($262.agent.getReport());
assert.sameValue(
Atomics.wake(i32a, WAIT_INDEX, 1),
1,
`Notification #1: on WAIT_INDEX (0) of i32a must notify 1 waiter.`
);
notified.push(getReport());
notified.push($262.agent.getReport());
assert.sameValue(
Atomics.wake(i32a, WAIT_INDEX, 1),
1,
`Notification #2: on WAIT_INDEX (0) of i32a must notify 1 waiter.`
);
notified.push(getReport());
notified.push($262.agent.getReport());
assert.sameValue(
notified.join(''),

View File

@ -43,7 +43,7 @@ for (var attempt = 0; attempt < 10; attempt++) {
$262.agent.broadcast(i32a.buffer);
// Wait for agents to be running.
waitUntil(i32a, RUNNING, NUMAGENT);
$262.agent.waitUntil(i32a, RUNNING, NUMAGENT);
// Sleep to allow the agents a fair chance to wait. If we don't,
// we risk sending the wakeup before agents are sleeping, and we hang.
@ -51,13 +51,13 @@ for (var attempt = 0; attempt < 10; attempt++) {
var waiterlist = [];
assert.sameValue(Atomics.store(i32a, SPIN + 0, 1), 1);
waiterlist.push(getReport());
waiterlist.push($262.agent.getReport());
assert.sameValue(Atomics.store(i32a, SPIN + 1, 1), 1);
waiterlist.push(getReport());
waiterlist.push($262.agent.getReport());
assert.sameValue(Atomics.store(i32a, SPIN + 2, 1), 1);
waiterlist.push(getReport());
waiterlist.push($262.agent.getReport());
var notified = [];
assert.sameValue(
@ -65,21 +65,21 @@ for (var attempt = 0; attempt < 10; attempt++) {
1,
`Attempt #${attempt}, Notification #0: on WAIT_INDEX (0) of i32a must notify 1 waiter.`
);
notified.push(getReport());
notified.push($262.agent.getReport());
assert.sameValue(
Atomics.wake(i32a, WAIT_INDEX, 1),
1,
`Attempt #${attempt}, Notification #1: on WAIT_INDEX (0) of i32a must notify 1 waiter.`
);
notified.push(getReport());
notified.push($262.agent.getReport());
assert.sameValue(
Atomics.wake(i32a, WAIT_INDEX, 1),
1,
`Attempt #${attempt}, Notification #2: on WAIT_INDEX (0) of i32a must notify 1 waiter.`
);
notified.push(getReport());
notified.push($262.agent.getReport());
assert.sameValue(
notified.join(''),

View File

@ -27,4 +27,4 @@ assert.sameValue(Atomics.wake(i32a, 0, NaN), 0, 'Atomics.wake(i32a, 0, NaN) retu
// Sleep past the timeout
$262.agent.sleep(300);
assert.sameValue(getReport(), 'timed-out', 'getReport() returns "timed-out"');
assert.sameValue($262.agent.getReport(), 'timed-out', '$262.agent.getReport() returns "timed-out"');

View File

@ -34,7 +34,7 @@ const i32a = new Int32Array(
$262.agent.broadcast(i32a.buffer);
// Wait for agents to be running.
waitUntil(i32a, RUNNING, NUMAGENT);
$262.agent.waitUntil(i32a, RUNNING, NUMAGENT);
// Then wait some more to give the agents a fair chance to wait. If we don't,
// we risk sending the wakeup before agents are sleeping, and we hang.
@ -50,15 +50,15 @@ assert.sameValue(
);
// Collect and check results
const rs = [];
const reports = [];
for (var i = 0; i < NUMAGENT; i++) {
rs.push(getReport());
reports.push($262.agent.getReport());
}
rs.sort();
reports.sort();
for (var i = 0; i < WAKECOUNT; i++) {
assert.sameValue(rs[i], 'ok', 'The value of rs[i] is "ok"');
assert.sameValue(reports[i], 'ok', 'The value of reports[i] is "ok"');
}
for (var i = WAKECOUNT; i < NUMAGENT; i++) {
assert.sameValue(rs[i], 'timed-out', 'The value of rs[i] is "timed-out"');
assert.sameValue(reports[i], 'timed-out', 'The value of reports[i] is "timed-out"');
}

View File

@ -24,11 +24,11 @@ const i32a = new Int32Array(
$262.agent.broadcast(i32a.buffer);
waitUntil(i32a, 1, 1);
$262.agent.waitUntil(i32a, 1, 1);
assert.sameValue(Atomics.wake(i32a, 0, 1), 1, 'Atomics.wake(i32a, 0, 1) returns 1');
assert.sameValue(getReport(), 'ok', 'The value of `report` is "ok"');
assert.sameValue($262.agent.getReport(), 'ok', 'The value of `report` is "ok"');
// Already awake, this should be a noop
assert.sameValue(Atomics.wake(i32a, 0, 1), 0, 'Atomics.wake(i32a, 0, 1) returns 0');

View File

@ -35,7 +35,7 @@ const i32a = new Int32Array(
$262.agent.broadcast(i32a.buffer);
// Wait for agents to be running.
waitUntil(i32a, RUNNING, NUMAGENT);
$262.agent.waitUntil(i32a, RUNNING, NUMAGENT);
// Then wait some more to give the agents a fair chance to wait. If we don't,
// we risk sending the wakeup before agents are sleeping, and we hang.
@ -54,16 +54,16 @@ assert.sameValue(
$262.agent.sleep(300);
// Collect and check results
var rs = [];
var reports = [];
for (var i = 0; i < NUMAGENT; i++) {
rs.push(getReport());
reports.push($262.agent.getReport());
}
rs.sort();
reports.sort();
for (var i = 0; i < WAKECOUNT; i++) {
assert.sameValue(rs[i], 'ok', 'The value of rs[i] is "ok"');
assert.sameValue(reports[i], 'ok', 'The value of reports[i] is "ok"');
}
for (var i = WAKECOUNT; i < NUMAGENT; i++) {
assert.sameValue(rs[i], 'timed-out', 'The value of rs[i] is "timed-out"');
assert.sameValue(reports[i], 'timed-out', 'The value of reports[i] is "timed-out"');
}

View File

@ -9,11 +9,13 @@ includes: [atomicsHelper.js]
features: [Atomics, SharedArrayBuffer, TypedArray]
---*/
const RUNNING = 1;
$262.agent.start(`
$262.agent.receiveBroadcast(function(sab) {
const i32a = new Int32Array(sab);
Atomics.add(i32a, 1, 1);
Atomics.add(i32a, ${RUNNING}, 1);
// THIS WILL NEVER WAIT.
$262.agent.leaving();
});
`);
@ -23,8 +25,7 @@ const i32a = new Int32Array(
);
$262.agent.broadcast(i32a.buffer);
waitUntil(i32a, 1, 1);
$262.agent.waitUntil(i32a, RUNNING, 1);
// There are ZERO agents waiting to wake...
assert.sameValue(Atomics.wake(i32a, 0, 1), 0, 'Atomics.wake(i32a, 0, 1) returns 0');

View File

@ -4,17 +4,18 @@
/*---
esid: sec-atomics.wake
description: >
Test that Atomics.wake wakes zero waiters if there are no agents that match
its arguments waiting.
Test that Atomics.wake wakes zero waiters if there are no waiters
at the index specified.
includes: [atomicsHelper.js]
features: [Atomics, SharedArrayBuffer, TypedArray]
---*/
const RUNNING = 1;
$262.agent.start(`
$262.agent.receiveBroadcast(function(sab) {
const i32a = new Int32Array(sab);
Atomics.add(i32a, 1, 1);
Atomics.add(i32a, ${RUNNING}, 1);
$262.agent.leaving();
});
`);
@ -24,8 +25,7 @@ const i32a = new Int32Array(
);
$262.agent.broadcast(i32a.buffer);
$262.agent.waitUntil(i32a, RUNNING, 1);
waitUntil(i32a, 1, 1);
// There are ZERO matching agents...
// There are ZERO matching agents waiting on index 1
assert.sameValue(Atomics.wake(i32a, 1, 1), 0, 'Atomics.wake(i32a, 1, 1) returns 0');

View File

@ -34,7 +34,7 @@ const i32a = new Int32Array(
$262.agent.broadcast(i32a.buffer);
// Wait for agents to be running.
waitUntil(i32a, RUNNING, NUMAGENT);
$262.agent.waitUntil(i32a, RUNNING, NUMAGENT);
// There's a slight risk we'll fail to wake the desired count, if the preceding
// sleep() took much longer than anticipated and workers have started timing
@ -49,5 +49,5 @@ assert.sameValue(
$262.agent.sleep(300);
for (var i = 0; i < NUMAGENT; i++) {
assert.sameValue(getReport(), 'timed-out', `Report #${i}: must equal "timed-out"`);
assert.sameValue($262.agent.getReport(), 'timed-out', `Report #${i}: must equal "timed-out"`);
}