Commit ad1690d6 authored by binji's avatar binji Committed by Commit bot

[futex] Avoid accumulation errors in futex wait timeout

The code previously used a relative timeout and accumulated wait times to see
if the timeout was exceeded. Now we convert the timeout into an absolute time,
and always compare the current time against that.

BUG=v8:4357
R=machenbach@chromium.org
LOG=n

Review URL: https://codereview.chromium.org/1272733002

Cr-Commit-Position: refs/heads/master@{#30036}
parent cd455055
......@@ -101,18 +101,25 @@ Object* FutexEmulation::Wait(Isolate* isolate,
}
}
base::TimeDelta rel_time_left = rel_timeout;
base::Time start_time = base::Time::NowFromSystemTime();
base::Time timeout_time = start_time + rel_timeout;
wait_list_.Pointer()->AddNode(node);
Object* result;
while (true) {
base::TimeDelta time_to_wait = (use_timeout && rel_time_left < kMaxWaitTime)
? rel_time_left
: kMaxWaitTime;
base::Time current_time = base::Time::NowFromSystemTime();
if (use_timeout && current_time > timeout_time) {
result = Smi::FromInt(Result::kTimedOut);
break;
}
base::TimeDelta time_until_timeout = timeout_time - current_time;
base::TimeDelta time_to_wait =
(use_timeout && time_until_timeout < kMaxWaitTime) ? time_until_timeout
: kMaxWaitTime;
base::Time start_time = base::Time::NowFromSystemTime();
bool wait_for_result = node->cond_.WaitFor(mutex_.Pointer(), time_to_wait);
USE(wait_for_result);
......@@ -121,17 +128,8 @@ Object* FutexEmulation::Wait(Isolate* isolate,
break;
}
// Spurious wakeup or timeout.
base::Time end_time = base::Time::NowFromSystemTime();
base::TimeDelta waited_for = end_time - start_time;
rel_time_left -= waited_for;
if (use_timeout && rel_time_left < base::TimeDelta::FromMicroseconds(0)) {
result = Smi::FromInt(Result::kTimedOut);
break;
}
// Potentially handle interrupts before continuing to wait.
// Spurious wakeup or timeout. Potentially handle interrupts before
// continuing to wait.
Object* interrupt_object = isolate->stack_guard()->HandleInterrupts();
if (interrupt_object->IsException()) {
result = interrupt_object;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment