Savarese Software Research Corporation
TimeValue.h
Go to the documentation of this file.
1 /* Copyright 2006-2008 Savarese Software Research Corporation
2  *
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.savarese.com/software/ApacheLicense-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
21 #ifndef __SSRC_WISP_UTILITY_TIME_VALUE_H
22 #define __SSRC_WISP_UTILITY_TIME_VALUE_H
23 
24 #include <ssrc/wisp-packages.h>
25 
26 #include <cstdint>
27 #include <stdexcept>
28 #include <limits>
29 #include <ctime>
30 #include <time.h>
31 
32 #if defined(WISP_HAVE_MACH_CLOCK_H)
33 #include <mach/mach_host.h>
34 #include <mach/clock.h>
35 #endif
36 
38 
39 #define __WISP_BILLION 1000000000
40 
41 class TimeValue {
42  timespec _time;
43 
44 
45 #ifdef WISP_HAVE_CLOCK_GETTIME
46  static int gettime(::clockid_t clk_id, timespec *tp) {
47  return ::clock_gettime(clk_id, tp);
48  }
49 #elif defined(WISP_HAVE_CLOCK_GET_TIME)
50  static int gettime(::clock_id_t clk_id, timespec *tp) {
51  ::clock_serv_t clock_serv;
52  ::mach_timespec_t mtp;
53  int result = -1;
54 
55  if((::host_get_clock_service(mach_host_self(), clk_id, &clock_serv) ==
56  KERN_SUCCESS))
57  {
58  if(::clock_get_time(clock_serv, &mtp) == KERN_SUCCESS) {
59  tp->tv_sec = mtp.tv_sec;
60  tp->tv_nsec = mtp.tv_nsec;
61  result = 0;
62  }
63  }
64  return result;
65  }
66 #else
67 # error "System does not implement POSIX clock_gettime or MACH clock_get_time."
68 #endif
69 
70 public:
71  typedef std::int64_t ms_type;
72  typedef time_t sec_type;
73  typedef long nsec_type;
74  typedef std::numeric_limits<sec_type> sec_type_traits;
75 
76  static sec_type now_seconds() {
77  return std::time(0);
78  }
79 
80  static TimeValue time() {
81  return TimeValue().now();
82  }
83 
84  TimeValue() {
85  _time.tv_sec = _time.tv_nsec = 0;
86  }
87 
88  TimeValue(const sec_type seconds,
89  const nsec_type nanoseconds)
90  SSRC_DECL_THROW(std::invalid_argument)
91  {
92  if(seconds < 0 || nanoseconds < 0)
93  throw std::invalid_argument("negative time");
94 
96  _time.tv_sec = seconds + nanoseconds / __WISP_BILLION;
97  _time.tv_nsec = nanoseconds % __WISP_BILLION;
98  } else {
99  _time.tv_sec = seconds;
100  _time.tv_nsec = nanoseconds;
101  }
102  }
103 
104  explicit TimeValue(const ms_type millisec) {
105  _time.tv_sec = millisec / 1000;
106  _time.tv_nsec = (millisec % 1000) * 1000000;
107  }
108 
109  TimeValue & now() {
110 #ifdef WISP_HAVE_CLOCK_GETTIME
111  gettime(CLOCK_REALTIME, &_time);
112 #elif defined(WISP_HAVE_CLOCK_GET_TIME)
113  gettime(CALENDAR_CLOCK, &_time);
114 #endif
115  return *this;
116  }
117 
119 #ifdef WISP_HAVE_CLOCK_GETTIME
120  gettime(CLOCK_MONOTONIC, &_time);
121 #elif defined(WISP_HAVE_CLOCK_GET_TIME)
122  gettime(SYSTEM_CLOCK, &_time);
123 #endif
124  return *this;
125  }
126 
127  ms_type to_milliseconds() const {
128  return (static_cast<ms_type>(_time.tv_sec)*1000 +
129  (_time.tv_nsec + 999999)/1000000);
130  }
131 
132  sec_type seconds() const throw () {
133  return _time.tv_sec;
134  }
135 
136  nsec_type nanoseconds() const throw () {
137  return _time.tv_nsec;
138  }
139 
140  TimeValue & operator+=(const TimeValue & t2) {
141  _time.tv_sec+=t2._time.tv_sec;
142  _time.tv_nsec+=t2._time.tv_nsec;
143 
144  if(_time.tv_nsec >= __WISP_BILLION) {
145  ++_time.tv_sec;
146  _time.tv_nsec-=__WISP_BILLION;
147  }
148 
149  return *this;
150  }
151 
152  TimeValue & operator-=(const TimeValue & t2) {
153  _time.tv_sec-=t2._time.tv_sec;
154  _time.tv_nsec-=t2._time.tv_nsec;
155 
156  if(_time.tv_nsec < 0) {
157  --_time.tv_sec;
158  _time.tv_nsec+=__WISP_BILLION;
159  }
160 
161  return *this;
162  }
163 
164  friend bool operator==(const TimeValue & t1, const TimeValue & t2) {
165  return (t1._time.tv_sec == t2._time.tv_sec &&
166  t1._time.tv_nsec == t2._time.tv_nsec);
167  }
168 
169  friend bool operator<(const TimeValue & t1, const TimeValue & t2) {
170  return (t1._time.tv_sec < t2._time.tv_sec ||
171  (t1._time.tv_sec == t2._time.tv_sec &&
172  t1._time.tv_nsec < t2._time.tv_nsec));
173  }
174 
175  template<class Archive>
176  void serialize(Archive & ar, const unsigned int) {
177  ar & _time.tv_sec & _time.tv_nsec;
178  }
179 };
180 
181 inline TimeValue operator-(const TimeValue & t1, const TimeValue & t2) {
182  TimeValue result(t1);
183  return (result-=t2);
184 }
185 
186 inline TimeValue operator+(const TimeValue & t1, const TimeValue & t2) {
187  TimeValue result(t1);
188  return (result+=t2);
189 }
190 
192  TimeValue(TimeValue::sec_type_traits::max(), 0);
193 
194 #undef __WISP_BILLION
195 
197 
198 #endif

Savarese Software Research Corporation
Copyright © 2006-2012 Savarese Software Research Corporation. All rights reserved.