Import Upstream version 1.8.5
[hcoop/debian/openafs.git] / src / rx / rx_clock.h
1 /*
2 * Copyright 2000, International Business Machines Corporation and others.
3 * All Rights Reserved.
4 *
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
8 */
9
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. */
12
13 #ifndef _CLOCK_
14 #define _CLOCK_
15
16 #ifdef KERNEL
17 #if defined(AFS_AIX_ENV) || defined(AFS_AUX_ENV) || defined(AFS_SUN5_ENV)
18 #include "h/systm.h"
19 #include "h/time.h"
20 #endif /* System V */
21 #else /* KERNEL */
22 #ifndef AFS_NT40_ENV
23 #ifndef ITIMER_REAL
24 #include <sys/time.h>
25 #endif /* ITIMER_REAL */
26 #else
27 #include <time.h>
28 #include <afs/afsutil.h>
29 #endif
30 #endif /* KERNEL */
31
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. */
33
34 #ifndef BEGIN
35 #define BEGIN do {
36 #define END } while(0)
37 #endif
38
39 /* A clock value is the number of seconds and microseconds that have elapsed since calling clock_Init. */
40 struct clock {
41 afs_int32 sec; /* Seconds since clock_Init */
42 afs_int32 usec; /* Microseconds since clock_Init */
43 };
44
45 #if defined(KERNEL)
46 #include "afs/afs_osi.h"
47 #endif
48 #if !defined(KERNEL) || defined(UKERNEL)
49 #if defined(AFS_USE_GETTIMEOFDAY) || defined(AFS_PTHREAD_ENV) || defined(UKERNEL)
50 #define clock_Init()
51 #define clock_NewTime()
52 #define clock_UpdateTime()
53 #define clock_Sec() (time(NULL))
54 #define clock_haveCurrentTime 1
55
56 #define clock_GetTime(cv) \
57 BEGIN \
58 struct timeval tv; \
59 gettimeofday(&tv, NULL); \
60 (cv)->sec = (afs_int32)tv.tv_sec; \
61 (cv)->usec = (afs_int32)tv.tv_usec; \
62 END
63
64 #else /* AFS_USE_GETTIMEOFDAY || AFS_PTHREAD_ENV */
65
66 /* For internal use. The last value returned from clock_GetTime() */
67 extern struct clock clock_now;
68
69 /* For internal use: this flag, if set, indicates a new time should be read by clock_getTime() */
70 extern int clock_haveCurrentTime;
71
72 /* For external use: the number of times the clock value is actually updated */
73 extern int clock_nUpdates;
74
75 /* Initialize the clock package */
76
77 #define clock_NewTime() (clock_haveCurrentTime = 0)
78
79 /* Return the current clock time. If the clock value has not been updated since the last call to clock_NewTime, it is updated now */
80 #define clock_GetTime(cv) \
81 BEGIN \
82 if (!clock_haveCurrentTime) clock_UpdateTime(); \
83 (cv)->sec = clock_now.sec; \
84 (cv)->usec = clock_now.usec; \
85 END
86
87 /* Current clock time, truncated to seconds */
88 #define clock_Sec() ((!clock_haveCurrentTime)? clock_UpdateTime(), clock_now.sec:clock_now.sec)
89
90 extern void clock_Init(void);
91 extern int clock_UnInit(void);
92 extern void clock_UpdateTime(void);
93
94 #endif /* AFS_USE_GETTIMEOFDAY || AFS_PTHREAD_ENV */
95 #else /* KERNEL */
96 #define clock_Init()
97 #if defined(AFS_SGI61_ENV) || defined(AFS_HPUX_ENV) || defined(AFS_LINUX_64BIT_KERNEL)
98 #define clock_GetTime(cv) osi_GetTime((osi_timeval_t *)cv)
99 #else
100 #if (defined(AFS_AIX51_ENV) && defined(AFS_64BIT_KERNEL)) || (defined(AFS_DARWIN100_ENV) && defined(__amd64__)) || defined(AFS_XBSD_ENV)
101 #define clock_GetTime(cv) \
102 BEGIN \
103 struct timeval tv; \
104 osi_GetTime(&tv); \
105 (cv)->sec = (afs_int32)tv.tv_sec; \
106 (cv)->usec = (afs_int32)tv.tv_usec; \
107 END
108 #else /* defined(AFS_AIX51_ENV) && defined(AFS_64BIT_KERNEL) */
109 #define clock_GetTime(cv) osi_GetTime((osi_timeval_t *)(cv))
110 #endif /* defined(AFS_AIX51_ENV) && defined(AFS_64BIT_KERNEL) */
111 #endif
112 #define clock_Sec() osi_Time()
113 #define clock_NewTime() /* don't do anything; clock is fast enough in kernel */
114 #endif /* KERNEL */
115
116 /* Returns the elapsed time in milliseconds between clock values (*cv1) and (*cv2) */
117 #define clock_ElapsedTime(cv1, cv2) \
118 (((cv2)->sec - (cv1)->sec)*1000 + ((cv2)->usec - (cv1)->usec)/1000)
119
120 /* Some comparison operators for clock values */
121 #define clock_Gt(a, b) ((a)->sec>(b)->sec || ((a)->sec==(b)->sec && (a)->usec>(b)->usec))
122 #define clock_Ge(a, b) ((a)->sec>(b)->sec || ((a)->sec==(b)->sec && (a)->usec>=(b)->usec))
123 #define clock_Eq(a, b) ((a)->sec==(b)->sec && (a)->usec==(b)->usec)
124 #define clock_Le(a, b) ((a)->sec<(b)->sec || ((a)->sec==(b)->sec && (a)->usec<=(b)->usec))
125 #define clock_Lt(a, b) ((a)->sec<(b)->sec || ((a)->sec==(b)->sec && (a)->usec<(b)->usec))
126
127 /* Is the clock value zero? */
128 #define clock_IsZero(c) ((c)->sec == 0 && (c)->usec == 0)
129
130 /* Set the clock value to zero */
131 #define clock_Zero(c) ((c)->sec = (c)->usec = 0)
132
133 /* Add time c2 to time c1. Both c2 and c1 must be positive times. */
134 #define clock_Add(c1, c2) \
135 BEGIN \
136 (c1)->sec += (c2)->sec; \
137 if (((c1)->usec += (c2)->usec) >= 1000000) { \
138 (c1)->usec -= 1000000; \
139 (c1)->sec++; \
140 } \
141 END
142
143 #define USEC(cp) (((cp)->sec * 1000000) + (cp)->usec)
144 #define MSEC(cp) (((cp)->sec * 1000) + ((cp)->usec / 1000))
145 #define _4THMSEC(cp) (((cp)->sec * 4000) + ((cp)->usec / 250))
146 #define _8THMSEC(cp) (((cp)->sec * 8000) + ((cp)->usec / 125))
147
148 /* Add ms milliseconds to time c1. Both ms and c1 must be positive */
149 #define clock_Addmsec(c1, ms) \
150 BEGIN \
151 if ((ms) >= 1000) { \
152 (c1)->sec += (afs_int32)((ms) / 1000); \
153 (c1)->usec += (afs_int32)(((ms) % 1000) * 1000); \
154 } else { \
155 (c1)->usec += (afs_int32)((ms) * 1000); \
156 } \
157 if ((c1)->usec >= 1000000) { \
158 (c1)->usec -= 1000000; \
159 (c1)->sec++; \
160 } \
161 END
162
163 /* Subtract time c2 from time c1. c2 should be less than c1 */
164 #define clock_Sub(c1, c2) \
165 BEGIN \
166 if (((c1)->usec -= (c2)->usec) < 0) { \
167 (c1)->usec += 1000000; \
168 (c1)->sec--; \
169 } \
170 (c1)->sec -= (c2)->sec; \
171 END
172
173 #define clock_Float(c) ((c)->sec + (c)->usec/1e6)
174
175 /* Add square of time c2 to time c1. Both c2 and c1 must be positive times. */
176 #define clock_AddSq(c1, c2) \
177 BEGIN \
178 if((c2)->sec > 0 ) \
179 { \
180 (c1)->sec += (c2)->sec * (c2)->sec \
181 + 2 * (c2)->sec * (c2)->usec /1000000; \
182 (c1)->usec += (2 * (c2)->sec * (c2)->usec) % 1000000 \
183 + ((c2)->usec / 1000)*((c2)->usec / 1000) \
184 + 2 * ((c2)->usec / 1000) * ((c2)->usec % 1000) / 1000 \
185 + ((((c2)->usec % 1000) > 707) ? 1 : 0); \
186 } \
187 else \
188 { \
189 (c1)->usec += ((c2)->usec / 1000)*((c2)->usec / 1000) \
190 + 2 * ((c2)->usec / 1000) * ((c2)->usec % 1000) / 1000 \
191 + ((((c2)->usec % 1000) > 707) ? 1 : 0); \
192 } \
193 if ((c1)->usec > 1000000) { \
194 (c1)->usec -= 1000000; \
195 (c1)->sec++; \
196 } \
197 END
198
199 #endif /* _CLOCK_ */