File: | thread/time.c |
Warning: | line 188, column 5 Duplicate code detected |
Note: | line 202, column 5 Similar code here |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* |
2 | * The contents of this file are subject to the Mozilla Public License |
3 | * Version 1.1 (the "License"); you may not use this file except in |
4 | * compliance with the License. You may obtain a copy of the License at |
5 | * http://mozilla.org/. |
6 | * |
7 | * Software distributed under the License is distributed on an "AS IS" |
8 | * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See |
9 | * the License for the specific language governing rights and limitations |
10 | * under the License. |
11 | * |
12 | * The Original Code is AOLserver Code and related documentation |
13 | * distributed by AOL. |
14 | * |
15 | * The Initial Developer of the Original Code is America Online, |
16 | * Inc. Portions created by AOL are Copyright (C) 1999 America Online, |
17 | * Inc. All Rights Reserved. |
18 | * |
19 | * Alternatively, the contents of this file may be used under the terms |
20 | * of the GNU General Public License (the "GPL"), in which case the |
21 | * provisions of GPL are applicable instead of those above. If you wish |
22 | * to allow use of your version of this file only under the terms of the |
23 | * GPL and not to allow others to use your version of this file under the |
24 | * License, indicate your decision by deleting the provisions above and |
25 | * replace them with the notice and other provisions required by the GPL. |
26 | * If you do not delete the provisions above, a recipient may use your |
27 | * version of this file under either the License or the GPL. |
28 | */ |
29 | |
30 | |
31 | /* |
32 | * time.c -- |
33 | * |
34 | * Ns_Time support routines. |
35 | */ |
36 | |
37 | #include "thread.h" |
38 | |
39 | /* |
40 | *---------------------------------------------------------------------- |
41 | * |
42 | * Ns_GetTime -- |
43 | * |
44 | * Get the current time value. |
45 | * |
46 | * Results: |
47 | * Time fields in timePtr are updated. |
48 | * |
49 | * Side effects: |
50 | * None. |
51 | * |
52 | *---------------------------------------------------------------------- |
53 | */ |
54 | #if defined(HAVE_GETTIMEOFDAY1) |
55 | |
56 | void |
57 | Ns_GetTime(Ns_Time *timePtr) |
58 | { |
59 | |
60 | /* |
61 | * When gettimeofday() is available on the platform, use it. |
62 | * otherwise use other approaches below. |
63 | */ |
64 | struct timeval tbuf; |
65 | |
66 | gettimeofday(&tbuf, NULL((void*)0)); |
67 | timePtr->sec = tbuf.tv_sec; |
68 | timePtr->usec = tbuf.tv_usec; |
69 | } |
70 | |
71 | #elif defined(_MSC_VER) |
72 | |
73 | void |
74 | Ns_GetTime(Ns_Time *timePtr) |
75 | { |
76 | /* |
77 | * Platform-dependent approach to get the current time value from |
78 | * Windows via GetSystemTimeAsFileTime() |
79 | * |
80 | * Note: This version can be used together with Mutex timing under |
81 | * windows. |
82 | * |
83 | */ |
84 | |
85 | /* |
86 | * Number of 100 nanosecond units from 1601-01-01 to 1970-01-01: |
87 | */ |
88 | static const __int64 EPOCH_BIAS = 116444736000000000i64; |
89 | |
90 | union { |
91 | unsigned __int64 i; |
92 | FILETIME s; |
93 | } ft; |
94 | |
95 | GetSystemTimeAsFileTime(&ft.s); |
96 | timePtr->sec = (long)((ft.i - EPOCH_BIAS) / 10000000i64); |
97 | timePtr->usec = (long)((ft.i / 10i64 ) % 1000000i64); |
98 | } |
99 | |
100 | #else |
101 | |
102 | void |
103 | Ns_GetTime(Ns_Time *timePtr) |
104 | { |
105 | /* |
106 | * Platform-independent approach to get the current time value |
107 | * using Tcl_GetTime(). |
108 | * |
109 | * Be aware that calling this function requires Tcl to be |
110 | * initialized. Therefore, one MUST NOT call this code from |
111 | * within DllMain() under windows, otherwise the call is blocked |
112 | * or the behavior is undefined. Therefore, don't use this |
113 | * variant under Windows, when Mutex timing are activated. |
114 | */ |
115 | |
116 | Tcl_Time tbuf; |
117 | Tcl_GetTime(&tbuf); |
118 | |
119 | timePtr->sec = tbuf.sec; |
120 | timePtr->usec = tbuf.usec; |
121 | } |
122 | #endif |
123 | |
124 | |
125 | /* |
126 | *---------------------------------------------------------------------- |
127 | * |
128 | * Ns_AdjTime -- |
129 | * |
130 | * Adjust an Ns_Time so the values are in range. "usec" is only allowed |
131 | * to be negative, when "sec" == 0 (to express e.g. -0.1sec). |
132 | * "usec" is kept in the range <1mio. |
133 | * |
134 | * Results: |
135 | * None. |
136 | * |
137 | * Side effects: |
138 | * None. |
139 | * |
140 | *---------------------------------------------------------------------- |
141 | */ |
142 | |
143 | void |
144 | Ns_AdjTime(Ns_Time *timePtr) |
145 | { |
146 | NS_NONNULL_ASSERT(timePtr != NULL)((void) (0)); |
147 | |
148 | if (unlikely(timePtr->usec < 0)(__builtin_expect((timePtr->usec < 0), 0)) && unlikely(timePtr->sec > 0)(__builtin_expect((timePtr->sec > 0), 0))) { |
149 | timePtr->sec += (timePtr->usec / 1000000L) - 1; |
150 | timePtr->usec = (timePtr->usec % 1000000L) + 1000000L; |
151 | } else if (unlikely(timePtr->usec > 1000000L)(__builtin_expect((timePtr->usec > 1000000L), 0))) { |
152 | timePtr->sec += timePtr->usec / 1000000L; |
153 | timePtr->usec = timePtr->usec % 1000000L; |
154 | } |
155 | } |
156 | |
157 | |
158 | /* |
159 | *---------------------------------------------------------------------- |
160 | * |
161 | * Ns_DiffTime -- |
162 | * |
163 | * Determine the difference between values passed in t1 and t0 |
164 | * Ns_Time structures. |
165 | * |
166 | * Results: |
167 | * -1, 0, or 1 if t1 is before, same, or after t0. |
168 | * |
169 | * Side effects: |
170 | * None. |
171 | * |
172 | *---------------------------------------------------------------------- |
173 | */ |
174 | |
175 | long |
176 | Ns_DiffTime(const Ns_Time *t1, const Ns_Time *t0, Ns_Time *diffPtr) |
177 | { |
178 | Ns_Time diff, t0p, t1p, *t0Ptr, *t1Ptr; |
179 | bool_Bool t0pos, t1pos, subtract, isNegative; |
180 | |
181 | |
182 | NS_NONNULL_ASSERT(t0 != NULL)((void) (0)); |
183 | NS_NONNULL_ASSERT(t1 != NULL)((void) (0)); |
184 | |
185 | if (diffPtr == NULL((void*)0)) { |
186 | diffPtr = &diff; |
187 | } |
188 | if (t0->sec < 0) { |
Duplicate code detected | |
189 | t0p.sec = -t0->sec; |
190 | t0p.usec = t0->usec; |
191 | t0pos = NS_FALSE0; |
192 | } else if (t0->sec == 0 && t0->usec < 0) { |
193 | t0p.sec = -t0->sec; |
194 | t0p.usec = -t0->usec; |
195 | t0pos = NS_FALSE0; |
196 | } else { |
197 | t0p.sec = t0->sec; |
198 | t0p.usec = t0->usec; |
199 | t0pos = NS_TRUE1; |
200 | } |
201 | |
202 | if (t1->sec < 0) { |
Similar code here | |
203 | t1p.sec = -t1->sec; |
204 | t1p.usec = t1->usec; |
205 | t1pos = NS_FALSE0; |
206 | } else if (t1->sec == 0 && t1->usec < 0) { |
207 | t1p.sec = -t1->sec; |
208 | t1p.usec = -t1->usec; |
209 | t1pos = NS_FALSE0; |
210 | } else { |
211 | t1p.sec = t1->sec; |
212 | t1p.usec = t1->usec; |
213 | t1pos = NS_TRUE1; |
214 | } |
215 | |
216 | if (t1pos) { |
217 | if (t0pos) { |
218 | /* |
219 | * Subtract POS - POS |
220 | */ |
221 | subtract = NS_TRUE1; |
222 | isNegative = t1p.sec < t0p.sec |
223 | || (t1p.sec == t0p.sec && (t1p.usec < t0p.usec)); |
224 | if (isNegative) { |
225 | t0Ptr = &t1p; |
226 | t1Ptr = &t0p; |
227 | } else { |
228 | t0Ptr = &t0p; |
229 | t1Ptr = &t1p; |
230 | } |
231 | } else { |
232 | /* |
233 | * Add POS - NEG |
234 | */ |
235 | subtract = NS_FALSE0; |
236 | isNegative = NS_FALSE0; |
237 | t0Ptr = &t1p; |
238 | t1Ptr = &t0p; |
239 | } |
240 | } else { |
241 | if (t0pos) { |
242 | /* |
243 | * ADD NEG - POS |
244 | */ |
245 | subtract = NS_FALSE0; |
246 | isNegative = NS_TRUE1; |
247 | } else { |
248 | /* |
249 | * Subtract NEG - NEG |
250 | */ |
251 | subtract = NS_TRUE1; |
252 | isNegative = t0p.sec < t1p.sec |
253 | || (t1p.sec == t0p.sec && (t0p.usec < t1p.usec)); |
254 | if (isNegative) { |
255 | t0Ptr = &t0p; |
256 | t1Ptr = &t1p; |
257 | } else { |
258 | t0Ptr = &t1p; |
259 | t1Ptr = &t0p; |
260 | } |
261 | } |
262 | } |
263 | |
264 | if (subtract) { |
265 | |
266 | if (t1Ptr->usec >= t0Ptr->usec) { |
267 | diffPtr->sec = t1Ptr->sec - t0Ptr->sec; |
268 | diffPtr->usec = t1Ptr->usec - t0Ptr->usec; |
269 | } else { |
270 | diffPtr->sec = t1Ptr->sec - t0Ptr->sec - 1; |
271 | if (diffPtr->sec < 0) { |
272 | diffPtr->sec = t0Ptr->sec - t1Ptr->sec; |
273 | diffPtr->usec = t0Ptr->usec - t1Ptr->usec; |
274 | } else { |
275 | diffPtr->usec = 1000000L + t1Ptr->usec - t0Ptr->usec; |
276 | } |
277 | } |
278 | } else { |
279 | |
280 | diffPtr->sec = t0p.sec + t1p.sec; |
281 | diffPtr->usec = t0p.usec + t1p.usec; |
282 | } |
283 | |
284 | if (isNegative) { |
285 | if (diffPtr->sec == 0) { |
286 | diffPtr->usec = -diffPtr->usec; |
287 | } else { |
288 | diffPtr->sec = -diffPtr->sec; |
289 | } |
290 | } |
291 | |
292 | Ns_AdjTime(diffPtr); |
293 | |
294 | if (diffPtr->sec < 0) { |
295 | return -1; |
296 | } |
297 | if (diffPtr->sec == 0) { |
298 | if (diffPtr->usec == 0) { |
299 | return 0; |
300 | } else if (diffPtr->usec < 0) { |
301 | return -1; |
302 | } |
303 | } |
304 | |
305 | return 1; |
306 | } |
307 | |
308 | |
309 | /* |
310 | *---------------------------------------------------------------------- |
311 | * |
312 | * Ns_IncrTime -- |
313 | * |
314 | * Increment the given Ns_Time structure with the given number |
315 | * of seconds and microseconds. |
316 | * |
317 | * Results: |
318 | * None. |
319 | * |
320 | * Side effects: |
321 | * None. |
322 | * |
323 | *---------------------------------------------------------------------- |
324 | */ |
325 | |
326 | void |
327 | Ns_IncrTime(Ns_Time *timePtr, time_t sec, long usec) |
328 | { |
329 | NS_NONNULL_ASSERT(timePtr != NULL)((void) (0)); |
330 | |
331 | if (unlikely(usec < 0)(__builtin_expect((usec < 0), 0)) || unlikely(sec < 0)(__builtin_expect((sec < 0), 0))) { |
332 | fprintf(stderr, "Ns_IncrTime ignores negative increment sec %" PRId64__fprintf_chk (stderr, 2 - 1, "Ns_IncrTime ignores negative increment sec %" "l" "d" " or usec %ld\n", (int64_t)sec, usec) |
333 | " or usec %ld\n", (int64_t)sec, usec)__fprintf_chk (stderr, 2 - 1, "Ns_IncrTime ignores negative increment sec %" "l" "d" " or usec %ld\n", (int64_t)sec, usec); |
334 | } else { |
335 | timePtr->sec += sec; |
336 | timePtr->usec += usec; |
337 | Ns_AdjTime(timePtr); |
338 | } |
339 | } |
340 | |
341 | |
342 | /* |
343 | *---------------------------------------------------------------------- |
344 | * |
345 | * Ns_AbsoluteTime -- |
346 | * |
347 | * Return an absolute time in the future given adjPtr. Small |
348 | * values of adjPtr are added to the current time, large values |
349 | * are assumed to be absolute already. NULL is infinity. |
350 | * |
351 | * Results: |
352 | * Pointer to absPtr if adjusted, adjPtr otherwise. |
353 | * |
354 | * Side effects: |
355 | * Ns_Time structure pointed to by absPtr may be adjusted upwards. |
356 | * |
357 | *---------------------------------------------------------------------- |
358 | */ |
359 | |
360 | Ns_Time * |
361 | Ns_AbsoluteTime(Ns_Time *absPtr, Ns_Time *adjPtr) |
362 | { |
363 | NS_NONNULL_ASSERT(absPtr != NULL)((void) (0)); |
364 | |
365 | if (adjPtr != NULL((void*)0)) { |
366 | if (adjPtr->sec < 1000000000) { |
367 | Ns_GetTime(absPtr); |
368 | Ns_IncrTime(absPtr, adjPtr->sec, adjPtr->usec); |
369 | return absPtr; |
370 | } |
371 | } |
372 | |
373 | return adjPtr; |
374 | } |
375 | |
376 | |
377 | /* |
378 | *---------------------------------------------------------------------- |
379 | * |
380 | * Ns_TimeToMilliseconds -- |
381 | * |
382 | * Convert Ns_Time to milliseconds. Make sure that in case the Ns_Time |
383 | * value is not 0, the result is also not 0. |
384 | * |
385 | * Results: |
386 | * Time in milliseconds. |
387 | * |
388 | * Side effects: |
389 | * None. |
390 | * |
391 | *---------------------------------------------------------------------- |
392 | */ |
393 | time_t |
394 | Ns_TimeToMilliseconds(const Ns_Time *timePtr) |
395 | { |
396 | time_t result; |
397 | |
398 | NS_NONNULL_ASSERT(timePtr != NULL)((void) (0)); |
399 | |
400 | if (likely(timePtr->sec >= 0)(__builtin_expect((timePtr->sec >= 0), 1))) { |
401 | result = timePtr->sec*1000 + timePtr->usec/1000; |
402 | } else { |
403 | result = timePtr->sec*1000 - timePtr->usec/1000; |
404 | } |
405 | if (result == 0 && timePtr->sec == 0 && timePtr->usec != 0) { |
406 | result = 1; |
407 | } |
408 | |
409 | return result; |
410 | } |
411 | |
412 | /* |
413 | * Local Variables: |
414 | * mode: c |
415 | * c-basic-offset: 4 |
416 | * fill-column: 78 |
417 | * indent-tabs-mode: nil |
418 | * End: |
419 | */ |