Commit | Line | Data |
---|---|---|
8c15b8c7 TJ |
1 | /* |
2 | The software in this package is distributed under the GNU General | |
3 | Public License version 2 (with a special exception described below). | |
4 | ||
5 | A copy of GNU General Public License (GPL) is included in this distribution, | |
6 | in the file COPYING.GPL. | |
7 | ||
8 | As a special exception, if other files instantiate templates or use macros | |
9 | or inline functions from this file, or you compile this file and link it | |
10 | with other works to produce a work based on this file, this file | |
11 | does not by itself cause the resulting work to be covered | |
12 | by the GNU General Public License. | |
13 | ||
14 | However the source code for this file must still be made available | |
15 | in accordance with section (3) of the GNU General Public License. | |
16 | ||
17 | This exception does not invalidate any other reasons why a work based | |
18 | on this file might be covered by the GNU General Public License. | |
19 | */ | |
7841da45 | 20 | /** |
aba4c34d RP |
21 | * @file |
22 | * @brief | |
23 | * | |
7841da45 | 24 | * @author Reinhard Pfau \<reinhard.pfau@gmx.de\> |
aba4c34d | 25 | * |
7841da45 RP |
26 | * @copyright © Copyright 2008-2009 Intra2Net AG |
27 | * @contact Intra2net Opensource team \<opensource@intra2net.com\> | |
aba4c34d RP |
28 | */ |
29 | ||
30 | #include "asyncio_time_tools.hpp" | |
31 | ||
32 | #include <sys/time.h> | |
33 | #include <unistd.h> | |
34 | #include <sys/timeb.h> | |
35 | #include <sys/syscall.h> | |
36 | ||
37 | ||
38 | // define missing POSIX.1b constants... | |
39 | ||
40 | #ifndef CLOCK_REALTIME | |
41 | #define CLOCK_REALTIME 0 | |
42 | #endif | |
43 | #ifndef CLOCK_MONOTONIC | |
44 | #define CLOCK_MONOTONIC 1 | |
45 | #endif | |
46 | ||
47 | namespace AsyncIo | |
48 | { | |
49 | namespace Utils | |
50 | { | |
51 | ||
52 | ||
53 | namespace | |
54 | { | |
55 | ||
56 | ||
57 | /** | |
58 | * @brief fetches the value from the monotonic clock source. | |
59 | * @param[out] seconds the seconds. | |
60 | * @param[out] nano_seconds the nano seconds. | |
61 | * @return @a true if the clock was successfully read. | |
62 | */ | |
63 | bool monotonic_clock_gettime(long int& seconds, long int& nano_seconds) | |
64 | { | |
65 | struct timespec tp[1]; | |
66 | int res= ::syscall(__NR_clock_gettime, CLOCK_MONOTONIC, tp); | |
67 | if (0 == res) | |
68 | { | |
69 | seconds= tp->tv_sec; | |
70 | nano_seconds= tp->tv_nsec; | |
71 | } | |
72 | return (res==0); | |
73 | } // eo monotonic_clock_gettime(long int&,long int&) | |
74 | ||
75 | ||
76 | ||
77 | ||
78 | void get_current_real_time(long& current_sec, long& current_msec) | |
79 | { | |
80 | struct timeval tv; | |
81 | gettimeofday(&tv,NULL); | |
82 | current_sec= tv.tv_sec; | |
83 | current_msec= (tv.tv_usec / 1000); | |
84 | if (current_msec >= 1000) | |
85 | { | |
86 | current_sec += (current_msec / 1000); | |
87 | current_msec%= 1000; | |
88 | } | |
89 | } // eo get_current_real_time | |
90 | ||
91 | ||
92 | void get_current_monotonic_time(long& current_sec, long& current_msec) | |
93 | { | |
94 | long nsec; | |
95 | if (monotonic_clock_gettime(current_sec,nsec)) | |
96 | { | |
97 | current_msec= nsec / 1000000L; | |
98 | } | |
99 | else | |
100 | { | |
101 | //fallback... | |
102 | get_current_real_time(current_sec,current_msec); | |
103 | } | |
104 | } // eo get_current_monotonic_time | |
105 | ||
106 | ||
107 | ||
108 | } // eo anonymous namespace | |
109 | ||
110 | /**************************************************************************\ | |
111 | \**************************************************************************/ | |
112 | ||
113 | ||
114 | /* | |
115 | * implementation of MilliTime | |
116 | */ | |
117 | ||
118 | MilliTime::MilliTime(long sec, long msec) | |
119 | : mt_sec(sec), mt_msec(msec) | |
120 | { | |
121 | normalize(); | |
122 | } // eo MilliTime::MilliTime | |
123 | ||
124 | ||
125 | void MilliTime::set(long sec, long msec) | |
126 | { | |
127 | mt_sec= sec; | |
128 | mt_msec= msec; | |
129 | normalize(); | |
130 | } // eo MilliTime::set | |
131 | ||
132 | ||
133 | /** | |
134 | * normalizes the values, so that mt_msec has a value between 0 and 999. | |
135 | */ | |
136 | void MilliTime::normalize() | |
137 | { | |
138 | if (mt_msec < 0) | |
139 | { | |
140 | mt_sec += (mt_msec / 1000) - 1; | |
141 | mt_msec = (mt_msec % 1000) + 1000; | |
142 | } | |
143 | else if (mt_msec>=1000) | |
144 | { | |
145 | mt_sec+= (mt_msec / 1000); | |
146 | mt_msec %= 1000; | |
147 | } | |
148 | } // eo MilliTime::normalize | |
149 | ||
150 | ||
151 | /** | |
152 | * determine if the represented point in time is before another one. | |
153 | * @param other the other point in time. | |
154 | * @return true if the own point in time is before the other one. | |
155 | */ | |
156 | bool MilliTime::operator < (MilliTime& other) | |
157 | { | |
158 | normalize(); | |
159 | other.normalize(); | |
160 | return | |
161 | (mt_sec < other.mt_sec) | |
162 | || (( mt_sec == other.mt_sec) && (mt_msec < other.mt_msec)); | |
163 | } // eo MilliTime::operator < | |
164 | ||
165 | ||
166 | /** | |
167 | * determine if two point in times are equal. | |
168 | * @param other the point in time to compare with. | |
169 | * @return true if the represented times are equal. | |
170 | */ | |
171 | bool MilliTime::operator == (MilliTime& other) | |
172 | { | |
173 | normalize(); | |
174 | other.normalize(); | |
175 | return (( mt_sec == other.mt_sec) && (mt_msec == other.mt_msec)); | |
176 | } // eo MilliTime::operator < | |
177 | ||
178 | /** | |
179 | * @brief subtracts a time delta from the object. | |
180 | * @param lhs the time delta to subtract. | |
181 | * @return reference to the object itself. | |
182 | */ | |
183 | MilliTime& MilliTime::operator -= (const MilliTime& lhs) | |
184 | { | |
185 | mt_sec -= lhs.mt_sec; | |
186 | mt_msec -= lhs.mt_msec; | |
54a4d0ab | 187 | return *this; |
aba4c34d RP |
188 | } // eo operator -= |
189 | ||
190 | ||
191 | /** | |
192 | * @brief adds a time delta from the object. | |
193 | * @param lhs the time delta to add. | |
194 | * @return reference to the object itself. | |
195 | */ | |
196 | MilliTime& MilliTime::operator += (const MilliTime& lhs) | |
197 | { | |
198 | mt_sec += lhs.mt_sec; | |
199 | mt_msec += lhs.mt_msec; | |
54a4d0ab | 200 | return *this; |
aba4c34d RP |
201 | } // eo operator += |
202 | ||
203 | ||
204 | ||
205 | /** | |
206 | * @brief gets the current time as MilliTime structure. | |
7841da45 | 207 | * @param[out] mt reference to the MilliTime structure which is filled with the result. |
aba4c34d RP |
208 | */ |
209 | void get_current_real_time(MilliTime& mt) | |
210 | { | |
211 | long sec, msec; | |
212 | get_current_real_time(sec,msec); | |
213 | mt.set(sec,msec); | |
214 | } // eo get_current_real_time | |
215 | ||
216 | ||
217 | /** | |
218 | * @brief gets the current time as MilliTime structure. | |
7841da45 | 219 | * @param[out] mt reference to the MilliTime structure which is filled with the result. |
aba4c34d RP |
220 | */ |
221 | void get_current_monotonic_time(MilliTime& mt) | |
222 | { | |
223 | long sec, msec; | |
224 | get_current_monotonic_time(sec,msec); | |
225 | mt.set(sec,msec); | |
226 | } // eo get_current_monotonic_time | |
227 | ||
228 | ||
229 | ||
230 | ||
231 | ||
232 | } // eo namespace Utils | |
233 | } // eo namespace AsyncIo |