Bug Summary

File:thread/time.c
Warning:line 188, column 5
Duplicate code detected
Note:line 202, column 5
Similar code here

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name time.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/home/isvv/naviserver/nsthread -resource-dir /usr/local/lib/clang/15.0.0 -D _FORTIFY_SOURCE=2 -D NDEBUG -D SYSTEM_MALLOC -I ../include -I /usr/include/tcl8.6 -D HAVE_CONFIG_H -internal-isystem /usr/local/lib/clang/15.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/11/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -std=c99 -fdebug-compilation-dir=/home/isvv/naviserver/nsthread -ferror-limit 19 -stack-protector 2 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker alpha -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2022-07-23-130959-11103-1 -x c time.c
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
56void
57Ns_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
73void
74Ns_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
102void
103Ns_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
143void
144Ns_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
175long
176Ns_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
326void
327Ns_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
360Ns_Time *
361Ns_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 */
393time_t
394Ns_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 */