allow-rx-shutdown-for-userlevel-20010212
[openafs.git] / src / rx / rx_clock.c
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 /* See rx_clock.h for calling conventions */
12
13 #ifdef  KERNEL
14 #include "../afs/param.h"
15 #ifndef UKERNEL
16 #include "../rx/rx_clock.h"
17 #include "../h/types.h"
18 #include "../h/time.h"
19 #else /* !UKERNEL */
20 #include "../afs/sysincludes.h"
21 #include "../afs/afsincludes.h"
22 #include "../rx/rx_clock.h"
23 #endif /* !UKERNEL */
24 #else /* KERNEL */
25 #include <afs/param.h>
26 #include <sys/time.h>
27 #include <stdio.h>
28 #include <errno.h>
29 #include "rx_clock.h"
30 #endif
31
32 #if     !defined(AFS_USE_GETTIMEOFDAY)
33 /*use this package only if gettimeofday is much much costlier than getitime */
34
35 #ifndef KERNEL
36
37 #if defined(AFS_GFS_ENV)
38 #define STARTVALUE 8000000      /* Ultrix bounds smaller, too small for general use */
39 #else
40 #define STARTVALUE 100000000    /* Max number of seconds setitimer allows, for some reason */
41 #endif
42
43 struct clock clock_now;         /* The last elapsed time ready by clock_GetTimer */
44
45 /* This is set to 1 whenever the time is read, and reset to 0 whenever clock_NewTime is called.  This is to allow the caller to control the frequency with which the actual time is re-evaluated (an expensive operation) */
46 int clock_haveCurrentTime;
47
48 int clock_nUpdates;             /* The actual number of clock updates */
49 static int clockInitialized = 0;
50
51 /* Initialize the clock */
52 void clock_Init(void) {
53     struct itimerval itimer, otimer;
54
55     if (!clockInitialized) {
56         itimer.it_value.tv_sec = STARTVALUE;
57         itimer.it_value.tv_usec = 0;
58         itimer.it_interval.tv_sec = 0;
59         itimer.it_interval.tv_usec = 0;
60
61         if (setitimer(ITIMER_REAL, &itimer, &otimer) != 0) {
62             fprintf(stderr, "clock:  could not set interval timer; \
63                                 aborted(errno=%d)\n", errno);
64             fflush (stderr);
65             exit(1);
66         }
67         clockInitialized = 1;
68     }
69
70     clock_UpdateTime();
71 }
72
73 #ifndef KERNEL
74 /* Make clock uninitialized. */
75 clock_UnInit()
76 {
77     clockInitialized = 0;
78
79 #endif 
80
81 /* Compute the current time.  The timer gets the current total elapsed time since startup, expressed in seconds and microseconds.  This call is almost 200 usec on an APC RT */
82 void clock_UpdateTime()
83 {
84     struct itimerval itimer;
85     getitimer(ITIMER_REAL, &itimer);
86     clock_now.sec = STARTVALUE - 1 - itimer.it_value.tv_sec; /* The "-1" makes up for adding 1000000 usec, on the next line */
87     clock_now.usec = 1000000 - itimer.it_value.tv_usec;
88     if (clock_now.usec == 1000000) clock_now.usec = 0, clock_now.sec++;
89     clock_haveCurrentTime = 1;
90     clock_nUpdates++;
91 }
92 #else /* KERNEL */
93 #endif /* KERNEL */
94
95 #endif /* AFS_USE_GETTIMEOFDAY */