Properly fix the license for C++ template usage. This means we needed to change from...
[libasyncio] / utils / asyncio_time_tools.cpp
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 */
20 /** 
21  * @file
22  * @brief
23  *
24  * @author Reinhard Pfau \<reinhard.pfau@intra2net.com\>
25  *
26  * @copyright &copy; Copyright 2008 Intra2Net AG
27  */
28
29 #include "asyncio_time_tools.hpp"
30
31 #include <sys/time.h>
32 #include <unistd.h>
33 #include <sys/timeb.h>
34 #include <sys/syscall.h>
35
36
37 // define missing POSIX.1b constants...
38
39 #ifndef CLOCK_REALTIME
40 #define CLOCK_REALTIME 0
41 #endif
42 #ifndef CLOCK_MONOTONIC
43 #define CLOCK_MONOTONIC 1
44 #endif
45
46 namespace AsyncIo
47 {
48 namespace Utils
49 {
50
51
52 namespace
53 {
54
55
56 /**
57  * @brief fetches the value from the monotonic clock source.
58  * @param[out] seconds the seconds.
59  * @param[out] nano_seconds the nano seconds.
60  * @return @a true if the clock was successfully read.
61  */
62 bool monotonic_clock_gettime(long int& seconds, long int& nano_seconds)
63 {
64     struct timespec tp[1];
65     int res= ::syscall(__NR_clock_gettime, CLOCK_MONOTONIC, tp);
66     if (0 == res)
67     {
68         seconds= tp->tv_sec;
69         nano_seconds= tp->tv_nsec;
70     }
71     return (res==0);
72 } // eo monotonic_clock_gettime(long int&,long int&)
73
74
75
76
77 void get_current_real_time(long& current_sec, long& current_msec)
78 {
79     struct timeval tv;
80     gettimeofday(&tv,NULL);
81     current_sec= tv.tv_sec;
82     current_msec= (tv.tv_usec / 1000);
83     if (current_msec >= 1000)
84     {
85         current_sec += (current_msec / 1000);
86         current_msec%= 1000;
87     }
88 } // eo get_current_real_time
89
90
91 void get_current_monotonic_time(long& current_sec, long& current_msec)
92 {
93     long nsec;
94     if (monotonic_clock_gettime(current_sec,nsec))
95     {
96         current_msec= nsec / 1000000L;
97     }
98     else
99     {
100         //fallback...
101         get_current_real_time(current_sec,current_msec);
102     }
103 } // eo get_current_monotonic_time
104
105
106
107 } // eo anonymous namespace
108
109 /**************************************************************************\
110 \**************************************************************************/
111
112
113 /*
114  * implementation of MilliTime
115  */
116
117 MilliTime::MilliTime(long sec, long msec)
118 : mt_sec(sec), mt_msec(msec)
119 {
120     normalize();
121 } // eo MilliTime::MilliTime
122
123
124 void MilliTime::set(long sec, long msec)
125 {
126     mt_sec= sec;
127     mt_msec= msec;
128     normalize();
129 } // eo MilliTime::set
130
131
132 /**
133  * normalizes the values, so that mt_msec has a value between 0 and 999.
134  */
135 void MilliTime::normalize()
136 {
137     if (mt_msec < 0)
138     {
139         mt_sec += (mt_msec / 1000) - 1;
140         mt_msec = (mt_msec % 1000) + 1000;
141     }
142     else if (mt_msec>=1000)
143     {
144         mt_sec+= (mt_msec / 1000);
145         mt_msec %= 1000;
146     }
147 } // eo MilliTime::normalize
148
149
150 /**
151  * determine if the represented point in time is before another one.
152  * @param other the other point in time.
153  * @return true if the own point in time is before the other one.
154  */
155 bool MilliTime::operator < (MilliTime& other)
156 {
157     normalize();
158     other.normalize();
159     return
160         (mt_sec < other.mt_sec)
161         || (( mt_sec == other.mt_sec) && (mt_msec < other.mt_msec));
162 } // eo MilliTime::operator <
163
164
165 /**
166  * determine if two point in times are equal.
167  * @param other the point in time to compare with.
168  * @return true if the represented times are equal.
169  */
170 bool MilliTime::operator == (MilliTime& other)
171 {
172     normalize();
173     other.normalize();
174     return (( mt_sec == other.mt_sec) && (mt_msec == other.mt_msec));
175 } // eo MilliTime::operator <
176
177 /**
178  * @brief subtracts a time delta from the object.
179  * @param lhs the time delta to subtract.
180  * @return reference to the object itself.
181  */
182 MilliTime& MilliTime::operator -= (const MilliTime& lhs)
183 {
184     mt_sec  -= lhs.mt_sec;
185     mt_msec -= lhs.mt_msec;
186     return *this;
187 } // eo operator -=
188
189
190 /**
191  * @brief adds a time delta from the object.
192  * @param lhs the time delta to add.
193  * @return reference to the object itself.
194  */
195 MilliTime& MilliTime::operator += (const MilliTime& lhs)
196 {
197     mt_sec  += lhs.mt_sec;
198     mt_msec += lhs.mt_msec;
199     return *this;
200 }  // eo operator +=
201
202
203
204 /**
205  * @brief gets the current time as MilliTime structure.
206  * @param[out] mt reference to the MilliTime strcucture which is filled with the result.
207  */
208 void get_current_real_time(MilliTime& mt)
209 {
210     long sec, msec;
211     get_current_real_time(sec,msec);
212     mt.set(sec,msec);
213 } // eo get_current_real_time
214
215
216 /**
217  * @brief gets the current time as MilliTime structure.
218  * @param[out] mt reference to the MilliTime strcucture which is filled with the result.
219  */
220 void get_current_monotonic_time(MilliTime& mt)
221 {
222     long sec, msec;
223     get_current_monotonic_time(sec,msec);
224     mt.set(sec,msec);
225 } // eo get_current_monotonic_time
226
227
228
229
230
231 } // eo namespace Utils
232 } // eo namespace AsyncIo