Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2003)

Unified Diff: mojo/edk/util/waitable_event.cc

Issue 1408003013: Reland "EDK: Move //mojo/edk/system/waitable_event* to edk/util." (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « mojo/edk/util/waitable_event.h ('k') | mojo/edk/util/waitable_event_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: mojo/edk/util/waitable_event.cc
diff --git a/mojo/edk/system/waitable_event.cc b/mojo/edk/util/waitable_event.cc
similarity index 59%
rename from mojo/edk/system/waitable_event.cc
rename to mojo/edk/util/waitable_event.cc
index c05d038e0e45e49d1980da91a41fabf17388a614..c4b345355a0c334803187b3da1d0c38d9d36361a 100644
--- a/mojo/edk/system/waitable_event.cc
+++ b/mojo/edk/util/waitable_event.cc
@@ -2,20 +2,71 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "mojo/edk/system/waitable_event.h"
+#include "mojo/edk/util/waitable_event.h"
-#include "base/logging.h"
-#include "base/time/time.h"
+#include "build/build_config.h"
+#include "mojo/edk/util/logging_internal.h"
-using mojo::util::CondVar;
-using mojo::util::Mutex;
-using mojo::util::MutexLocker;
+#if defined(OS_MACOSX) || defined(OS_IOS)
+#include <mach/kern_return.h>
+#include <mach/mach_time.h>
+#else
+#include <errno.h>
+#include <time.h>
+#endif // defined(OS_MACOSX) || defined(OS_IOS)
namespace mojo {
-namespace system {
+namespace util {
namespace {
+// Mac OS X/iOS don't have a (useful) |clock_gettime()|.
+// Note: Chromium's |base::TimeTicks::Now()| uses boot time (obtained via
+// |sysctl()| with |CTL_KERN|/|KERN_BOOTTIME|). For our current purposes,
+// monotonic time (which pauses during sleeps) is sufficient. TODO(vtl): If/when
+// we use this for other purposes, maybe we should use boot time (maybe also on
+// POSIX).
+#if defined(OS_MACOSX) || defined(OS_IOS)
+mach_timebase_info_data_t GetMachTimebaseInfo() {
+ mach_timebase_info_data_t timebase_info = {};
+ kern_return_t error = mach_timebase_info(&timebase_info);
+ INTERNAL_DCHECK(error == KERN_SUCCESS);
+ return timebase_info;
+}
+
+// Returns the number of microseconds elapsed since epoch start (according to a
+// monotonic clock).
+uint64_t Now() {
+ const uint64_t kNanosecondsPerMicrosecond = 1000ULL;
+
+ // TODO(vtl): Without magic statics, this is not thread-safe, at least the
+ // first time around (neither is Mac Chromium's |base::TimeTicks::Now()|)!
+ static mach_timebase_info_data_t timebase_info = GetMachTimebaseInfo();
+
+ // |timebase_info| converts absolute time tick units into nanoseconds. By
+ // dividing by 1000 first, we reduce the risk of overflowing (at the cost of a
+ // risk of a slight loss in precision).
+ return mach_absolute_time() / kNanosecondsPerMicrosecond *
+ timebase_info.numer / timebase_info.denom;
+}
+#else
+// Returns the number of microseconds elapsed since epoch start (according to a
+// monotonic clock).
+uint64_t Now() {
+ const uint64_t kMicrosecondsPerSecond = 1000000ULL;
+ const uint64_t kNanosecondsPerMicrosecond = 1000ULL;
+
+ struct timespec now;
+ int error = clock_gettime(CLOCK_MONOTONIC, &now);
+ INTERNAL_DCHECK_WITH_ERRNO(!error, "clock_gettime", errno);
+ INTERNAL_DCHECK(now.tv_sec >= 0);
+ INTERNAL_DCHECK(now.tv_nsec >= 0);
+
+ return static_cast<uint64_t>(now.tv_sec) * kMicrosecondsPerSecond +
+ static_cast<uint64_t>(now.tv_nsec) / kNanosecondsPerMicrosecond;
+}
+#endif // defined(OS_MACOSX) || defined(OS_IOS)
+
// Waits with a timeout on |condition()|. Returns true on timeout, or false if
// |condition()| ever returns true. |condition()| should have no side effects
// (and will always be called with |*mutex| held).
@@ -32,7 +83,7 @@ bool WaitWithTimeoutImpl(Mutex* mutex,
// We may get spurious wakeups.
uint64_t wait_remaining = timeout_microseconds;
- auto start = base::TimeTicks::Now();
+ uint64_t start = Now();
while (true) {
if (cv->WaitWithTimeout(mutex, wait_remaining))
return true; // Definitely timed out.
@@ -42,9 +93,9 @@ bool WaitWithTimeoutImpl(Mutex* mutex,
return false;
// Or the wakeup may have been spurious.
- auto now = base::TimeTicks::Now();
- DCHECK_GE(now, start);
- uint64_t elapsed = static_cast<uint64_t>((now - start).InMicroseconds());
+ uint64_t now = Now();
+ INTERNAL_DCHECK(now >= start);
+ uint64_t elapsed = now - start;
// It's possible that we may have timed out anyway.
if (elapsed >= timeout_microseconds)
return true;
@@ -86,7 +137,7 @@ bool AutoResetWaitableEvent::WaitWithTimeout(uint64_t timeout_microseconds) {
// We may get spurious wakeups.
uint64_t wait_remaining = timeout_microseconds;
- auto start = base::TimeTicks::Now();
+ uint64_t start = Now();
while (true) {
if (cv_.WaitWithTimeout(&mutex_, wait_remaining))
return true; // Definitely timed out.
@@ -96,9 +147,9 @@ bool AutoResetWaitableEvent::WaitWithTimeout(uint64_t timeout_microseconds) {
break;
// Or the wakeup may have been spurious.
- auto now = base::TimeTicks::Now();
- DCHECK_GE(now, start);
- uint64_t elapsed = static_cast<uint64_t>((now - start).InMicroseconds());
+ uint64_t now = Now();
+ INTERNAL_DCHECK(now >= start);
+ uint64_t elapsed = now - start;
// It's possible that we may have timed out anyway.
if (elapsed >= timeout_microseconds)
return true;
@@ -155,7 +206,7 @@ bool ManualResetWaitableEvent::WaitWithTimeout(uint64_t timeout_microseconds) {
// Also check |signaled_| in case we're already signaled.
return signaled_ || signal_id_ != last_signal_id;
}, timeout_microseconds);
- DCHECK(rv || signaled_ || signal_id_ != last_signal_id);
+ INTERNAL_DCHECK(rv || signaled_ || signal_id_ != last_signal_id);
return rv;
}
@@ -164,5 +215,5 @@ bool ManualResetWaitableEvent::IsSignaledForTest() {
return signaled_;
}
-} // namespace system
+} // namespace util
} // namespace mojo
« no previous file with comments | « mojo/edk/util/waitable_event.h ('k') | mojo/edk/util/waitable_event_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698