OpenAFS
OpenAFS distributed network file system
/cygdrive/c/src/openafs/openafs.git/repo/src/rx/rx_clock.h
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_ */
 All Data Structures Files Functions Variables