From: binji Date: Wed, 5 Aug 2015 20:58:06 +0000 (-0700) Subject: [futex] Avoid accumulation errors in futex wait timeout X-Git-Tag: upstream/4.7.83~1004 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=ad1690d686575baadf8aa0fa820b0438e1a4b9a4;p=platform%2Fupstream%2Fv8.git [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} --- diff --git a/src/futex-emulation.cc b/src/futex-emulation.cc index b8168a8..39f43dd 100644 --- a/src/futex-emulation.cc +++ b/src/futex-emulation.cc @@ -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;