OpenAFS
OpenAFS distributed network file system
|
00001 /* 00002 * Copyright 2000, International Business Machines Corporation and others. 00003 * All Rights Reserved. 00004 * 00005 * This software has been released under the terms of the IBM Public 00006 * License. For details, see the LICENSE file in the top-level source 00007 * directory or online at http://www.openafs.org/dl/license10.html 00008 */ 00009 00010 /* Elapsed time package */ 00011 /* 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. */ 00012 00013 #ifndef _CLOCK_ 00014 #define _CLOCK_ 00015 00016 #ifdef KERNEL 00017 #if defined(AFS_AIX_ENV) || defined(AFS_AUX_ENV) || defined(AFS_SUN5_ENV) 00018 #include "h/systm.h" 00019 #include "h/time.h" 00020 #endif /* System V */ 00021 #else /* KERNEL */ 00022 #ifndef AFS_NT40_ENV 00023 #ifndef ITIMER_REAL 00024 #include <sys/time.h> 00025 #endif /* ITIMER_REAL */ 00026 #else 00027 #include <time.h> 00028 #include <afs/afsutil.h> 00029 #endif 00030 #endif /* KERNEL */ 00031 00032 /* 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. */ 00033 00034 #ifndef BEGIN 00035 #define BEGIN do { 00036 #define END } while(0) 00037 #endif 00038 00039 /* A clock value is the number of seconds and microseconds that have elapsed since calling clock_Init. */ 00040 struct clock { 00041 afs_int32 sec; /* Seconds since clock_Init */ 00042 afs_int32 usec; /* Microseconds since clock_Init */ 00043 }; 00044 00045 #if defined(KERNEL) 00046 #include "afs/afs_osi.h" 00047 #endif 00048 #if !defined(KERNEL) || defined(UKERNEL) 00049 #if defined(AFS_USE_GETTIMEOFDAY) || defined(AFS_PTHREAD_ENV) || defined(UKERNEL) 00050 #define clock_Init() 00051 #define clock_NewTime() 00052 #define clock_UpdateTime() 00053 #define clock_Sec() (time(NULL)) 00054 #define clock_haveCurrentTime 1 00055 00056 #define clock_GetTime(cv) \ 00057 BEGIN \ 00058 struct timeval tv; \ 00059 gettimeofday(&tv, NULL); \ 00060 (cv)->sec = (afs_int32)tv.tv_sec; \ 00061 (cv)->usec = (afs_int32)tv.tv_usec; \ 00062 END 00063 00064 #else /* AFS_USE_GETTIMEOFDAY || AFS_PTHREAD_ENV */ 00065 00066 /* For internal use. The last value returned from clock_GetTime() */ 00067 extern struct clock clock_now; 00068 00069 /* For internal use: this flag, if set, indicates a new time should be read by clock_getTime() */ 00070 extern int clock_haveCurrentTime; 00071 00072 /* For external use: the number of times the clock value is actually updated */ 00073 extern int clock_nUpdates; 00074 00075 /* Initialize the clock package */ 00076 00077 #define clock_NewTime() (clock_haveCurrentTime = 0) 00078 00079 /* Return the current clock time. If the clock value has not been updated since the last call to clock_NewTime, it is updated now */ 00080 #define clock_GetTime(cv) \ 00081 BEGIN \ 00082 if (!clock_haveCurrentTime) clock_UpdateTime(); \ 00083 (cv)->sec = clock_now.sec; \ 00084 (cv)->usec = clock_now.usec; \ 00085 END 00086 00087 /* Current clock time, truncated to seconds */ 00088 #define clock_Sec() ((!clock_haveCurrentTime)? clock_UpdateTime(), clock_now.sec:clock_now.sec) 00089 00090 extern void clock_Init(void); 00091 extern int clock_UnInit(void); 00092 extern void clock_UpdateTime(void); 00093 00094 #endif /* AFS_USE_GETTIMEOFDAY || AFS_PTHREAD_ENV */ 00095 #else /* KERNEL */ 00096 #define clock_Init() 00097 #if defined(AFS_SGI61_ENV) || defined(AFS_HPUX_ENV) || defined(AFS_LINUX_64BIT_KERNEL) 00098 #define clock_GetTime(cv) osi_GetTime((osi_timeval_t *)cv) 00099 #else 00100 #if (defined(AFS_AIX51_ENV) && defined(AFS_64BIT_KERNEL)) || (defined(AFS_DARWIN100_ENV) && defined(__amd64__)) || defined(AFS_NBSD_ENV) 00101 #define clock_GetTime(cv) \ 00102 BEGIN \ 00103 struct timeval tv; \ 00104 osi_GetTime(&tv); \ 00105 (cv)->sec = (afs_int32)tv.tv_sec; \ 00106 (cv)->usec = (afs_int32)tv.tv_usec; \ 00107 END 00108 #else /* defined(AFS_AIX51_ENV) && defined(AFS_64BIT_KERNEL) */ 00109 #define clock_GetTime(cv) osi_GetTime((osi_timeval_t *)(cv)) 00110 #endif /* defined(AFS_AIX51_ENV) && defined(AFS_64BIT_KERNEL) */ 00111 #endif 00112 #define clock_Sec() osi_Time() 00113 #define clock_NewTime() /* don't do anything; clock is fast enough in kernel */ 00114 #endif /* KERNEL */ 00115 00116 /* Returns the elapsed time in milliseconds between clock values (*cv1) and (*cv2) */ 00117 #define clock_ElapsedTime(cv1, cv2) \ 00118 (((cv2)->sec - (cv1)->sec)*1000 + ((cv2)->usec - (cv1)->usec)/1000) 00119 00120 /* Some comparison operators for clock values */ 00121 #define clock_Gt(a, b) ((a)->sec>(b)->sec || ((a)->sec==(b)->sec && (a)->usec>(b)->usec)) 00122 #define clock_Ge(a, b) ((a)->sec>(b)->sec || ((a)->sec==(b)->sec && (a)->usec>=(b)->usec)) 00123 #define clock_Eq(a, b) ((a)->sec==(b)->sec && (a)->usec==(b)->usec) 00124 #define clock_Le(a, b) ((a)->sec<(b)->sec || ((a)->sec==(b)->sec && (a)->usec<=(b)->usec)) 00125 #define clock_Lt(a, b) ((a)->sec<(b)->sec || ((a)->sec==(b)->sec && (a)->usec<(b)->usec)) 00126 00127 /* Is the clock value zero? */ 00128 #define clock_IsZero(c) ((c)->sec == 0 && (c)->usec == 0) 00129 00130 /* Set the clock value to zero */ 00131 #define clock_Zero(c) ((c)->sec = (c)->usec = 0) 00132 00133 /* Add time c2 to time c1. Both c2 and c1 must be positive times. */ 00134 #define clock_Add(c1, c2) \ 00135 BEGIN \ 00136 (c1)->sec += (c2)->sec; \ 00137 if (((c1)->usec += (c2)->usec) >= 1000000) { \ 00138 (c1)->usec -= 1000000; \ 00139 (c1)->sec++; \ 00140 } \ 00141 END 00142 00143 #define USEC(cp) (((cp)->sec * 1000000) + (cp)->usec) 00144 #define MSEC(cp) (((cp)->sec * 1000) + ((cp)->usec / 1000)) 00145 #define _4THMSEC(cp) (((cp)->sec * 4000) + ((cp)->usec / 250)) 00146 #define _8THMSEC(cp) (((cp)->sec * 8000) + ((cp)->usec / 125)) 00147 00148 /* Add ms milliseconds to time c1. Both ms and c1 must be positive */ 00149 #define clock_Addmsec(c1, ms) \ 00150 BEGIN \ 00151 if ((ms) >= 1000) { \ 00152 (c1)->sec += (afs_int32)((ms) / 1000); \ 00153 (c1)->usec += (afs_int32)(((ms) % 1000) * 1000); \ 00154 } else { \ 00155 (c1)->usec += (afs_int32)((ms) * 1000); \ 00156 } \ 00157 if ((c1)->usec >= 1000000) { \ 00158 (c1)->usec -= 1000000; \ 00159 (c1)->sec++; \ 00160 } \ 00161 END 00162 00163 /* Subtract time c2 from time c1. c2 should be less than c1 */ 00164 #define clock_Sub(c1, c2) \ 00165 BEGIN \ 00166 if (((c1)->usec -= (c2)->usec) < 0) { \ 00167 (c1)->usec += 1000000; \ 00168 (c1)->sec--; \ 00169 } \ 00170 (c1)->sec -= (c2)->sec; \ 00171 END 00172 00173 #define clock_Float(c) ((c)->sec + (c)->usec/1e6) 00174 00175 /* Add square of time c2 to time c1. Both c2 and c1 must be positive times. */ 00176 #define clock_AddSq(c1, c2) \ 00177 BEGIN \ 00178 if((c2)->sec > 0 ) \ 00179 { \ 00180 (c1)->sec += (c2)->sec * (c2)->sec \ 00181 + 2 * (c2)->sec * (c2)->usec /1000000; \ 00182 (c1)->usec += (2 * (c2)->sec * (c2)->usec) % 1000000 \ 00183 + ((c2)->usec / 1000)*((c2)->usec / 1000) \ 00184 + 2 * ((c2)->usec / 1000) * ((c2)->usec % 1000) / 1000 \ 00185 + ((((c2)->usec % 1000) > 707) ? 1 : 0); \ 00186 } \ 00187 else \ 00188 { \ 00189 (c1)->usec += ((c2)->usec / 1000)*((c2)->usec / 1000) \ 00190 + 2 * ((c2)->usec / 1000) * ((c2)->usec % 1000) / 1000 \ 00191 + ((((c2)->usec % 1000) > 707) ? 1 : 0); \ 00192 } \ 00193 if ((c1)->usec > 1000000) { \ 00194 (c1)->usec -= 1000000; \ 00195 (c1)->sec++; \ 00196 } \ 00197 END 00198 00199 #endif /* _CLOCK_ */