blob: 57c5f264bdd3256ef77739d3a8a94ee2e2830d28 [file] [log] [blame]
brians343bc112013-02-10 01:53:46 +00001#ifndef AOS_COMMON_TIME_H_
2#define AOS_COMMON_TIME_H_
3
4#include <stdint.h>
5#include <time.h>
6
7#ifndef __VXWORKS__
8#include <type_traits>
9#else
10#include <sysLib.h>
11#endif
12#include <ostream>
13
14#include "aos/aos_stdint.h"
15#include "aos/common/type_traits.h"
16
17namespace aos {
18namespace time {
19
20// A nice structure for representing times.
21// 0 <= nsec_ < kNSecInSec should always be true. All functions here will make
22// sure that that is true if it was on all inputs (including *this).
23//
24// The arithmetic and comparison operators are overloaded because they make
25// complete sense and are very useful. The default copy and assignment stuff is
26// left because it works fine. Multiplication and division of Times by Times are
27// not implemented because I can't think of any uses for them and there are
28// multiple ways to do it.
29struct Time {
30 public:
31 static const int32_t kNSecInSec = 1000000000;
32 static const int32_t kNSecInMSec = 1000000;
33 static const int32_t kNSecInUSec = 1000;
34 static const int32_t kMSecInSec = 1000;
35 static const int32_t kUSecInSec = 1000000;
36 Time(int32_t sec, int32_t nsec) : sec_(sec), nsec_(nsec) {
37 Check();
38 }
39 #ifndef SWIG
40 explicit Time(const struct timespec &value)
41 : sec_(value.tv_sec), nsec_(value.tv_nsec) {
42 Check();
43 }
44 struct timespec ToTimespec() const {
45 struct timespec ans;
46 ans.tv_sec = sec_;
47 ans.tv_nsec = nsec_;
48 return ans;
49 }
50 #endif // SWIG
51 // CLOCK_MONOTONIC on the fitpc and CLOCK_REALTIME on the cRIO because the
52 // cRIO doesn't have any others.
53 // CLOCK_REALTIME is the default realtime clock and CLOCK_MONOTONIC doesn't
54 // change when somebody changes the wall clock (like the ntp deamon or
55 // whatever). See clock_gettime(2) for details.
56 //
57 // This is the clock that code that just wants to sleep for a certain amount
58 // of time or measure how long something takes should use.
59 #ifndef __VXWORKS__
60 static const clockid_t kDefaultClock = CLOCK_MONOTONIC;
61 #else
62 static const clockid_t kDefaultClock = CLOCK_REALTIME;
63 #endif
64 // Creates a Time representing the current value of the specified clock or
65 // dies.
66 static Time Now(clockid_t clock = kDefaultClock);
67
68 // Constructs a Time representing seconds.
69 static Time InSeconds(double seconds) {
70 return Time(static_cast<int32_t>(seconds),
71 (seconds - static_cast<int32_t>(seconds)) * kNSecInSec);
72 }
73
74 // Constructs a time representing microseconds.
75 static Time InNS(int64_t nseconds) {
76 return Time(nseconds / static_cast<int64_t>(kNSecInSec),
77 nseconds % kNSecInSec);
78 }
79
80 // Constructs a time representing microseconds.
81 static Time InUS(int useconds) {
82 return Time(useconds / kUSecInSec, (useconds % kUSecInSec) * kNSecInUSec);
83 }
84
85 // Constructs a time representing mseconds.
86 static Time InMS(int mseconds) {
87 return Time(mseconds / kMSecInSec, (mseconds % kMSecInSec) * kNSecInMSec);
88 }
89
90 // Checks whether or not this time is within amount nanoseconds of other.
91 bool IsWithin(const Time &other, int64_t amount) const;
92
93 // Returns the time represented all in nanoseconds.
94 int64_t ToNSec() const {
95 return static_cast<int64_t>(sec_) * static_cast<int64_t>(kNSecInSec) +
96 static_cast<int64_t>(nsec_);
97 }
98#ifdef __VXWORKS__
99 // Returns the time represented all in system clock ticks. The system clock
100 // rate is retrieved using sysClkRateGet().
101 int ToTicks() const {
102 return ToNSec() / static_cast<int64_t>(kNSecInSec / sysClkRateGet());
103 }
104#endif
105
106 // Returns the time represented in milliseconds.
107 int64_t ToMSec() const {
108 return static_cast<int64_t>(sec_) * static_cast<int64_t>(kMSecInSec) +
109 (static_cast<int64_t>(nsec_) / static_cast<int64_t>(kNSecInMSec));
110 }
111
112 #ifndef SWIG
113 Time &operator+=(const Time &rhs);
114 Time &operator-=(const Time &rhs);
115 Time &operator*=(int32_t rhs);
116 Time &operator/=(int32_t rhs);
117 Time &operator%=(int32_t rhs);
118 #endif
119 const Time operator+(const Time &rhs) const;
120 const Time operator-(const Time &rhs) const;
121 const Time operator*(int32_t rhs) const;
122 const Time operator/(int32_t rhs) const;
123 const Time operator%(int32_t rhs) const;
124
125 bool operator==(const Time &rhs) const;
126 bool operator!=(const Time &rhs) const;
127 bool operator<(const Time &rhs) const;
128 bool operator>(const Time &rhs) const;
129 bool operator<=(const Time &rhs) const;
130 bool operator>=(const Time &rhs) const;
131
132 #ifndef SWIG
133 // For gtest etc.
134 friend std::ostream &operator<<(std::ostream &os, const Time &time);
135 #endif // SWIG
136
137 int32_t sec() const { return sec_; }
138 void set_sec(int32_t sec) { sec_ = sec; }
139 int32_t nsec() const { return nsec_; }
140 void set_nsec(int32_t nsec) {
141 nsec_ = nsec;
142 Check();
143 }
144
145 private:
146 int32_t sec_, nsec_;
147 // LOG(FATAL)s if nsec_ is >= kNSecInSec.
148 void Check();
149};
150
151// Sleeps for the amount of time represented by time counted by clock.
152void SleepFor(const Time &time, clockid_t clock = Time::kDefaultClock);
153// Sleeps until clock is at the time represented by time.
154void SleepUntil(const Time &time, clockid_t clock = Time::kDefaultClock);
155
156} // namespace time
157} // namespace aos
158
159#endif // AOS_COMMON_TIME_H_