зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1253351 - count argument of futexWake defaults to +Infinity. r=bbouvier
--HG-- extra : rebase_source : 269248db8d70f6e5c55836129b50fba621c3e7f7
This commit is contained in:
Родитель
b40b83ba87
Коммит
43a06b20d4
|
@ -852,10 +852,14 @@ js::atomics_futexWake(JSContext* cx, unsigned argc, Value* vp)
|
||||||
if (!GetTypedArrayIndex(cx, idxv, view, &offset))
|
if (!GetTypedArrayIndex(cx, idxv, view, &offset))
|
||||||
return false;
|
return false;
|
||||||
double count;
|
double count;
|
||||||
if (!ToInteger(cx, countv, &count))
|
if (countv.isUndefined()) {
|
||||||
return false;
|
count = mozilla::PositiveInfinity<double>();
|
||||||
if (count < 0)
|
} else {
|
||||||
count = 0;
|
if (!ToInteger(cx, countv, &count))
|
||||||
|
return false;
|
||||||
|
if (count < 0.0)
|
||||||
|
count = 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
AutoLockFutexAPI lock;
|
AutoLockFutexAPI lock;
|
||||||
|
|
||||||
|
@ -901,10 +905,14 @@ js::atomics_futexWakeOrRequeue(JSContext* cx, unsigned argc, Value* vp)
|
||||||
if (!GetTypedArrayIndex(cx, idx1v, view, &offset1))
|
if (!GetTypedArrayIndex(cx, idx1v, view, &offset1))
|
||||||
return false;
|
return false;
|
||||||
double count;
|
double count;
|
||||||
if (!ToInteger(cx, countv, &count))
|
if (countv.isUndefined()) {
|
||||||
return false;
|
count = mozilla::PositiveInfinity<double>();
|
||||||
if (count < 0)
|
} else {
|
||||||
count = 0;
|
if (!ToInteger(cx, countv, &count))
|
||||||
|
return false;
|
||||||
|
if (count < 0.0)
|
||||||
|
count = 0.0;
|
||||||
|
}
|
||||||
int32_t value;
|
int32_t value;
|
||||||
if (!ToInt32(cx, valv, &value))
|
if (!ToInt32(cx, valv, &value))
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -61,19 +61,22 @@ assertThrowsInstanceOf(() => setSharedArrayBuffer(() => 37), Error);
|
||||||
|
|
||||||
// Futex test
|
// Futex test
|
||||||
|
|
||||||
|
if (helperThreadCount() === 0) {
|
||||||
|
// Abort if there is no helper thread.
|
||||||
|
reportCompare(true,true);
|
||||||
|
quit();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// Main is sharing the buffer with the worker; the worker is clearing
|
// Main is sharing the buffer with the worker; the worker is clearing
|
||||||
// the buffer.
|
// the buffer.
|
||||||
|
|
||||||
mem[0] = 42;
|
mem[0] = 42;
|
||||||
mem[1] = 37;
|
mem[1] = 37;
|
||||||
mem[2] = DEBUG;
|
mem[2] = DEBUG;
|
||||||
setSharedArrayBuffer(mem.buffer);
|
|
||||||
|
|
||||||
if (helperThreadCount() === 0) {
|
setSharedArrayBuffer(mem.buffer);
|
||||||
// Abort if there is no helper thread.
|
|
||||||
reportCompare(true,true);
|
|
||||||
quit();
|
|
||||||
}
|
|
||||||
|
|
||||||
evalInWorker(`
|
evalInWorker(`
|
||||||
var mem = new Int32Array(getSharedArrayBuffer());
|
var mem = new Int32Array(getSharedArrayBuffer());
|
||||||
|
@ -83,11 +86,11 @@ function dprint(s) {
|
||||||
assertEq(mem[0], 42); // what was written in the main thread
|
assertEq(mem[0], 42); // what was written in the main thread
|
||||||
assertEq(mem[1], 37); // is read in the worker
|
assertEq(mem[1], 37); // is read in the worker
|
||||||
mem[1] = 1337;
|
mem[1] = 1337;
|
||||||
dprint("Sleeping for 3 seconds");
|
dprint("Sleeping for 2 seconds");
|
||||||
sleep(3);
|
sleep(2);
|
||||||
dprint("Waking the main thread now");
|
dprint("Waking the main thread now");
|
||||||
setSharedArrayBuffer(null);
|
setSharedArrayBuffer(null);
|
||||||
Atomics.futexWake(mem, 0, 1);
|
assertEq(Atomics.futexWake(mem, 0, 1), 1); // Can fail spuriously but very unlikely
|
||||||
`);
|
`);
|
||||||
|
|
||||||
var then = Date.now();
|
var then = Date.now();
|
||||||
|
@ -96,12 +99,31 @@ dprint("Woke up as I should have in " + (Date.now() - then)/1000 + "s");
|
||||||
assertEq(mem[1], 1337); // what was written in the worker is read in the main thread
|
assertEq(mem[1], 1337); // what was written in the worker is read in the main thread
|
||||||
assertEq(getSharedArrayBuffer(), null); // The worker's clearing of the mbx is visible
|
assertEq(getSharedArrayBuffer(), null); // The worker's clearing of the mbx is visible
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Test the default argument to futexWake()
|
||||||
|
|
||||||
|
setSharedArrayBuffer(mem.buffer);
|
||||||
|
|
||||||
|
evalInWorker(`
|
||||||
|
var mem = new Int32Array(getSharedArrayBuffer());
|
||||||
|
sleep(2); // Probably long enough to avoid a spurious error next
|
||||||
|
assertEq(Atomics.futexWake(mem, 0), 1); // Last argument to futexWake should default to +Infinity
|
||||||
|
`);
|
||||||
|
|
||||||
|
var then = Date.now();
|
||||||
|
dprint("Main thread waiting on wakeup (2s)");
|
||||||
|
assertEq(Atomics.futexWait(mem, 0, 42), Atomics.OK);
|
||||||
|
dprint("Woke up as I should have in " + (Date.now() - then)/1000 + "s");
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// A tricky case: while in the wait there will be an interrupt, and in
|
// A tricky case: while in the wait there will be an interrupt, and in
|
||||||
// the interrupt handler we will execute a futexWait. This is
|
// the interrupt handler we will execute a futexWait. This is
|
||||||
// explicitly prohibited (for now), so there should be a catchable exception.
|
// explicitly prohibited (for now), so there should be a catchable exception.
|
||||||
|
|
||||||
timeout(2, function () {
|
timeout(2, function () {
|
||||||
dprint("In the interrupt, starting inner wait");
|
dprint("In the interrupt, starting inner wait with timeout 2s");
|
||||||
Atomics.futexWait(mem, 0, 42); // Should throw and propagate all the way out
|
Atomics.futexWait(mem, 0, 42); // Should throw and propagate all the way out
|
||||||
});
|
});
|
||||||
var exn = false;
|
var exn = false;
|
||||||
|
@ -110,13 +132,15 @@ try {
|
||||||
assertEq(Atomics.futexWait(mem, 0, 42, 5000), Atomics.OK);
|
assertEq(Atomics.futexWait(mem, 0, 42, 5000), Atomics.OK);
|
||||||
}
|
}
|
||||||
catch (e) {
|
catch (e) {
|
||||||
dprint("Got the exception!");
|
dprint("Got the timeout exception!");
|
||||||
exn = true;
|
exn = true;
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
timeout(-1);
|
timeout(-1);
|
||||||
}
|
}
|
||||||
assertEq(exn, true);
|
assertEq(exn, true);
|
||||||
dprint("Done");
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
dprint("Done");
|
||||||
reportCompare(true,true);
|
reportCompare(true,true);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче