Removed Common

Change-Id: I01ea8f07220375c2ad9bc0092281d4f27c642303
diff --git a/aos/time/BUILD b/aos/time/BUILD
new file mode 100644
index 0000000..cbeeb5b
--- /dev/null
+++ b/aos/time/BUILD
@@ -0,0 +1,33 @@
+package(default_visibility = ["//visibility:public"])
+
+cc_library(
+    name = "time",
+    srcs = [
+        "time.cc",
+    ],
+    hdrs = [
+        "time.h",
+    ],
+    compatible_with = [
+        "//tools:armhf-debian",
+    ],
+    deps = [
+        "//aos:macros",
+        "//aos/mutex:mutex",
+        "//aos/logging",
+        "//aos/linux_code/ipc_lib:shared_mem",
+    ],
+)
+
+cc_test(
+    name = "time_test",
+    srcs = [
+        "time_test.cc",
+    ],
+    deps = [
+        ":time",
+        "//aos/logging",
+        "//aos/util:death_test_log_implementation",
+        "//aos/testing:googletest",
+    ],
+)
diff --git a/aos/time/time.cc b/aos/time/time.cc
new file mode 100644
index 0000000..a72b121
--- /dev/null
+++ b/aos/time/time.cc
@@ -0,0 +1,145 @@
+#include "aos/time/time.h"
+
+#include <inttypes.h>
+#include <string.h>
+
+#include <atomic>
+#include <chrono>
+
+// We only use global_core from here, which is weak, so we don't really have a
+// dependency on it.
+#include "aos/linux_code/ipc_lib/shared_mem.h"
+
+#include "aos/logging/logging.h"
+#include "aos/mutex/mutex.h"
+
+namespace chrono = ::std::chrono;
+
+namespace std {
+namespace this_thread {
+template <>
+void sleep_until(const ::aos::monotonic_clock::time_point &end_time) {
+  struct timespec end_time_timespec;
+  ::std::chrono::seconds sec =
+      ::std::chrono::duration_cast<::std::chrono::seconds>(
+          end_time.time_since_epoch());
+  ::std::chrono::nanoseconds nsec =
+      ::std::chrono::duration_cast<::std::chrono::nanoseconds>(
+          end_time.time_since_epoch() - sec);
+  end_time_timespec.tv_sec = sec.count();
+  end_time_timespec.tv_nsec = nsec.count();
+  int returnval;
+  do {
+    returnval = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME,
+                                &end_time_timespec, nullptr);
+    if (returnval != EINTR && returnval != 0) {
+      PLOG(FATAL, "clock_nanosleep(%jd, TIMER_ABSTIME, %p, nullptr) failed",
+           static_cast<uintmax_t>(CLOCK_MONOTONIC), &end_time_timespec);
+    }
+  } while (returnval != 0);
+}
+
+}  // namespace this_thread
+}  // namespace std
+
+
+namespace aos {
+namespace time {
+
+// State required to enable and use mock time.
+namespace {
+// True if mock time is enabled.
+// This does not need to be checked with the mutex held because setting time to
+// be enabled or disabled is atomic, and all future operations are atomic
+// anyways.  If there is a race condition setting or clearing whether time is
+// enabled or not, it will still be a race condition if current_mock_time is
+// also set atomically with enabled.
+::std::atomic<bool> mock_time_enabled{false};
+// Mutex to make time reads and writes thread safe.
+Mutex time_mutex;
+// Current time when time is mocked.
+monotonic_clock::time_point current_mock_time = monotonic_clock::epoch();
+
+}  // namespace
+
+void EnableMockTime(monotonic_clock::time_point now) {
+  MutexLocker time_mutex_locker(&time_mutex);
+  mock_time_enabled = true;
+  current_mock_time = now;
+}
+
+void UpdateMockTime() { SetMockTime(monotonic_clock::now()); }
+
+void DisableMockTime() {
+  MutexLocker time_mutex_locker(&time_mutex);
+  mock_time_enabled = false;
+}
+
+void SetMockTime(monotonic_clock::time_point now) {
+  MutexLocker time_mutex_locker(&time_mutex);
+  if (__builtin_expect(!mock_time_enabled, 0)) {
+    LOG(FATAL, "Tried to set mock time and mock time is not enabled\n");
+  }
+  current_mock_time = now;
+}
+
+void IncrementMockTime(monotonic_clock::duration amount) {
+  static ::aos::Mutex mutex;
+  ::aos::MutexLocker sync(&mutex);
+  SetMockTime(monotonic_clock::now() + amount);
+}
+
+void OffsetToNow(monotonic_clock::time_point now) {
+  CHECK_NOTNULL(&global_core);
+  CHECK_NOTNULL(global_core);
+  CHECK_NOTNULL(global_core->mem_struct);
+  const auto offset = now - monotonic_clock::now();
+  global_core->mem_struct->time_offset =
+      chrono::duration_cast<chrono::nanoseconds>(offset).count();
+}
+
+struct timespec to_timespec(
+    const ::aos::monotonic_clock::duration duration) {
+  struct timespec time_timespec;
+  ::std::chrono::seconds sec =
+      ::std::chrono::duration_cast<::std::chrono::seconds>(duration);
+  ::std::chrono::nanoseconds nsec =
+      ::std::chrono::duration_cast<::std::chrono::nanoseconds>(duration - sec);
+  time_timespec.tv_sec = sec.count();
+  time_timespec.tv_nsec = nsec.count();
+  return time_timespec;
+}
+
+struct timespec to_timespec(
+    const ::aos::monotonic_clock::time_point time) {
+  return to_timespec(time.time_since_epoch());
+}
+}  // namespace time
+
+constexpr monotonic_clock::time_point monotonic_clock::min_time;
+
+monotonic_clock::time_point monotonic_clock::now() noexcept {
+  {
+    if (time::mock_time_enabled.load(::std::memory_order_relaxed)) {
+      MutexLocker time_mutex_locker(&time::time_mutex);
+      return time::current_mock_time;
+    }
+  }
+
+  struct timespec current_time;
+  if (clock_gettime(CLOCK_MONOTONIC, &current_time) != 0) {
+    PLOG(FATAL, "clock_gettime(%jd, %p) failed",
+         static_cast<uintmax_t>(CLOCK_MONOTONIC), &current_time);
+  }
+  const chrono::nanoseconds offset =
+      (&global_core == nullptr || global_core == nullptr ||
+       global_core->mem_struct == nullptr)
+          ? chrono::nanoseconds(0)
+          : chrono::nanoseconds(global_core->mem_struct->time_offset);
+
+  return time_point(::std::chrono::seconds(current_time.tv_sec) +
+                    ::std::chrono::nanoseconds(current_time.tv_nsec)) + offset;
+}
+
+
+}  // namespace aos
diff --git a/aos/time/time.h b/aos/time/time.h
new file mode 100644
index 0000000..9bef741
--- /dev/null
+++ b/aos/time/time.h
@@ -0,0 +1,102 @@
+#ifndef AOS_TIME_H_
+#define AOS_TIME_H_
+
+#include <stdint.h>
+#include <time.h>
+#include <sys/time.h>
+#include <stdint.h>
+
+#include <type_traits>
+#include <chrono>
+#include <thread>
+#include <ostream>
+
+#include "aos/type_traits/type_traits.h"
+#include "aos/macros.h"
+
+namespace aos {
+
+class monotonic_clock {
+ public:
+  typedef ::std::chrono::nanoseconds::rep rep;
+  typedef ::std::chrono::nanoseconds::period period;
+  typedef ::std::chrono::nanoseconds duration;
+  typedef ::std::chrono::time_point<monotonic_clock> time_point;
+
+  static monotonic_clock::time_point now() noexcept;
+  static constexpr bool is_steady = true;
+
+  // Returns the epoch (0).
+  static constexpr monotonic_clock::time_point epoch() {
+    return time_point(zero());
+  }
+
+  static constexpr monotonic_clock::duration zero() { return duration(0); }
+
+  static constexpr time_point min_time{
+      time_point(duration(::std::numeric_limits<duration::rep>::min()))};
+};
+
+namespace time {
+
+// Enables returning the mock time value for Now instead of checking the system
+// clock.
+void EnableMockTime(monotonic_clock::time_point now);
+// Calls SetMockTime with the current actual time.
+void UpdateMockTime();
+// Sets now when time is being mocked.
+void SetMockTime(monotonic_clock::time_point now);
+// Convenience function to just increment the mock time by a certain amount in
+// a thread safe way.
+void IncrementMockTime(monotonic_clock::duration amount);
+// Disables mocking time.
+void DisableMockTime();
+
+// Sets the global offset for all times so monotonic_clock::now() will return
+// now.
+// There is no synchronization here, so this is only safe when only a single
+// task is running.
+// This is only allowed when the shared memory core infrastructure has been
+// initialized in this process.
+void OffsetToNow(const monotonic_clock::time_point now);
+
+// Construct a time representing the period of hertz.
+constexpr ::std::chrono::nanoseconds FromRate(int hertz) {
+  return ::std::chrono::duration_cast<::std::chrono::nanoseconds>(
+             ::std::chrono::seconds(1)) /
+         hertz;
+}
+
+// RAII class that freezes monotonic_clock::now() (to avoid making large numbers
+// of syscalls to find the real time).
+class TimeFreezer {
+ public:
+  TimeFreezer() { EnableMockTime(monotonic_clock::now()); }
+  ~TimeFreezer() { DisableMockTime(); }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(TimeFreezer);
+};
+
+// Converts a monotonic_clock::duration into a timespec object.
+struct timespec to_timespec(::aos::monotonic_clock::duration duration);
+
+// Converts a monotonic_clock::time_point into a timespec object as time since
+// epoch.
+struct timespec to_timespec(::aos::monotonic_clock::time_point time);
+
+}  // namespace time
+}  // namespace aos
+
+namespace std {
+namespace this_thread {
+// Template specialization for monotonic_clock, since we can use clock_nanosleep
+// with TIMER_ABSTIME and get very precise absolute time sleeps.
+template <>
+void sleep_until(const ::aos::monotonic_clock::time_point &end_time);
+
+}  // namespace this_thread
+}  // namespace std
+
+
+#endif  // AOS_TIME_H_
diff --git a/aos/time/time_test.cc b/aos/time/time_test.cc
new file mode 100644
index 0000000..7b6c1a5
--- /dev/null
+++ b/aos/time/time_test.cc
@@ -0,0 +1,54 @@
+#include "aos/time/time.h"
+
+#include <thread>
+
+#include "gtest/gtest.h"
+
+#include "aos/macros.h"
+#include "aos/util/death_test_log_implementation.h"
+
+namespace aos {
+namespace time {
+namespace testing {
+
+TEST(TimeTest, FromRate) {
+  EXPECT_EQ(::std::chrono::milliseconds(10), FromRate(100));
+}
+
+// Test the monotonic_clock and sleep_until functions.
+TEST(TimeTest, MonotonicClockSleepAndNow) {
+  monotonic_clock::time_point start = monotonic_clock::now();
+  const auto kSleepTime = ::std::chrono::milliseconds(500);
+  ::std::this_thread::sleep_until(start + kSleepTime);
+  monotonic_clock::time_point end = monotonic_clock::now();
+  EXPECT_GE(end - start, kSleepTime);
+  EXPECT_LT(end - start, kSleepTime + ::std::chrono::milliseconds(200));
+}
+
+// Test to_timespec for a duration.
+TEST(TimeTest, DurationToTimespec) {
+  struct timespec pos_time = to_timespec(::std::chrono::milliseconds(56262));
+  EXPECT_EQ(pos_time.tv_sec, 56);
+  EXPECT_EQ(pos_time.tv_nsec, 262000000);
+
+  struct timespec neg_time = to_timespec(::std::chrono::milliseconds(-56262));
+  EXPECT_EQ(neg_time.tv_sec, -56);
+  EXPECT_EQ(neg_time.tv_nsec, -262000000);
+}
+
+// Test to_timespec for a time_point.
+TEST(TimeTest, TimePointToTimespec) {
+  struct timespec pos_time = to_timespec(::aos::monotonic_clock::epoch() +
+                                     ::std::chrono::seconds(1432423));
+  EXPECT_EQ(pos_time.tv_sec, 1432423);
+  EXPECT_EQ(pos_time.tv_nsec, 0);
+
+  struct timespec neg_time = to_timespec(::aos::monotonic_clock::epoch() -
+                                     ::std::chrono::seconds(1432423));
+  EXPECT_EQ(neg_time.tv_sec, -1432423);
+  EXPECT_EQ(neg_time.tv_nsec, 0);
+}
+
+}  // namespace testing
+}  // namespace time
+}  // namespace aos