diff options
author | Michaël Zasso <targos@protonmail.com> | 2019-03-12 09:01:49 +0100 |
---|---|---|
committer | Michaël Zasso <targos@protonmail.com> | 2019-03-14 18:49:21 +0100 |
commit | 7b48713334469818661fe276cf571de9c7899f2d (patch) | |
tree | 4dbda49ac88db76ce09dc330a0cb587e68e139ba /deps/v8/src/futex-emulation.cc | |
parent | 8549ac09b256666cf5275224ec58fab9939ff32e (diff) | |
download | node-new-7b48713334469818661fe276cf571de9c7899f2d.tar.gz |
deps: update V8 to 7.3.492.25
PR-URL: https://github.com/nodejs/node/pull/25852
Reviewed-By: Ujjwal Sharma <usharma1998@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Ali Ijaz Sheikh <ofrobots@google.com>
Diffstat (limited to 'deps/v8/src/futex-emulation.cc')
-rw-r--r-- | deps/v8/src/futex-emulation.cc | 104 |
1 files changed, 67 insertions, 37 deletions
diff --git a/deps/v8/src/futex-emulation.cc b/deps/v8/src/futex-emulation.cc index c1dd523984..1cd856541b 100644 --- a/deps/v8/src/futex-emulation.cc +++ b/deps/v8/src/futex-emulation.cc @@ -27,17 +27,13 @@ base::LazyInstance<FutexWaitList>::type FutexEmulation::wait_list_ = void FutexWaitListNode::NotifyWake() { // Lock the FutexEmulation mutex before notifying. We know that the mutex // will have been unlocked if we are currently waiting on the condition - // variable. - // - // The mutex may also not be locked if the other thread is currently handling - // interrupts, or if FutexEmulation::Wait was just called and the mutex - // hasn't been locked yet. In either of those cases, we set the interrupted - // flag to true, which will be tested after the mutex is re-locked. - base::LockGuard<base::Mutex> lock_guard(FutexEmulation::mutex_.Pointer()); - if (waiting_) { - cond_.NotifyOne(); - interrupted_ = true; - } + // variable. The mutex will not be locked if FutexEmulation::Wait hasn't + // locked it yet. In that case, we set the interrupted_ + // flag to true, which will be tested after the mutex locked by a future wait. + base::MutexGuard lock_guard(FutexEmulation::mutex_.Pointer()); + // if not waiting, this will not have any effect. + cond_.NotifyOne(); + interrupted_ = true; } @@ -80,25 +76,51 @@ void AtomicsWaitWakeHandle::Wake() { // The split lock by itself isn’t an issue, as long as the caller properly // synchronizes this with the closing `AtomicsWaitCallback`. { - base::LockGuard<base::Mutex> lock_guard(FutexEmulation::mutex_.Pointer()); + base::MutexGuard lock_guard(FutexEmulation::mutex_.Pointer()); stopped_ = true; } isolate_->futex_wait_list_node()->NotifyWake(); } -Object* FutexEmulation::Wait(Isolate* isolate, - Handle<JSArrayBuffer> array_buffer, size_t addr, - int32_t value, double rel_timeout_ms) { - DCHECK_LT(addr, array_buffer->byte_length()); +enum WaitReturnValue : int { kOk = 0, kNotEqual = 1, kTimedOut = 2 }; + +Object FutexEmulation::WaitJs(Isolate* isolate, + Handle<JSArrayBuffer> array_buffer, size_t addr, + int32_t value, double rel_timeout_ms) { + Object res = Wait32(isolate, array_buffer, addr, value, rel_timeout_ms); + if (res->IsSmi()) { + int val = Smi::ToInt(res); + switch (val) { + case WaitReturnValue::kOk: + return ReadOnlyRoots(isolate).ok(); + case WaitReturnValue::kNotEqual: + return ReadOnlyRoots(isolate).not_equal(); + case WaitReturnValue::kTimedOut: + return ReadOnlyRoots(isolate).timed_out(); + default: + UNREACHABLE(); + } + } + return res; +} - void* backing_store = array_buffer->backing_store(); - int32_t* p = - reinterpret_cast<int32_t*>(static_cast<int8_t*>(backing_store) + addr); +Object FutexEmulation::Wait32(Isolate* isolate, + Handle<JSArrayBuffer> array_buffer, size_t addr, + int32_t value, double rel_timeout_ms) { + return Wait<int32_t>(isolate, array_buffer, addr, value, rel_timeout_ms); +} - FutexWaitListNode* node = isolate->futex_wait_list_node(); - node->backing_store_ = backing_store; - node->wait_addr_ = addr; - node->waiting_ = true; +Object FutexEmulation::Wait64(Isolate* isolate, + Handle<JSArrayBuffer> array_buffer, size_t addr, + int64_t value, double rel_timeout_ms) { + return Wait<int64_t>(isolate, array_buffer, addr, value, rel_timeout_ms); +} + +template <typename T> +Object FutexEmulation::Wait(Isolate* isolate, + Handle<JSArrayBuffer> array_buffer, size_t addr, + T value, double rel_timeout_ms) { + DCHECK_LT(addr, array_buffer->byte_length()); bool use_timeout = rel_timeout_ms != V8_INFINITY; @@ -125,21 +147,28 @@ Object* FutexEmulation::Wait(Isolate* isolate, addr, value, rel_timeout_ms, &stop_handle); if (isolate->has_scheduled_exception()) { - node->waiting_ = false; return isolate->PromoteScheduledException(); } - Object* result; + Object result; AtomicsWaitEvent callback_result = AtomicsWaitEvent::kWokenUp; do { // Not really a loop, just makes it easier to break out early. - base::LockGuard<base::Mutex> lock_guard(mutex_.Pointer()); + base::MutexGuard lock_guard(mutex_.Pointer()); + void* backing_store = array_buffer->backing_store(); + + FutexWaitListNode* node = isolate->futex_wait_list_node(); + node->backing_store_ = backing_store; + node->wait_addr_ = addr; + node->waiting_ = true; + // Reset node->waiting_ = false when leaving this scope (but while // still holding the lock). ResetWaitingOnScopeExit reset_waiting(node); + T* p = reinterpret_cast<T*>(static_cast<int8_t*>(backing_store) + addr); if (*p != value) { - result = ReadOnlyRoots(isolate).not_equal(); + result = Smi::FromInt(WaitReturnValue::kNotEqual); callback_result = AtomicsWaitEvent::kNotEqual; break; } @@ -175,7 +204,7 @@ Object* FutexEmulation::Wait(Isolate* isolate, // notification will wake up the condition variable. node->waiting() will // be false, so we'll loop and then check interrupts. if (interrupted) { - Object* interrupt_object = isolate->stack_guard()->HandleInterrupts(); + Object interrupt_object = isolate->stack_guard()->HandleInterrupts(); if (interrupt_object->IsException(isolate)) { result = interrupt_object; callback_result = AtomicsWaitEvent::kTerminatedExecution; @@ -197,7 +226,7 @@ Object* FutexEmulation::Wait(Isolate* isolate, } if (!node->waiting_) { - result = ReadOnlyRoots(isolate).ok(); + result = Smi::FromInt(WaitReturnValue::kOk); break; } @@ -205,7 +234,7 @@ Object* FutexEmulation::Wait(Isolate* isolate, if (use_timeout) { current_time = base::TimeTicks::Now(); if (current_time >= timeout_time) { - result = ReadOnlyRoots(isolate).timed_out(); + result = Smi::FromInt(WaitReturnValue::kTimedOut); callback_result = AtomicsWaitEvent::kTimedOut; break; } @@ -236,17 +265,18 @@ Object* FutexEmulation::Wait(Isolate* isolate, return result; } -Object* FutexEmulation::Wake(Handle<JSArrayBuffer> array_buffer, size_t addr, - uint32_t num_waiters_to_wake) { +Object FutexEmulation::Wake(Handle<JSArrayBuffer> array_buffer, size_t addr, + uint32_t num_waiters_to_wake) { DCHECK_LT(addr, array_buffer->byte_length()); int waiters_woken = 0; void* backing_store = array_buffer->backing_store(); - base::LockGuard<base::Mutex> lock_guard(mutex_.Pointer()); + base::MutexGuard lock_guard(mutex_.Pointer()); FutexWaitListNode* node = wait_list_.Pointer()->head_; while (node && num_waiters_to_wake > 0) { - if (backing_store == node->backing_store_ && addr == node->wait_addr_) { + if (backing_store == node->backing_store_ && addr == node->wait_addr_ && + node->waiting_) { node->waiting_ = false; node->cond_.NotifyOne(); if (num_waiters_to_wake != kWakeAll) { @@ -261,12 +291,12 @@ Object* FutexEmulation::Wake(Handle<JSArrayBuffer> array_buffer, size_t addr, return Smi::FromInt(waiters_woken); } -Object* FutexEmulation::NumWaitersForTesting(Handle<JSArrayBuffer> array_buffer, - size_t addr) { +Object FutexEmulation::NumWaitersForTesting(Handle<JSArrayBuffer> array_buffer, + size_t addr) { DCHECK_LT(addr, array_buffer->byte_length()); void* backing_store = array_buffer->backing_store(); - base::LockGuard<base::Mutex> lock_guard(mutex_.Pointer()); + base::MutexGuard lock_guard(mutex_.Pointer()); int waiters = 0; FutexWaitListNode* node = wait_list_.Pointer()->head_; |