author | Lars T Hansen <lhansen@mozilla.com> |
Thu, 31 Mar 2016 15:23:23 -0700 | |
changeset 291450 | 88688664f228ff07d20d623c701a49dac9226f12 |
parent 291449 | fa65591762ba7c70848462228de0fbc2dd61672c |
child 291451 | 859f435f2ca001acc659cf47a2068fc94287e84a |
push id | 30134 |
push user | ryanvm@gmail.com |
push date | Mon, 04 Apr 2016 01:40:30 +0000 |
treeherder | mozilla-central@cfd51e67b26e [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | bbouvier |
bugs | 1259544 |
milestone | 48.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/js/src/builtin/AtomicsObject.cpp +++ b/js/src/builtin/AtomicsObject.cpp @@ -880,134 +880,16 @@ js::atomics_futexWake(JSContext* cx, uns --count; } while (count > 0 && iter != waiters); } r.setInt32(woken); return true; } -bool -js::atomics_futexWakeOrRequeue(JSContext* cx, unsigned argc, Value* vp) -{ - CallArgs args = CallArgsFromVp(argc, vp); - HandleValue objv = args.get(0); - HandleValue idx1v = args.get(1); - HandleValue countv = args.get(2); - HandleValue idx2v = args.get(3); - HandleValue valv = args.get(4); - MutableHandleValue r = args.rval(); - - Rooted<TypedArrayObject*> view(cx, nullptr); - if (!GetSharedTypedArray(cx, objv, &view)) - return false; - if (view->type() != Scalar::Int32) - return ReportBadArrayType(cx); - uint32_t offset1; - if (!GetTypedArrayIndex(cx, idx1v, view, &offset1)) - return false; - double count; - if (countv.isUndefined()) { - count = mozilla::PositiveInfinity<double>(); - } else { - if (!ToInteger(cx, countv, &count)) - return false; - if (count < 0.0) - count = 0.0; - } - int32_t value; - if (!ToInt32(cx, valv, &value)) - return false; - uint32_t offset2; - if (!GetTypedArrayIndex(cx, idx2v, view, &offset2)) - return false; - - AutoLockFutexAPI lock; - - SharedMem<int32_t*> addr = view->viewDataShared().cast<int32_t*>() + offset1; - if (jit::AtomicOperations::loadSafeWhenRacy(addr) != value) { - r.setInt32(AtomicsObject::FutexNotequal); - return true; - } - - Rooted<SharedArrayBufferObject*> sab(cx, view->bufferShared()); - SharedArrayRawBuffer* sarb = sab->rawBufferObject(); - - // Walk the list of waiters looking for those waiting on offset1. - // Wake some and requeue the others. There may already be other - // waiters on offset2, so those that are requeued must be moved to - // the back of the list. Offset1 may equal offset2. The list's - // first node may change, and the list may be emptied out by the - // operation. - - FutexWaiter* waiters = sarb->waiters(); - if (!waiters) { - r.setInt32(0); - return true; - } - - int32_t woken = 0; - FutexWaiter whead((uint32_t)-1, nullptr); // Header node for waiters - FutexWaiter* first = waiters; - FutexWaiter* last = waiters->back; - whead.lower_pri = first; - whead.back = last; - first->back = &whead; - last->lower_pri = &whead; - - FutexWaiter rhead((uint32_t)-1, nullptr); // Header node for requeued - rhead.lower_pri = rhead.back = &rhead; - - FutexWaiter* iter = whead.lower_pri; - while (iter != &whead) { - FutexWaiter* c = iter; - iter = iter->lower_pri; - if (c->offset != offset1 || !c->rt->fx.isWaiting()) - continue; - if (count > 0) { - c->rt->fx.wake(FutexRuntime::WakeExplicit); - ++woken; - --count; - } else { - c->offset = offset2; - - // Remove the node from the waiters list. - c->back->lower_pri = c->lower_pri; - c->lower_pri->back = c->back; - - // Insert the node at the back of the requeuers list. - c->lower_pri = &rhead; - c->back = rhead.back; - rhead.back->lower_pri = c; - rhead.back = c; - } - } - - // If there are any requeuers, append them to the waiters. - if (rhead.lower_pri != &rhead) { - whead.back->lower_pri = rhead.lower_pri; - rhead.lower_pri->back = whead.back; - - whead.back = rhead.back; - rhead.back->lower_pri = &whead; - } - - // Make the final list and install it. - waiters = nullptr; - if (whead.lower_pri != &whead) { - whead.back->lower_pri = whead.lower_pri; - whead.lower_pri->back = whead.back; - waiters = whead.lower_pri; - } - sarb->setWaiters(waiters); - - r.setInt32(woken); - return true; -} - /* static */ bool js::FutexRuntime::initialize() { MOZ_ASSERT(!lock_); lock_ = PR_NewLock(); return lock_ != nullptr; } @@ -1234,17 +1116,16 @@ const JSFunctionSpec AtomicsMethods[] = JS_INLINABLE_FN("add", atomics_add, 3,0, AtomicsAdd), JS_INLINABLE_FN("sub", atomics_sub, 3,0, AtomicsSub), JS_INLINABLE_FN("and", atomics_and, 3,0, AtomicsAnd), JS_INLINABLE_FN("or", atomics_or, 3,0, AtomicsOr), JS_INLINABLE_FN("xor", atomics_xor, 3,0, AtomicsXor), JS_INLINABLE_FN("isLockFree", atomics_isLockFree, 1,0, AtomicsIsLockFree), JS_FN("futexWait", atomics_futexWait, 4,0), JS_FN("futexWake", atomics_futexWake, 3,0), - JS_FN("futexWakeOrRequeue", atomics_futexWakeOrRequeue, 5,0), JS_FS_END }; static const JSConstDoubleSpec AtomicsConstants[] = { {"OK", AtomicsObject::FutexOK}, {"TIMEDOUT", AtomicsObject::FutexTimedout}, {"NOTEQUAL", AtomicsObject::FutexNotequal}, {0, 0}
--- a/js/src/builtin/AtomicsObject.h +++ b/js/src/builtin/AtomicsObject.h @@ -37,17 +37,16 @@ bool atomics_fence(JSContext* cx, unsign bool atomics_add(JSContext* cx, unsigned argc, Value* vp); bool atomics_sub(JSContext* cx, unsigned argc, Value* vp); bool atomics_and(JSContext* cx, unsigned argc, Value* vp); bool atomics_or(JSContext* cx, unsigned argc, Value* vp); bool atomics_xor(JSContext* cx, unsigned argc, Value* vp); bool atomics_isLockFree(JSContext* cx, unsigned argc, Value* vp); bool atomics_futexWait(JSContext* cx, unsigned argc, Value* vp); bool atomics_futexWake(JSContext* cx, unsigned argc, Value* vp); -bool atomics_futexWakeOrRequeue(JSContext* cx, unsigned argc, Value* vp); /* asm.js callouts */ int32_t atomics_add_asm_callout(int32_t vt, int32_t offset, int32_t value); int32_t atomics_sub_asm_callout(int32_t vt, int32_t offset, int32_t value); int32_t atomics_and_asm_callout(int32_t vt, int32_t offset, int32_t value); int32_t atomics_or_asm_callout(int32_t vt, int32_t offset, int32_t value); int32_t atomics_xor_asm_callout(int32_t vt, int32_t offset, int32_t value); int32_t atomics_cmpxchg_asm_callout(int32_t vt, int32_t offset, int32_t oldval, int32_t newval);
--- a/js/src/tests/shell/futex-apis.js +++ b/js/src/tests/shell/futex-apis.js @@ -54,46 +54,43 @@ let sab = new SharedArrayBuffer(16); Date, Math, Atomics ]; for ( let i=0 ; i < values.length ; i++ ) { let view = values[i]; assertThrowsInstanceOf(() => Atomics.futexWait(view, 0, 0), TypeError); assertThrowsInstanceOf(() => Atomics.futexWake(view, 0), TypeError); - assertThrowsInstanceOf(() => Atomics.futexWakeOrRequeue(view, 0, 0, 1, 0), TypeError); } } // Check against TypedArray on non-shared memory cases. { let views = [Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array]; for ( let View of views ) { let view = new View(ab); assertThrowsInstanceOf(() => Atomics.futexWait(view, 0, 0), TypeError); assertThrowsInstanceOf(() => Atomics.futexWake(view, 0), TypeError); - assertThrowsInstanceOf(() => Atomics.futexWakeOrRequeue(view, 0, 0, 1, 0), TypeError); } } // Check against TypedArray on shared memory, but wrong view type { let views = [Int8Array, Uint8Array, Int16Array, Uint16Array, Uint32Array, Uint8ClampedArray, Float32Array, Float64Array]; for ( let View of views ) { let view = new View(sab); assertThrowsInstanceOf(() => Atomics.futexWait(view, 0, 0), TypeError); assertThrowsInstanceOf(() => Atomics.futexWake(view, 0), TypeError); - assertThrowsInstanceOf(() => Atomics.futexWakeOrRequeue(view, 0, 0, 1, 0), TypeError); } } ////////////////////////////////////////////////////////////////////// // // The indices must be in the range of the array { @@ -105,14 +102,12 @@ let sab = new SharedArrayBuffer(16); (view) => undefined, (view) => '3.5', (view) => { password: "qumquat" } ]; for ( let iidx=0 ; iidx < indices.length ; iidx++ ) { let Idx = indices[iidx](view); assertThrowsInstanceOf(() => Atomics.futexWait(view, Idx, 10), RangeError); assertThrowsInstanceOf(() => Atomics.futexWake(view, Idx), RangeError); - assertThrowsInstanceOf(() => Atomics.futexWakeOrRequeue(view, Idx, 5, 0, 0), RangeError); - assertThrowsInstanceOf(() => Atomics.futexWakeOrRequeue(view, 0, 5, Idx, 0), RangeError); } } reportCompare(true,true);