[SAB] Fix flake in Atomics.wait, part II
Refs: https://ci.chromium.org/buildbot/client.v8/V8%20Linux64%20TSAN/21047 Bug: v8:7836 Change-Id: Ic825065de419bbab97972d9b7a2beb6527b0a48a Reviewed-on: https://chromium-review.googlesource.com/1103560 Commit-Queue: Ben Smith <binji@chromium.org> Reviewed-by: Ben Smith <binji@chromium.org> Cr-Commit-Position: refs/heads/master@{#53810}
This commit is contained in:
parent
71892ad96c
commit
e980d0e860
@ -74,7 +74,14 @@ void FutexWaitList::RemoveNode(FutexWaitListNode* node) {
|
||||
}
|
||||
|
||||
void AtomicsWaitWakeHandle::Wake() {
|
||||
stopped_ = true;
|
||||
// Adding a separate `NotifyWake()` variant that doesn't acquire the lock
|
||||
// itself would likely just add unnecessary complexity..
|
||||
// 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());
|
||||
stopped_ = true;
|
||||
}
|
||||
isolate_->futex_wait_list_node()->NotifyWake();
|
||||
}
|
||||
|
||||
@ -126,6 +133,9 @@ Object* FutexEmulation::Wait(Isolate* isolate,
|
||||
|
||||
do { // Not really a loop, just makes it easier to break out early.
|
||||
base::LockGuard<base::Mutex> lock_guard(mutex_.Pointer());
|
||||
// Reset node->waiting_ = false when leaving this scope (but while
|
||||
// still holding the lock).
|
||||
ResetWaitingOnScopeExit reset_waiting(node);
|
||||
|
||||
if (*p != value) {
|
||||
result = isolate->heap()->not_equal();
|
||||
@ -214,8 +224,6 @@ Object* FutexEmulation::Wait(Isolate* isolate,
|
||||
wait_list_.Pointer()->RemoveNode(node);
|
||||
} while (0);
|
||||
|
||||
node->waiting_ = false;
|
||||
|
||||
isolate->RunAtomicsWaitCallback(callback_result, array_buffer, addr, value,
|
||||
rel_timeout_ms, nullptr);
|
||||
|
||||
|
@ -62,6 +62,7 @@ class FutexWaitListNode {
|
||||
private:
|
||||
friend class FutexEmulation;
|
||||
friend class FutexWaitList;
|
||||
friend class ResetWaitingOnScopeExit;
|
||||
|
||||
base::ConditionVariable cond_;
|
||||
// prev_ and next_ are protected by FutexEmulation::mutex_.
|
||||
@ -70,7 +71,8 @@ class FutexWaitListNode {
|
||||
void* backing_store_;
|
||||
size_t wait_addr_;
|
||||
// waiting_ and interrupted_ are protected by FutexEmulation::mutex_
|
||||
// if this node is currently contained in FutexEmulation::wait_list_.
|
||||
// if this node is currently contained in FutexEmulation::wait_list_
|
||||
// or an AtomicsWaitWakeHandle has access to it.
|
||||
bool waiting_;
|
||||
bool interrupted_;
|
||||
|
||||
@ -94,6 +96,16 @@ class FutexWaitList {
|
||||
DISALLOW_COPY_AND_ASSIGN(FutexWaitList);
|
||||
};
|
||||
|
||||
class ResetWaitingOnScopeExit {
|
||||
public:
|
||||
explicit ResetWaitingOnScopeExit(FutexWaitListNode* node) : node_(node) {}
|
||||
~ResetWaitingOnScopeExit() { node_->waiting_ = false; }
|
||||
|
||||
private:
|
||||
FutexWaitListNode* node_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(ResetWaitingOnScopeExit);
|
||||
};
|
||||
|
||||
class FutexEmulation : public AllStatic {
|
||||
public:
|
||||
@ -124,6 +136,7 @@ class FutexEmulation : public AllStatic {
|
||||
|
||||
private:
|
||||
friend class FutexWaitListNode;
|
||||
friend class AtomicsWaitWakeHandle;
|
||||
|
||||
// `mutex_` protects the composition of `wait_list_` (i.e. no elements may be
|
||||
// added or removed without holding this mutex), as well as the `waiting_`
|
||||
|
Loading…
Reference in New Issue
Block a user