2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
10 /* Elapsed time package */
11 /* This package maintains a clock which is independent of the time of day. It uses the 4.3BSD interval timer (getitimer/setitimer) in TIMER_REAL mode. Any other use of the timer voids this package's warranty. */
17 #if defined(AFS_AIX_ENV) || defined(AFS_AUX_ENV)
18 #include "../h/systm.h"
19 #include "../h/time.h"
25 #endif /* ITIMER_REAL */
28 #include <afs/afsutil.h>
32 /* Some macros to make macros more reasonable (this allows a block to be used within a macro which does not cause if statements to screw up). That is, you can use "if (...) macro_name(); else ...;" without having things blow up on the semi-colon. */
36 #define END } while(0)
39 /* A clock value is the number of seconds and microseconds that have elapsed since calling clock_Init. */
41 afs_int32 sec; /* Seconds since clock_Init */
42 afs_int32 usec; /* Microseconds since clock_Init */
46 #if defined(AFS_USE_GETTIMEOFDAY) || defined(AFS_PTHREAD_ENV)
48 #define clock_NewTime()
49 #define clock_UpdateTime()
50 #define clock_GetTime(cv) (gettimeofday((struct timeval *)cv, NULL))
51 #define clock_Sec() (time(NULL))
52 #define clock_haveCurrentTime 1
53 #else /* AFS_USE_GETTIMEOFDAY || AFS_PTHREAD_ENV */
55 /* For internal use. The last value returned from clock_GetTime() */
56 extern struct clock clock_now;
58 /* For internal use: this flag, if set, indicates a new time should be read by clock_getTime() */
59 extern int clock_haveCurrentTime;
61 /* For external use: the number of times the clock value is actually updated */
62 extern int clock_nUpdates;
64 /* Initialize the clock package */
65 extern void clock_Init();
67 #define clock_NewTime() (clock_haveCurrentTime = 0)
69 /* Update the value to be returned by gettime */
70 extern void clock_UpdateTime();
72 /* Return the current clock time. If the clock value has not been updated since the last call to clock_NewTime, it is updated now */
73 #define clock_GetTime(cv) \
75 if (!clock_haveCurrentTime) clock_UpdateTime(); \
76 (cv)->sec = clock_now.sec; \
77 (cv)->usec = clock_now.usec; \
80 /* Current clock time, truncated to seconds */
81 #define clock_Sec() ((!clock_haveCurrentTime)? clock_UpdateTime(), clock_now.sec:clock_now.sec)
82 #endif /* AFS_USE_GETTIMEOFDAY || AFS_PTHREAD_ENV */
84 #include "../afs/afs_osi.h"
86 #if defined(AFS_SGI61_ENV) || defined(AFS_HPUX_ENV) || defined(AFS_LINUX_64BIT_KERNEL)
87 #define clock_GetTime(cv) osi_GetTime((osi_timeval_t *)cv)
89 #define clock_GetTime(cv) osi_GetTime((struct timeval *)cv)
91 #define clock_Sec() osi_Time()
92 #define clock_NewTime() /* don't do anything; clock is fast enough in kernel */
95 /* Returns the elapsed time in milliseconds between clock values (*cv1) and (*cv2) */
96 #define clock_ElapsedTime(cv1, cv2) \
97 (((cv2)->sec - (cv1)->sec)*1000 + ((cv2)->usec - (cv1)->usec)/1000)
99 #ifdef AFS_PTHREAD_ENV
100 #define clock_Advance(cv)
102 /* Advance the known value of the current clock time (clock_now) by the specified clock value */
103 #define clock_Advance(cv) clock_Add(&clock_now, cv)
104 #endif /* AFS_PTHREAD_ENV */
106 /* Some comparison operators for clock values */
107 #define clock_Gt(a, b) ((a)->sec>(b)->sec || (a)->sec==(b)->sec && (a)->usec>(b)->usec)
108 #define clock_Ge(a, b) ((a)->sec>(b)->sec || (a)->sec==(b)->sec && (a)->usec>=(b)->usec)
109 #define clock_Eq(a, b) ((a)->sec==(b)->sec && (a)->usec==(b)->usec)
110 #define clock_Le(a, b) ((a)->sec<(b)->sec || (a)->sec==(b)->sec && (a)->usec<=(b)->usec)
111 #define clock_Lt(a, b) ((a)->sec<(b)->sec || (a)->sec==(b)->sec && (a)->usec<(b)->usec)
113 /* Is the clock value zero? */
114 #define clock_IsZero(c) ((c)->sec == 0 && (c)->usec == 0)
116 /* Set the clock value to zero */
117 #define clock_Zero(c) ((c)->sec = (c)->usec = 0)
119 /* Add time c2 to time c1. Both c2 and c1 must be positive times. */
120 #define clock_Add(c1, c2) \
122 if (((c1)->usec += (c2)->usec) >= 1000000) { \
123 (c1)->usec -= 1000000; \
126 (c1)->sec += (c2)->sec; \
129 #define MSEC(cp) ((cp->sec * 1000) + (cp->usec / 1000))
131 /* Add ms milliseconds to time c1. Both ms and c1 must be positive */
132 #define clock_Addmsec(c1, ms) \
134 if ((ms) >= 1000) { \
135 (c1)->sec += (afs_int32)((ms) / 1000); \
136 (c1)->usec += (afs_int32)(((ms) % 1000) * 1000); \
138 (c1)->usec += (afs_int32)((ms) * 1000); \
140 if ((c1)->usec >= 1000000) { \
141 (c1)->usec -= 1000000; \
146 /* Subtract time c2 from time c1. c2 should be less than c1 */
147 #define clock_Sub(c1, c2) \
149 if (((c1)->usec -= (c2)->usec) < 0) { \
150 (c1)->usec += 1000000; \
153 (c1)->sec -= (c2)->sec; \
156 #define clock_Float(c) ((c)->sec + (c)->usec/1e6)
158 /* Add square of time c2 to time c1. Both c2 and c1 must be positive times. */
159 #define clock_AddSq(c1, c2) \
163 (c1)->sec += (c2)->sec * (c2)->sec \
164 + 2 * (c2)->sec * (c2)->usec /1000000; \
165 (c1)->usec += (2 * (c2)->sec * (c2)->usec) % 1000000 \
166 + ((c2)->usec / 1000)*((c2)->usec / 1000) \
167 + 2 * ((c2)->usec / 1000) * ((c2)->usec % 1000) / 1000 \
168 + ((((c2)->usec % 1000) > 707) ? 1 : 0); \
172 (c1)->usec += ((c2)->usec / 1000)*((c2)->usec / 1000) \
173 + 2 * ((c2)->usec / 1000) * ((c2)->usec % 1000) / 1000 \
174 + ((((c2)->usec % 1000) > 707) ? 1 : 0); \
176 if ((c1)->usec > 1000000) { \
177 (c1)->usec -= 1000000; \