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 |