| Index: src/platform/condition-variable.cc
|
| diff --git a/src/platform/condition-variable.cc b/src/platform/condition-variable.cc
|
| deleted file mode 100644
|
| index e180acdcb7fe91bf8eb5222734b09e5590110f8a..0000000000000000000000000000000000000000
|
| --- a/src/platform/condition-variable.cc
|
| +++ /dev/null
|
| @@ -1,322 +0,0 @@
|
| -// Copyright 2013 the V8 project authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -
|
| -#include "src/platform/condition-variable.h"
|
| -
|
| -#include <errno.h>
|
| -#include <time.h>
|
| -
|
| -#include "src/platform/time.h"
|
| -
|
| -namespace v8 {
|
| -namespace internal {
|
| -
|
| -#if V8_OS_POSIX
|
| -
|
| -ConditionVariable::ConditionVariable() {
|
| - // TODO(bmeurer): The test for V8_LIBRT_NOT_AVAILABLE is a temporary
|
| - // hack to support cross-compiling Chrome for Android in AOSP. Remove
|
| - // this once AOSP is fixed.
|
| -#if (V8_OS_FREEBSD || V8_OS_NETBSD || V8_OS_OPENBSD || \
|
| - (V8_OS_LINUX && V8_LIBC_GLIBC)) && !V8_LIBRT_NOT_AVAILABLE
|
| - // On Free/Net/OpenBSD and Linux with glibc we can change the time
|
| - // source for pthread_cond_timedwait() to use the monotonic clock.
|
| - pthread_condattr_t attr;
|
| - int result = pthread_condattr_init(&attr);
|
| - ASSERT_EQ(0, result);
|
| - result = pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
|
| - ASSERT_EQ(0, result);
|
| - result = pthread_cond_init(&native_handle_, &attr);
|
| - ASSERT_EQ(0, result);
|
| - result = pthread_condattr_destroy(&attr);
|
| -#else
|
| - int result = pthread_cond_init(&native_handle_, NULL);
|
| -#endif
|
| - ASSERT_EQ(0, result);
|
| - USE(result);
|
| -}
|
| -
|
| -
|
| -ConditionVariable::~ConditionVariable() {
|
| - int result = pthread_cond_destroy(&native_handle_);
|
| - ASSERT_EQ(0, result);
|
| - USE(result);
|
| -}
|
| -
|
| -
|
| -void ConditionVariable::NotifyOne() {
|
| - int result = pthread_cond_signal(&native_handle_);
|
| - ASSERT_EQ(0, result);
|
| - USE(result);
|
| -}
|
| -
|
| -
|
| -void ConditionVariable::NotifyAll() {
|
| - int result = pthread_cond_broadcast(&native_handle_);
|
| - ASSERT_EQ(0, result);
|
| - USE(result);
|
| -}
|
| -
|
| -
|
| -void ConditionVariable::Wait(Mutex* mutex) {
|
| - mutex->AssertHeldAndUnmark();
|
| - int result = pthread_cond_wait(&native_handle_, &mutex->native_handle());
|
| - ASSERT_EQ(0, result);
|
| - USE(result);
|
| - mutex->AssertUnheldAndMark();
|
| -}
|
| -
|
| -
|
| -bool ConditionVariable::WaitFor(Mutex* mutex, const TimeDelta& rel_time) {
|
| - struct timespec ts;
|
| - int result;
|
| - mutex->AssertHeldAndUnmark();
|
| -#if V8_OS_MACOSX
|
| - // Mac OS X provides pthread_cond_timedwait_relative_np(), which does
|
| - // not depend on the real time clock, which is what you really WANT here!
|
| - ts = rel_time.ToTimespec();
|
| - ASSERT_GE(ts.tv_sec, 0);
|
| - ASSERT_GE(ts.tv_nsec, 0);
|
| - result = pthread_cond_timedwait_relative_np(
|
| - &native_handle_, &mutex->native_handle(), &ts);
|
| -#else
|
| - // TODO(bmeurer): The test for V8_LIBRT_NOT_AVAILABLE is a temporary
|
| - // hack to support cross-compiling Chrome for Android in AOSP. Remove
|
| - // this once AOSP is fixed.
|
| -#if (V8_OS_FREEBSD || V8_OS_NETBSD || V8_OS_OPENBSD || \
|
| - (V8_OS_LINUX && V8_LIBC_GLIBC)) && !V8_LIBRT_NOT_AVAILABLE
|
| - // On Free/Net/OpenBSD and Linux with glibc we can change the time
|
| - // source for pthread_cond_timedwait() to use the monotonic clock.
|
| - result = clock_gettime(CLOCK_MONOTONIC, &ts);
|
| - ASSERT_EQ(0, result);
|
| - Time now = Time::FromTimespec(ts);
|
| -#else
|
| - // The timeout argument to pthread_cond_timedwait() is in absolute time.
|
| - Time now = Time::NowFromSystemTime();
|
| -#endif
|
| - Time end_time = now + rel_time;
|
| - ASSERT_GE(end_time, now);
|
| - ts = end_time.ToTimespec();
|
| - result = pthread_cond_timedwait(
|
| - &native_handle_, &mutex->native_handle(), &ts);
|
| -#endif // V8_OS_MACOSX
|
| - mutex->AssertUnheldAndMark();
|
| - if (result == ETIMEDOUT) {
|
| - return false;
|
| - }
|
| - ASSERT_EQ(0, result);
|
| - return true;
|
| -}
|
| -
|
| -#elif V8_OS_WIN
|
| -
|
| -struct ConditionVariable::Event {
|
| - Event() : handle_(::CreateEventA(NULL, true, false, NULL)) {
|
| - ASSERT(handle_ != NULL);
|
| - }
|
| -
|
| - ~Event() {
|
| - BOOL ok = ::CloseHandle(handle_);
|
| - ASSERT(ok);
|
| - USE(ok);
|
| - }
|
| -
|
| - bool WaitFor(DWORD timeout_ms) {
|
| - DWORD result = ::WaitForSingleObject(handle_, timeout_ms);
|
| - if (result == WAIT_OBJECT_0) {
|
| - return true;
|
| - }
|
| - ASSERT(result == WAIT_TIMEOUT);
|
| - return false;
|
| - }
|
| -
|
| - HANDLE handle_;
|
| - Event* next_;
|
| - HANDLE thread_;
|
| - volatile bool notified_;
|
| -};
|
| -
|
| -
|
| -ConditionVariable::NativeHandle::~NativeHandle() {
|
| - ASSERT(waitlist_ == NULL);
|
| -
|
| - while (freelist_ != NULL) {
|
| - Event* event = freelist_;
|
| - freelist_ = event->next_;
|
| - delete event;
|
| - }
|
| -}
|
| -
|
| -
|
| -ConditionVariable::Event* ConditionVariable::NativeHandle::Pre() {
|
| - LockGuard<Mutex> lock_guard(&mutex_);
|
| -
|
| - // Grab an event from the free list or create a new one.
|
| - Event* event = freelist_;
|
| - if (event != NULL) {
|
| - freelist_ = event->next_;
|
| - } else {
|
| - event = new Event;
|
| - }
|
| - event->thread_ = GetCurrentThread();
|
| - event->notified_ = false;
|
| -
|
| -#ifdef DEBUG
|
| - // The event must not be on the wait list.
|
| - for (Event* we = waitlist_; we != NULL; we = we->next_) {
|
| - ASSERT_NE(event, we);
|
| - }
|
| -#endif
|
| -
|
| - // Prepend the event to the wait list.
|
| - event->next_ = waitlist_;
|
| - waitlist_ = event;
|
| -
|
| - return event;
|
| -}
|
| -
|
| -
|
| -void ConditionVariable::NativeHandle::Post(Event* event, bool result) {
|
| - LockGuard<Mutex> lock_guard(&mutex_);
|
| -
|
| - // Remove the event from the wait list.
|
| - for (Event** wep = &waitlist_;; wep = &(*wep)->next_) {
|
| - ASSERT_NE(NULL, *wep);
|
| - if (*wep == event) {
|
| - *wep = event->next_;
|
| - break;
|
| - }
|
| - }
|
| -
|
| -#ifdef DEBUG
|
| - // The event must not be on the free list.
|
| - for (Event* fe = freelist_; fe != NULL; fe = fe->next_) {
|
| - ASSERT_NE(event, fe);
|
| - }
|
| -#endif
|
| -
|
| - // Reset the event.
|
| - BOOL ok = ::ResetEvent(event->handle_);
|
| - ASSERT(ok);
|
| - USE(ok);
|
| -
|
| - // Insert the event into the free list.
|
| - event->next_ = freelist_;
|
| - freelist_ = event;
|
| -
|
| - // Forward signals delivered after the timeout to the next waiting event.
|
| - if (!result && event->notified_ && waitlist_ != NULL) {
|
| - ok = ::SetEvent(waitlist_->handle_);
|
| - ASSERT(ok);
|
| - USE(ok);
|
| - waitlist_->notified_ = true;
|
| - }
|
| -}
|
| -
|
| -
|
| -ConditionVariable::ConditionVariable() {}
|
| -
|
| -
|
| -ConditionVariable::~ConditionVariable() {}
|
| -
|
| -
|
| -void ConditionVariable::NotifyOne() {
|
| - // Notify the thread with the highest priority in the waitlist
|
| - // that was not already signalled.
|
| - LockGuard<Mutex> lock_guard(native_handle_.mutex());
|
| - Event* highest_event = NULL;
|
| - int highest_priority = std::numeric_limits<int>::min();
|
| - for (Event* event = native_handle().waitlist();
|
| - event != NULL;
|
| - event = event->next_) {
|
| - if (event->notified_) {
|
| - continue;
|
| - }
|
| - int priority = GetThreadPriority(event->thread_);
|
| - ASSERT_NE(THREAD_PRIORITY_ERROR_RETURN, priority);
|
| - if (priority >= highest_priority) {
|
| - highest_priority = priority;
|
| - highest_event = event;
|
| - }
|
| - }
|
| - if (highest_event != NULL) {
|
| - ASSERT(!highest_event->notified_);
|
| - ::SetEvent(highest_event->handle_);
|
| - highest_event->notified_ = true;
|
| - }
|
| -}
|
| -
|
| -
|
| -void ConditionVariable::NotifyAll() {
|
| - // Notify all threads on the waitlist.
|
| - LockGuard<Mutex> lock_guard(native_handle_.mutex());
|
| - for (Event* event = native_handle().waitlist();
|
| - event != NULL;
|
| - event = event->next_) {
|
| - if (!event->notified_) {
|
| - ::SetEvent(event->handle_);
|
| - event->notified_ = true;
|
| - }
|
| - }
|
| -}
|
| -
|
| -
|
| -void ConditionVariable::Wait(Mutex* mutex) {
|
| - // Create and setup the wait event.
|
| - Event* event = native_handle_.Pre();
|
| -
|
| - // Release the user mutex.
|
| - mutex->Unlock();
|
| -
|
| - // Wait on the wait event.
|
| - while (!event->WaitFor(INFINITE))
|
| - ;
|
| -
|
| - // Reaquire the user mutex.
|
| - mutex->Lock();
|
| -
|
| - // Release the wait event (we must have been notified).
|
| - ASSERT(event->notified_);
|
| - native_handle_.Post(event, true);
|
| -}
|
| -
|
| -
|
| -bool ConditionVariable::WaitFor(Mutex* mutex, const TimeDelta& rel_time) {
|
| - // Create and setup the wait event.
|
| - Event* event = native_handle_.Pre();
|
| -
|
| - // Release the user mutex.
|
| - mutex->Unlock();
|
| -
|
| - // Wait on the wait event.
|
| - TimeTicks now = TimeTicks::Now();
|
| - TimeTicks end = now + rel_time;
|
| - bool result = false;
|
| - while (true) {
|
| - int64_t msec = (end - now).InMilliseconds();
|
| - if (msec >= static_cast<int64_t>(INFINITE)) {
|
| - result = event->WaitFor(INFINITE - 1);
|
| - if (result) {
|
| - break;
|
| - }
|
| - now = TimeTicks::Now();
|
| - } else {
|
| - result = event->WaitFor((msec < 0) ? 0 : static_cast<DWORD>(msec));
|
| - break;
|
| - }
|
| - }
|
| -
|
| - // Reaquire the user mutex.
|
| - mutex->Lock();
|
| -
|
| - // Release the wait event.
|
| - ASSERT(!result || event->notified_);
|
| - native_handle_.Post(event, result);
|
| -
|
| - return result;
|
| -}
|
| -
|
| -#endif // V8_OS_POSIX
|
| -
|
| -} } // namespace v8::internal
|
|
|