Initial IBM OpenAFS 1.0 tree
[openafs.git] / src / rx / rx_clock.h
1
2 /*
3 ****************************************************************************
4 *        Copyright IBM Corporation 1988, 1989 - All Rights Reserved        *
5 *                                                                          *
6 * Permission to use, copy, modify, and distribute this software and its    *
7 * documentation for any purpose and without fee is hereby granted,         *
8 * provided that the above copyright notice appear in all copies and        *
9 * that both that copyright notice and this permission notice appear in     *
10 * supporting documentation, and that the name of IBM not be used in        *
11 * advertising or publicity pertaining to distribution of the software      *
12 * without specific, written prior permission.                              *
13 *                                                                          *
14 * IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL *
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL IBM *
16 * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY      *
17 * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER  *
18 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING   *
19 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.    *
20 ****************************************************************************
21 */
22
23 /* Elapsed time package */
24 /* 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. */
25
26 #ifndef _CLOCK_
27 #define _CLOCK_
28
29 #ifdef  KERNEL
30 #if defined(AFS_AIX_ENV) || defined(AFS_AUX_ENV)
31 #include "../h/systm.h"
32 #include "../h/time.h"
33 #endif  /* System V */
34 #else /* KERNEL */
35 #ifndef AFS_NT40_ENV
36 #ifndef ITIMER_REAL
37 #include <sys/time.h>
38 #endif /* ITIMER_REAL */
39 #else
40 #include <time.h>
41 #include <afs/afsutil.h>
42 #endif
43 #endif /* KERNEL */
44
45 /* 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. */
46
47 #ifndef BEGIN
48 #define BEGIN do {
49 #define END } while(0)
50 #endif
51
52 /* A clock value is the number of seconds and microseconds that have elapsed since calling clock_Init. */
53 struct clock {
54     afs_int32 sec;          /* Seconds since clock_Init */
55     afs_int32 usec;         /* Microseconds since clock_Init */
56 };
57
58 #ifndef KERNEL
59 #if defined(AFS_USE_GETTIMEOFDAY) || defined(AFS_PTHREAD_ENV)
60 #define clock_Init()
61 #define clock_NewTime()
62 #define clock_UpdateTime()
63 #define clock_GetTime(cv) (gettimeofday((struct timeval *)cv, NULL))
64 #define clock_Sec() (time(NULL))
65 #define clock_haveCurrentTime 1
66 #else /* AFS_USE_GETTIMEOFDAY || AFS_PTHREAD_ENV */
67
68 /* For internal use.  The last value returned from clock_GetTime() */
69 extern struct clock clock_now;
70
71 /* For internal use:  this flag, if set, indicates a new time should be read by clock_getTime() */
72 extern int clock_haveCurrentTime;
73
74 /* For external use: the number of times the clock value is actually updated */
75 extern int clock_nUpdates;
76
77 /* Initialize the clock package */
78 extern void clock_Init();
79
80 #define clock_NewTime() (clock_haveCurrentTime = 0)
81
82 /* Update the value to be returned by gettime */
83 extern void clock_UpdateTime();
84
85 /* Return the current clock time.  If the clock value has not been updated since the last call to clock_NewTime, it is updated now */
86 #define clock_GetTime(cv)                               \
87     BEGIN                                               \
88         if (!clock_haveCurrentTime) clock_UpdateTime(); \
89         (cv)->sec = clock_now.sec;                      \
90         (cv)->usec = clock_now.usec;                    \
91     END
92
93 /* Current clock time, truncated to seconds */
94 #define clock_Sec() ((!clock_haveCurrentTime)? clock_UpdateTime(), clock_now.sec:clock_now.sec)
95 #endif /* AFS_USE_GETTIMEOFDAY || AFS_PTHREAD_ENV */
96 #else /* KERNEL */
97 #include "../afs/afs_osi.h"
98 #define clock_Init()
99 #if defined(AFS_SGI61_ENV) || defined(AFS_HPUX_ENV)
100 #define clock_GetTime(cv) osi_GetTime((osi_timeval_t *)cv)
101 #else
102 #define clock_GetTime(cv) osi_GetTime((struct timeval *)cv)
103 #endif
104 #define clock_Sec() osi_Time()
105 #define clock_NewTime()    /* don't do anything; clock is fast enough in kernel */
106 #endif /* KERNEL */
107
108 /* Returns the elapsed time in milliseconds between clock values (*cv1) and (*cv2) */
109 #define clock_ElapsedTime(cv1, cv2) \
110     (((cv2)->sec - (cv1)->sec)*1000 + ((cv2)->usec - (cv1)->usec)/1000)
111
112 #ifdef AFS_PTHREAD_ENV
113 #define clock_Advance(cv)
114 #else
115 /* Advance the known value of the current clock time (clock_now) by the specified clock value */
116 #define clock_Advance(cv) clock_Add(&clock_now, cv)
117 #endif /* AFS_PTHREAD_ENV */
118
119 /* Some comparison operators for clock values */
120 #define clock_Gt(a, b)  ((a)->sec>(b)->sec || (a)->sec==(b)->sec && (a)->usec>(b)->usec)
121 #define clock_Ge(a, b)  ((a)->sec>(b)->sec || (a)->sec==(b)->sec && (a)->usec>=(b)->usec)
122 #define clock_Eq(a, b)  ((a)->sec==(b)->sec && (a)->usec==(b)->usec)
123 #define clock_Le(a, b)  ((a)->sec<(b)->sec || (a)->sec==(b)->sec && (a)->usec<=(b)->usec)
124 #define clock_Lt(a, b)  ((a)->sec<(b)->sec || (a)->sec==(b)->sec && (a)->usec<(b)->usec)
125
126 /* Is the clock value zero? */
127 #define clock_IsZero(c) ((c)->sec == 0 && (c)->usec == 0)
128
129 /* Set the clock value to zero */
130 #define clock_Zero(c)   ((c)->sec = (c)->usec = 0)
131
132 /* Add time c2 to time c1.  Both c2 and c1 must be positive times. */
133 #define clock_Add(c1, c2)                                       \
134     BEGIN                                                       \
135         if (((c1)->usec += (c2)->usec) >= 1000000) {            \
136             (c1)->usec -= 1000000;                              \
137             (c1)->sec++;                                        \
138         }                                                       \
139         (c1)->sec += (c2)->sec;                                 \
140     END
141
142 #define MSEC(cp)        ((cp->sec * 1000) + (cp->usec / 1000))
143
144 /* Add ms milliseconds to time c1.  Both ms and c1 must be positive */
145 #define clock_Addmsec(c1, ms)                                    \
146     BEGIN                                                        \
147         if ((ms) >= 1000) {                                      \
148             (c1)->sec += (afs_int32)((ms) / 1000);                       \
149             (c1)->usec += (afs_int32)(((ms) % 1000) * 1000);     \
150         } else {                                                 \
151             (c1)->usec += (afs_int32)((ms) * 1000);                      \
152         }                                                        \
153         if ((c1)->usec >= 1000000) {                             \
154             (c1)->usec -= 1000000;                               \
155             (c1)->sec++;                                         \
156         }                                                        \
157     END
158
159 /* Subtract time c2 from time c1.  c2 should be less than c1 */
160 #define clock_Sub(c1, c2)                                       \
161     BEGIN                                                       \
162         if (((c1)->usec -= (c2)->usec) < 0) {                   \
163             (c1)->usec += 1000000;                              \
164             (c1)->sec--;                                        \
165         }                                                       \
166         (c1)->sec -= (c2)->sec;                                 \
167     END
168
169 #define clock_Float(c) ((c)->sec + (c)->usec/1e6)
170
171 /* Add square of time c2 to time c1.  Both c2 and c1 must be positive times. */
172 #define clock_AddSq(c1, c2)                                                   \
173     BEGIN                                                                     \
174    if((c2)->sec > 0 )                                                         \
175      {                                                                        \
176        (c1)->sec += (c2)->sec * (c2)->sec                                     \
177                     +  2 * (c2)->sec * (c2)->usec /1000000;                   \
178        (c1)->usec += (2 * (c2)->sec * (c2)->usec) % 1000000                   \
179                      + ((c2)->usec / 1000)*((c2)->usec / 1000)                \
180                      + 2 * ((c2)->usec / 1000) * ((c2)->usec % 1000) / 1000   \
181                      + ((((c2)->usec % 1000) > 707) ? 1 : 0);                 \
182      }                                                                        \
183    else                                                                       \
184      {                                                                        \
185        (c1)->usec += ((c2)->usec / 1000)*((c2)->usec / 1000)                  \
186                      + 2 * ((c2)->usec / 1000) * ((c2)->usec % 1000) / 1000   \
187                      + ((((c2)->usec % 1000) > 707) ? 1 : 0);                 \
188      }                                                                        \
189    if ((c1)->usec > 1000000) {                                                \
190         (c1)->usec -= 1000000;                                                \
191         (c1)->sec++;                                                          \
192    }                                                                          \
193     END
194
195 #endif /* _CLOCK_ */