Branch data Line data Source code
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 : :
16 : : /**
17 : : * @file
18 : : * This header defines the TimeValue class.
19 : : */
20 : :
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 : :
37 : : __BEGIN_NS_SSRC_WISP_UTILITY
38 : :
39 : : #define __WISP_BILLION 1000000000
40 : :
41 : : class TimeValue {
42 : : timespec _time;
43 : :
44 : :
45 : : #ifdef WISP_HAVE_CLOCK_GETTIME
46 : 15 : static int gettime(::clockid_t clk_id, timespec *tp) {
47 : 15 : 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 : 1 : static sec_type now_seconds() {
77 : 1 : return std::time(0);
78 : : }
79 : :
80 : : static TimeValue time() {
81 : : return TimeValue().now();
82 : : }
83 : :
84 : 18 : TimeValue() {
85 : 18 : _time.tv_sec = _time.tv_nsec = 0;
86 : 18 : }
87 : :
88 : 19 : TimeValue(const sec_type seconds,
89 : : const nsec_type nanoseconds)
90 : : SSRC_DECL_THROW(std::invalid_argument)
91 : 19 : {
92 [ + - - + ]: 19 : if(seconds < 0 || nanoseconds < 0)
93 [ # # ]: 0 : throw std::invalid_argument("negative time");
94 : :
95 [ - + ]: 19 : if(nanoseconds >= __WISP_BILLION) {
96 : 0 : _time.tv_sec = seconds + nanoseconds / __WISP_BILLION;
97 : 0 : _time.tv_nsec = nanoseconds % __WISP_BILLION;
98 : : } else {
99 : 19 : _time.tv_sec = seconds;
100 : 19 : _time.tv_nsec = nanoseconds;
101 : : }
102 : 19 : }
103 : :
104 : 1 : explicit TimeValue(const ms_type millisec) {
105 : 1 : _time.tv_sec = millisec / 1000;
106 : 1 : _time.tv_nsec = (millisec % 1000) * 1000000;
107 : 1 : }
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 : :
118 : 15 : TimeValue & now_mono() {
119 : : #ifdef WISP_HAVE_CLOCK_GETTIME
120 : 15 : gettime(CLOCK_MONOTONIC, &_time);
121 : : #elif defined(WISP_HAVE_CLOCK_GET_TIME)
122 : : gettime(SYSTEM_CLOCK, &_time);
123 : : #endif
124 : 15 : return *this;
125 : : }
126 : :
127 : 7 : ms_type to_milliseconds() const {
128 : 7 : return (static_cast<ms_type>(_time.tv_sec)*1000 +
129 : 7 : (_time.tv_nsec + 999999)/1000000);
130 : : }
131 : :
132 : 5 : sec_type seconds() const throw () {
133 : 5 : return _time.tv_sec;
134 : : }
135 : :
136 : 5 : nsec_type nanoseconds() const throw () {
137 : 5 : return _time.tv_nsec;
138 : : }
139 : :
140 : 4 : TimeValue & operator+=(const TimeValue & t2) {
141 : 4 : _time.tv_sec+=t2._time.tv_sec;
142 : 4 : _time.tv_nsec+=t2._time.tv_nsec;
143 : :
144 [ + + ]: 4 : if(_time.tv_nsec >= __WISP_BILLION) {
145 : 1 : ++_time.tv_sec;
146 : 1 : _time.tv_nsec-=__WISP_BILLION;
147 : : }
148 : :
149 : 4 : return *this;
150 : : }
151 : :
152 : 7 : TimeValue & operator-=(const TimeValue & t2) {
153 : 7 : _time.tv_sec-=t2._time.tv_sec;
154 : 7 : _time.tv_nsec-=t2._time.tv_nsec;
155 : :
156 [ + - ]: 7 : if(_time.tv_nsec < 0) {
157 : 7 : --_time.tv_sec;
158 : 7 : _time.tv_nsec+=__WISP_BILLION;
159 : : }
160 : :
161 : 7 : return *this;
162 : : }
163 : :
164 : 5 : friend bool operator==(const TimeValue & t1, const TimeValue & t2) {
165 [ + + + - ]: 6 : return (t1._time.tv_sec == t2._time.tv_sec &&
166 : 6 : t1._time.tv_nsec == t2._time.tv_nsec);
167 : : }
168 : :
169 : 27 : friend bool operator<(const TimeValue & t1, const TimeValue & t2) {
170 [ + + - + ]: 54 : return (t1._time.tv_sec < t2._time.tv_sec ||
171 [ # # ]: 2 : (t1._time.tv_sec == t2._time.tv_sec &&
172 : 27 : 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 : 7 : inline TimeValue operator-(const TimeValue & t1, const TimeValue & t2) {
182 : 7 : TimeValue result(t1);
183 : 7 : return (result-=t2);
184 : : }
185 : :
186 : 1 : inline TimeValue operator+(const TimeValue & t1, const TimeValue & t2) {
187 : 1 : TimeValue result(t1);
188 : 1 : return (result+=t2);
189 : : }
190 : :
191 : 8 : const TimeValue InfiniteTimeValue =
192 : : TimeValue(TimeValue::sec_type_traits::max(), 0);
193 : :
194 : : #undef __WISP_BILLION
195 : :
196 : : __END_NS_SSRC_WISP_UTILITY
197 : :
198 : : #endif
|