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