/* * Copyright 2000, International Business Machines Corporation and others. * All Rights Reserved. * * This software has been released under the terms of the IBM Public * License. For details, see the LICENSE file in the top-level source * directory or online at http://www.openafs.org/dl/license10.html */ /* Elapsed time package */ /* 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. */ #ifndef _CLOCK_ #define _CLOCK_ #ifdef KERNEL #if defined(AFS_AIX_ENV) || defined(AFS_AUX_ENV) || defined(AFS_SUN5_ENV) #include "h/systm.h" #include "h/time.h" #endif /* System V */ #else /* KERNEL */ #ifndef AFS_NT40_ENV #ifndef ITIMER_REAL #include #endif /* ITIMER_REAL */ #else #include #include #endif #endif /* KERNEL */ /* 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. */ #ifndef BEGIN #define BEGIN do { #define END } while(0) #endif /* A clock value is the number of seconds and microseconds that have elapsed since calling clock_Init. */ struct clock { afs_int32 sec; /* Seconds since clock_Init */ afs_int32 usec; /* Microseconds since clock_Init */ }; #if defined(KERNEL) #include "afs/afs_osi.h" #endif #if !defined(KERNEL) || defined(UKERNEL) #if defined(AFS_USE_GETTIMEOFDAY) || defined(AFS_PTHREAD_ENV) || defined(UKERNEL) #define clock_Init() #define clock_NewTime() #define clock_UpdateTime() #define clock_Sec() (time(NULL)) #define clock_haveCurrentTime 1 #define clock_GetTime(cv) \ BEGIN \ struct timeval tv; \ gettimeofday(&tv, NULL); \ (cv)->sec = (afs_int32)tv.tv_sec; \ (cv)->usec = (afs_int32)tv.tv_usec; \ END #else /* AFS_USE_GETTIMEOFDAY || AFS_PTHREAD_ENV */ /* For internal use. The last value returned from clock_GetTime() */ extern struct clock clock_now; /* For internal use: this flag, if set, indicates a new time should be read by clock_getTime() */ extern int clock_haveCurrentTime; /* For external use: the number of times the clock value is actually updated */ extern int clock_nUpdates; /* Initialize the clock package */ #define clock_NewTime() (clock_haveCurrentTime = 0) /* Return the current clock time. If the clock value has not been updated since the last call to clock_NewTime, it is updated now */ #define clock_GetTime(cv) \ BEGIN \ if (!clock_haveCurrentTime) clock_UpdateTime(); \ (cv)->sec = clock_now.sec; \ (cv)->usec = clock_now.usec; \ END /* Current clock time, truncated to seconds */ #define clock_Sec() ((!clock_haveCurrentTime)? clock_UpdateTime(), clock_now.sec:clock_now.sec) extern void clock_Init(void); extern int clock_UnInit(void); extern void clock_UpdateTime(void); #endif /* AFS_USE_GETTIMEOFDAY || AFS_PTHREAD_ENV */ #else /* KERNEL */ #define clock_Init() #if defined(AFS_SGI61_ENV) || defined(AFS_HPUX_ENV) || defined(AFS_LINUX_64BIT_KERNEL) #define clock_GetTime(cv) osi_GetTime((osi_timeval_t *)cv) #else #if (defined(AFS_AIX51_ENV) && defined(AFS_64BIT_KERNEL)) || (defined(AFS_DARWIN100_ENV) && defined(__amd64__)) || defined(AFS_NBSD_ENV) #define clock_GetTime(cv) \ BEGIN \ struct timeval tv; \ osi_GetTime(&tv); \ (cv)->sec = (afs_int32)tv.tv_sec; \ (cv)->usec = (afs_int32)tv.tv_usec; \ END #else /* defined(AFS_AIX51_ENV) && defined(AFS_64BIT_KERNEL) */ #define clock_GetTime(cv) osi_GetTime((osi_timeval_t *)(cv)) #endif /* defined(AFS_AIX51_ENV) && defined(AFS_64BIT_KERNEL) */ #endif #define clock_Sec() osi_Time() #define clock_NewTime() /* don't do anything; clock is fast enough in kernel */ #endif /* KERNEL */ /* Returns the elapsed time in milliseconds between clock values (*cv1) and (*cv2) */ #define clock_ElapsedTime(cv1, cv2) \ (((cv2)->sec - (cv1)->sec)*1000 + ((cv2)->usec - (cv1)->usec)/1000) /* Some comparison operators for clock values */ #define clock_Gt(a, b) ((a)->sec>(b)->sec || ((a)->sec==(b)->sec && (a)->usec>(b)->usec)) #define clock_Ge(a, b) ((a)->sec>(b)->sec || ((a)->sec==(b)->sec && (a)->usec>=(b)->usec)) #define clock_Eq(a, b) ((a)->sec==(b)->sec && (a)->usec==(b)->usec) #define clock_Le(a, b) ((a)->sec<(b)->sec || ((a)->sec==(b)->sec && (a)->usec<=(b)->usec)) #define clock_Lt(a, b) ((a)->sec<(b)->sec || ((a)->sec==(b)->sec && (a)->usec<(b)->usec)) /* Is the clock value zero? */ #define clock_IsZero(c) ((c)->sec == 0 && (c)->usec == 0) /* Set the clock value to zero */ #define clock_Zero(c) ((c)->sec = (c)->usec = 0) /* Add time c2 to time c1. Both c2 and c1 must be positive times. */ #define clock_Add(c1, c2) \ BEGIN \ (c1)->sec += (c2)->sec; \ if (((c1)->usec += (c2)->usec) >= 1000000) { \ (c1)->usec -= 1000000; \ (c1)->sec++; \ } \ END #define USEC(cp) (((cp)->sec * 1000000) + (cp)->usec) #define MSEC(cp) (((cp)->sec * 1000) + ((cp)->usec / 1000)) #define _4THMSEC(cp) (((cp)->sec * 4000) + ((cp)->usec / 250)) #define _8THMSEC(cp) (((cp)->sec * 8000) + ((cp)->usec / 125)) /* Add ms milliseconds to time c1. Both ms and c1 must be positive */ #define clock_Addmsec(c1, ms) \ BEGIN \ if ((ms) >= 1000) { \ (c1)->sec += (afs_int32)((ms) / 1000); \ (c1)->usec += (afs_int32)(((ms) % 1000) * 1000); \ } else { \ (c1)->usec += (afs_int32)((ms) * 1000); \ } \ if ((c1)->usec >= 1000000) { \ (c1)->usec -= 1000000; \ (c1)->sec++; \ } \ END /* Subtract time c2 from time c1. c2 should be less than c1 */ #define clock_Sub(c1, c2) \ BEGIN \ if (((c1)->usec -= (c2)->usec) < 0) { \ (c1)->usec += 1000000; \ (c1)->sec--; \ } \ (c1)->sec -= (c2)->sec; \ END #define clock_Float(c) ((c)->sec + (c)->usec/1e6) /* Add square of time c2 to time c1. Both c2 and c1 must be positive times. */ #define clock_AddSq(c1, c2) \ BEGIN \ if((c2)->sec > 0 ) \ { \ (c1)->sec += (c2)->sec * (c2)->sec \ + 2 * (c2)->sec * (c2)->usec /1000000; \ (c1)->usec += (2 * (c2)->sec * (c2)->usec) % 1000000 \ + ((c2)->usec / 1000)*((c2)->usec / 1000) \ + 2 * ((c2)->usec / 1000) * ((c2)->usec % 1000) / 1000 \ + ((((c2)->usec % 1000) > 707) ? 1 : 0); \ } \ else \ { \ (c1)->usec += ((c2)->usec / 1000)*((c2)->usec / 1000) \ + 2 * ((c2)->usec / 1000) * ((c2)->usec % 1000) / 1000 \ + ((((c2)->usec % 1000) > 707) ? 1 : 0); \ } \ if ((c1)->usec > 1000000) { \ (c1)->usec -= 1000000; \ (c1)->sec++; \ } \ END #endif /* _CLOCK_ */