fixed negative Times
diff --git a/aos/common/time.cc b/aos/common/time.cc
index c4f77a8..28e5cae 100644
--- a/aos/common/time.cc
+++ b/aos/common/time.cc
@@ -32,7 +32,7 @@
 //  That would let me create a MockTime clock source.
 }
 
-void Time::EnableMockTime(const Time now) {
+void Time::EnableMockTime(const Time &now) {
   mock_time_enabled = true;
   MutexLocker time_mutex_locker(&time_mutex);
   current_mock_time = now;
@@ -43,7 +43,7 @@
   mock_time_enabled = false;
 }
 
-void Time::SetMockTime(const Time now) {
+void Time::SetMockTime(const Time &now) {
   MutexLocker time_mutex_locker(&time_mutex);
   if (!mock_time_enabled) {
     LOG(FATAL, "Tried to set mock time and mock time is not enabled\n");
@@ -51,6 +51,12 @@
   current_mock_time = now;
 }
 
+void Time::IncrementMockTime(const Time &amount) {
+  static ::aos::Mutex mutex;
+  ::aos::MutexLocker sync(&mutex);
+  SetMockTime(Now() + amount);
+}
+
 Time Time::Now(clockid_t clock) {
   if (mock_time_enabled) {
     MutexLocker time_mutex_locker(&time_mutex);
@@ -58,9 +64,6 @@
   } else {
     timespec temp;
     if (clock_gettime(clock, &temp) != 0) {
-      // TODO(aschuh): There needs to be a pluggable low level logging interface
-      // so we can break this dependency loop.  This also would help during
-      // startup.
       LOG(FATAL, "clock_gettime(%jd, %p) failed with %d: %s\n",
           static_cast<uintmax_t>(clock), &temp, errno, strerror(errno));
     }
@@ -107,6 +110,10 @@
   sec_ *= rhs;  // better not overflow, or the result is just too big
   nsec_ = temp % kNSecInSec;
   sec_ += (temp - nsec_) / kNSecInSec;
+  if (nsec_ < 0) {
+    nsec_ += kNSecInSec;
+    sec_ -= 1;
+  }
   return *this;
 }
 const Time Time::operator*(int32_t rhs) const {
@@ -115,6 +122,10 @@
 Time &Time::operator/=(int32_t rhs) {
   nsec_ = (sec_ % rhs) * (kNSecInSec / rhs) + nsec_ / rhs;
   sec_ /= rhs;
+  if (nsec_ < 0) {
+    nsec_ += kNSecInSec;
+    sec_ -= 1;
+  }
   return *this;
 }
 const Time Time::operator/(int32_t rhs) const {
@@ -128,6 +139,10 @@
   const int wraps = nsec_ / kNSecInSec;
   sec_ = wraps;
   nsec_ -= kNSecInSec * wraps;
+  if (nsec_ < 0) {
+    nsec_ += kNSecInSec;
+    sec_ -= 1;
+  }
   return *this;
 }
 const Time Time::operator%(int32_t rhs) const {
diff --git a/aos/common/time.h b/aos/common/time.h
index 6c80451..a35065d 100644
--- a/aos/common/time.h
+++ b/aos/common/time.h
@@ -23,16 +23,22 @@
 // 0 <= nsec_ < kNSecInSec should always be true. All functions here will make
 // sure that that is true if it was on all inputs (including *this).
 //
+// Negative times are supported so that all of the normal arithmetic identities
+// work. nsec_ is still always positive.
+//
 // The arithmetic and comparison operators are overloaded because they make
 // complete sense and are very useful. The default copy and assignment stuff is
-// left because it works fine. Multiplication and division of Times by Times are
+// left because it works fine. Multiplication of Times by Times is
 // not implemented because I can't think of any uses for them and there are
-// multiple ways to do it.
+// multiple ways to do it. Division of Times by Times is implemented as the
+// ratio of them. Multiplication, division, and modulus of Times by integers are
+// implemented as interpreting the argument as nanoseconds.
 struct Time {
 #ifdef SWIG
 // All of the uses of constexpr here can safely be simply removed.
 // NOTE: This means that relying on the fact that constexpr implicitly makes
-// member functions const is not safe.
+// member functions const is not valid, so they all have to be explicitly marked
+// const.
 #define constexpr
 #endif  // SWIG
  public:
@@ -83,7 +89,6 @@
   static Time Now(clockid_t clock = kDefaultClock);
 
   // Constructs a Time representing seconds.
-  // TODO(brians): fix and test the negative cases for all of these
   static constexpr Time InSeconds(double seconds) {
     return (seconds < 0.0) ?
         Time(static_cast<int32_t>(seconds) - 1,
@@ -94,8 +99,11 @@
 
   // Constructs a time representing microseconds.
   static constexpr Time InNS(int64_t nseconds) {
-    return Time(nseconds / static_cast<int64_t>(kNSecInSec),
-                nseconds % kNSecInSec);
+    return (nseconds < 0) ?
+        Time(nseconds / static_cast<int64_t>(kNSecInSec) - 1,
+             (nseconds % kNSecInSec) + kNSecInSec) :
+        Time(nseconds / static_cast<int64_t>(kNSecInSec),
+             nseconds % kNSecInSec);
   }
 
   // Constructs a time representing microseconds.
@@ -108,7 +116,10 @@
 
   // Constructs a time representing mseconds.
   static constexpr Time InMS(int mseconds) {
-    return Time(mseconds / kMSecInSec, (mseconds % kMSecInSec) * kNSecInMSec);
+    return (mseconds < 0) ?
+        Time(mseconds / kMSecInSec - 1,
+             (mseconds % kMSecInSec) * kNSecInMSec + kNSecInSec) :
+        Time(mseconds / kMSecInSec, (mseconds % kMSecInSec) * kNSecInMSec);
   }
 
   // Checks whether or not this time is within amount nanoseconds of other.
@@ -138,7 +149,6 @@
   }
 
   // Returns the time represent in microseconds.
-  // TODO(brians): test this
   int64_t constexpr ToUSec() const {
     return static_cast<int64_t>(sec_) * static_cast<int64_t>(kUSecInSec) +
         (static_cast<int64_t>(nsec_) / static_cast<int64_t>(kNSecInUSec));
@@ -160,7 +170,6 @@
   const Time operator-(const Time &rhs) const;
   const Time operator*(int32_t rhs) const;
   const Time operator/(int32_t rhs) const;
-  // TODO(brians) test this
   double operator/(const Time &rhs) const;
   const Time operator%(int32_t rhs) const;
 
@@ -194,14 +203,12 @@
   // Enables returning the mock time value for Now instead of checking the
   // system clock.  This should only be used when testing things depending on
   // time, or many things may/will break.
-  static void EnableMockTime(const Time now);
+  static void EnableMockTime(const Time &now);
   // Sets now when time is being mocked.
-  static void SetMockTime(const Time now);
-  // Convenience function to just increment the mock time by a certain amount.
-  static void IncrementMockTime(const Time amount) {
-    // TODO(brians) make this thread safe so it's more useful?
-    SetMockTime(Now() + amount);
-  }
+  static void SetMockTime(const Time &now);
+  // Convenience function to just increment the mock time by a certain amount in
+  // a thread safe way.
+  static void IncrementMockTime(const Time &amount);
   // Disables mocking time.
   static void DisableMockTime();
 
@@ -212,7 +219,9 @@
   static void CheckImpl(int32_t nsec);
   void Check() { CheckImpl(nsec_); }
   // A constexpr version of CheckImpl that returns the given value when it
-  // succeeds.
+  // succeeds or evaluates to non-constexpr and returns 0 when it fails.
+  // This will result in the usual LOG(FATAL) if this is used where it isn't
+  // required to be constexpr or a compile error if it is.
   static constexpr int32_t CheckConstexpr(int32_t nsec) {
     return (nsec >= kNSecInSec || nsec < 0) ? CheckImpl(nsec), 0 : nsec;
   }
diff --git a/aos/common/time_test.cc b/aos/common/time_test.cc
index e6b7bb0..3f53de3 100644
--- a/aos/common/time_test.cc
+++ b/aos/common/time_test.cc
@@ -56,6 +56,9 @@
   EXPECT_EQ(MACRO_DARG(Time(57, 6500)), t + MACRO_DARG(Time(3, 6000)));
   EXPECT_EQ(MACRO_DARG(Time(50, 300)),
             t + MACRO_DARG(Time(-5, Time::kNSecInSec - 200)));
+  EXPECT_EQ(Time(-46, 500), t + Time(-100, 0));
+  EXPECT_EQ(Time(-47, Time::kNSecInSec - 500),
+            Time(-101, Time::kNSecInSec - 1000) + t);
 }
 TEST(TimeTest, Subtraction) {
   Time t(54, 500);
@@ -66,28 +69,55 @@
             t - MACRO_DARG(Time(0, Time::kNSecInSec - 100)));
   EXPECT_EQ(MACRO_DARG(Time(55, 800)),
             t - MACRO_DARG(Time(-2, Time::kNSecInSec - 300)));
+  EXPECT_EQ(Time(54, 5500), t - Time(-1, Time::kNSecInSec - 5000));
+  EXPECT_EQ(Time(-50, Time::kNSecInSec - 300),
+            Time(5, 200) - t);
 }
 
 TEST(TimeTest, Multiplication) {
   Time t(54, Time::kNSecInSec / 3);
   EXPECT_EQ(MACRO_DARG(Time(108, Time::kNSecInSec / 3 * 2)), t * 2);
   EXPECT_EQ(MACRO_DARG(Time(271, Time::kNSecInSec / 3 * 2 - 1)), t * 5);
+  EXPECT_EQ(Time(-109, Time::kNSecInSec / 3 + 1), t * -2);
+  EXPECT_EQ(Time(-55, Time::kNSecInSec / 3 * 2 + 1), t * -1);
+  EXPECT_EQ(Time(-218, Time::kNSecInSec / 3 * 2 + 2), (t * -1) * 4);
 }
-TEST(TimeTest, Division) {
-  EXPECT_EQ(MACRO_DARG(Time(5, Time::kNSecInSec / 10 * 4 + 50)),
-            MACRO_DARG(Time(54, 500)) / 10);
+TEST(TimeTest, DivisionByInt) {
+  EXPECT_EQ(Time(5, Time::kNSecInSec / 10 * 4 + 50), Time(54, 500) / 10);
+  EXPECT_EQ(Time(2, Time::kNSecInSec / 4 * 3),
+            Time(5, Time::kNSecInSec / 2) / 2);
+  EXPECT_EQ(Time(-3, Time::kNSecInSec / 4 * 3),
+            Time(-5, Time::kNSecInSec / 2) / 2);
+}
+TEST(TimeTest, DivisionByTime) {
+  EXPECT_DOUBLE_EQ(2, Time(10, 0) / Time(5, 0));
+  EXPECT_DOUBLE_EQ(9, Time(27, 0) / Time(3, 0));
+  EXPECT_DOUBLE_EQ(9.25, Time(37, 0) / Time(4, 0));
+  EXPECT_DOUBLE_EQ(5.25, Time(36, Time::kNSecInSec / 4 * 3) / Time(7, 0));
+  EXPECT_DOUBLE_EQ(-5.25, Time(-37, Time::kNSecInSec / 4) / Time(7, 0));
+  EXPECT_DOUBLE_EQ(-5.25, Time(36, Time::kNSecInSec / 4 * 3) / Time(-7, 0));
 }
 
 TEST(TimeTest, Comparisons) {
-  EXPECT_TRUE(MACRO_DARG(Time(971, 254) > Time(971, 253)));
-  EXPECT_TRUE(MACRO_DARG(Time(971, 254) >= Time(971, 253)));
-  EXPECT_TRUE(MACRO_DARG(Time(971, 254) < Time(971, 255)));
-  EXPECT_TRUE(MACRO_DARG(Time(971, 254) <= Time(971, 255)));
-  EXPECT_TRUE(MACRO_DARG(Time(971, 254) >= Time(971, 253)));
-  EXPECT_TRUE(MACRO_DARG(Time(971, 254) <= Time(971, 254)));
-  EXPECT_TRUE(MACRO_DARG(Time(971, 254) >= Time(971, 254)));
-  EXPECT_TRUE(MACRO_DARG(Time(972, 254) > Time(971, 254)));
-  EXPECT_TRUE(MACRO_DARG(Time(971, 254) < Time(972, 254)));
+  EXPECT_TRUE(Time(971, 254) > Time(971, 253));
+  EXPECT_TRUE(Time(971, 254) >= Time(971, 253));
+  EXPECT_TRUE(Time(971, 254) < Time(971, 255));
+  EXPECT_TRUE(Time(971, 254) <= Time(971, 255));
+  EXPECT_TRUE(Time(971, 254) >= Time(971, 253));
+  EXPECT_TRUE(Time(971, 254) <= Time(971, 254));
+  EXPECT_TRUE(Time(971, 254) >= Time(971, 254));
+  EXPECT_TRUE(Time(972, 254) > Time(971, 254));
+  EXPECT_TRUE(Time(971, 254) < Time(972, 254));
+
+  EXPECT_TRUE(Time(-971, 254) > Time(-971, 253));
+  EXPECT_TRUE(Time(-971, 254) >= Time(-971, 253));
+  EXPECT_TRUE(Time(-971, 254) < Time(-971, 255));
+  EXPECT_TRUE(Time(-971, 254) <= Time(-971, 255));
+  EXPECT_TRUE(Time(-971, 254) >= Time(-971, 253));
+  EXPECT_TRUE(Time(-971, 254) <= Time(-971, 254));
+  EXPECT_TRUE(Time(-971, 254) >= Time(-971, 254));
+  EXPECT_TRUE(Time(-972, 254) < Time(-971, 254));
+  EXPECT_TRUE(Time(-971, 254) > Time(-972, 254));
 }
 
 TEST(TimeTest, Within) {
@@ -95,54 +125,73 @@
   EXPECT_FALSE(MACRO_DARG(Time(55, 5000).IsWithin(Time(55, 4900), 99)));
   EXPECT_TRUE(MACRO_DARG(Time(5, 0).IsWithin(Time(4, Time::kNSecInSec - 200),
                                              250)));
+  EXPECT_TRUE(Time(-5, Time::kNSecInSec - 200).IsWithin(Time(-4, 0), 250));
+  EXPECT_TRUE(Time(-5, 200).IsWithin(Time(-5, 0), 250));
 }
 
-TEST(TimeTest, Modulo) {
+TEST(TimeTest, Modulus) {
   EXPECT_EQ(MACRO_DARG(Time(0, Time::kNSecInSec / 10 * 2)),
             MACRO_DARG(Time(50, 0) % (Time::kNSecInSec / 10 * 3)));
+  EXPECT_EQ(Time(-1, Time::kNSecInSec / 10 * 8),
+            Time(-50, 0) % (Time::kNSecInSec / 10 * 3));
+  EXPECT_EQ(Time(-1, Time::kNSecInSec / 10 * 8),
+            Time(-50, 0) % (-Time::kNSecInSec / 10 * 3));
+  EXPECT_EQ(Time(0, Time::kNSecInSec / 10 * 2),
+            Time(50, 0) % (-Time::kNSecInSec / 10 * 3));
 }
 
+// TODO(brians): Finish tests for negatives from here on.
 TEST(TimeTest, InSeconds) {
   EXPECT_EQ(MACRO_DARG(Time(2, Time::kNSecInSec / 100 * 55 - 1)),
             Time::InSeconds(2.55));
+  EXPECT_EQ(MACRO_DARG(Time(-3, Time::kNSecInSec / 100 * 45)),
+            Time::InSeconds(-2.55));
 }
 
 TEST(TimeTest, ToSeconds) {
-  EXPECT_EQ(13.23, Time::InSeconds(13.23).ToSeconds());
+  EXPECT_DOUBLE_EQ(13.23, Time::InSeconds(13.23).ToSeconds());
+  EXPECT_NEAR(-13.23, Time::InSeconds(-13.23).ToSeconds(),
+              1.0 / Time::kNSecInSec * 2);
 }
 
-#ifdef __VXWORKS__
-TEST(TimeTest, ToTicks) {
-  EXPECT_EQ(sysClkRateGet() / 100,
-            MACRO_DARG(Time(0, Time::kNSecInSec / 100).ToTicks()));
-}
-TEST(TimeTest, InTicks) {
-  EXPECT_EQ(MACRO_DARG(Time(2, Time::kNSecInSec)),
-            Time::InTicks(sysClkRateGet() * 2.5));
-}
-#endif
-
 TEST(TimeTest, InMS) {
   Time t = Time::InMS(254971);
   EXPECT_EQ(254, t.sec());
   EXPECT_EQ(971000000, t.nsec());
+
+  Time t2 = Time::InMS(-254971);
+  EXPECT_EQ(-255, t2.sec());
+  EXPECT_EQ(Time::kNSecInSec - 971000000, t2.nsec());
+}
+
+TEST(TimeTest, ToMSec) {
+  EXPECT_EQ(254971, Time(254, 971000000).ToMSec());
+  EXPECT_EQ(-254971, Time(-255, Time::kNSecInSec - 971000000).ToMSec());
 }
 
 TEST(TimeTest, InNS) {
   Time t = Time::InNS(static_cast<int64_t>(973254111971ll));
   EXPECT_EQ(973, t.sec());
   EXPECT_EQ(254111971, t.nsec());
+
+  Time t2 = Time::InNS(static_cast<int64_t>(-973254111971ll));
+  EXPECT_EQ(-974, t2.sec());
+  EXPECT_EQ(Time::kNSecInSec - 254111971, t2.nsec());
 }
 
 TEST(TimeTest, InUS) {
   Time t = Time::InUS(254111971);
   EXPECT_EQ(254, t.sec());
   EXPECT_EQ(111971000, t.nsec());
+
+  Time t2 = Time::InUS(-254111971);
+  EXPECT_EQ(-255, t2.sec());
+  EXPECT_EQ(Time::kNSecInSec - 111971000, t2.nsec());
 }
 
-TEST(TimeTest, ToMSec) {
-  Time t(254, 971000000);
-  EXPECT_EQ(254971, t.ToMSec());
+TEST(TimeTest, ToUSec) {
+  EXPECT_EQ(254000971, Time(254, 971000).ToUSec());
+  EXPECT_EQ(-254000971, Time(-255, Time::kNSecInSec - 971000).ToUSec());
 }
 
 TEST(TimeTest, Abs) {