Commit | Line | Data |
---|---|---|
805e021f CE |
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 | /* | |
11 | * fasttime.c -- Get the time of day quickly by mapping the kernel's | |
12 | * time of day variable. | |
13 | * | |
14 | * 6 January 1986 | |
15 | * | |
16 | * Modification History | |
17 | * 3/21/86: Added FT_ApproxTime which returns the last time | |
18 | * in seconds returned by RT_FastTime. The intent is to give | |
19 | * routines which aren't too concerned about the exact time | |
20 | * fast access to the time, even on kernels without mmap. | |
21 | * 4/2/86: Fixed my previous mod and fixed FT_Init so it doesn't initialize | |
22 | * a second time if explicitly called after being implicitly called. | |
23 | * This saves a (precious) file descriptor. | |
24 | */ | |
25 | ||
26 | #include <afsconfig.h> | |
27 | #include <afs/param.h> | |
28 | ||
29 | #include <roken.h> | |
30 | ||
31 | int ft_debug; | |
32 | ||
33 | #define TRUE 1 | |
34 | #define FALSE 0 | |
35 | ||
36 | static enum InitState { notTried, tried, done } initState = notTried; | |
37 | ||
38 | struct timeval FT_LastTime; /* last time returned by RT_FastTime. Used to implement | |
39 | * FT_ApproxTime */ | |
40 | ||
41 | ||
42 | /* Call this to get the memory mapped. It will return -1 if anything went | |
43 | wrong. In that case, calls to FT_GetTimeOfDay will call gettimeofday | |
44 | instead. If printErrors is true, errors in initialization will cause | |
45 | error messages to be printed on stderr. If notReally is true, then | |
46 | things are set up so that all calls to FT_GetTimeOfDay call gettimeofday. | |
47 | You might want this if your program won't run too long and the nlist | |
48 | call is too expensive. Yeah, it's pretty horrible. | |
49 | */ | |
50 | int | |
51 | FT_Init(int printErrors, int notReally) | |
52 | { | |
53 | if (initState != notTried && !notReally) | |
54 | return (initState == done ? 0 : -1); /* This is in case explicit initialization | |
55 | * occurs after automatic initialization */ | |
56 | initState = tried; | |
57 | if (notReally) | |
58 | return 0; /* fake success, but leave initState | |
59 | * wrong. */ | |
60 | if (printErrors) | |
61 | fprintf(stderr, "FT_Init: mmap not implemented on this kernel\n"); | |
62 | return (-1); | |
63 | } | |
64 | ||
65 | /* Call this to get the time of day. It will automatically initialize the | |
66 | first time you call it. If you want error messages when you initialize, | |
67 | call FT_Init yourself. If the initialization failed, this will just | |
68 | call gettimeofday. If you ask for the timezone info, this routine will | |
69 | punt to gettimeofday. */ | |
70 | int | |
71 | FT_GetTimeOfDay(struct timeval *tv, struct timezone *tz) | |
72 | { | |
73 | int ret; | |
74 | ret = gettimeofday(tv, tz); | |
75 | if (!ret) { | |
76 | /* need to bounds check 'cause Unix can fail these checks, (esp on Suns) | |
77 | * and time package can generate invalid (to select syscall) values | |
78 | * for the time until the next interesting event if it encounters | |
79 | * out of range microsecond fields */ | |
80 | if (tv->tv_usec < 0) | |
81 | tv->tv_usec = 0; | |
82 | if (tv->tv_usec > 999999) | |
83 | tv->tv_usec = 999999; | |
84 | FT_LastTime.tv_sec = tv->tv_sec; | |
85 | FT_LastTime.tv_usec = tv->tv_usec; | |
86 | } | |
87 | return ret; | |
88 | } | |
89 | ||
90 | ||
91 | /* For compatibility. Should go away. */ | |
92 | int | |
93 | TM_GetTimeOfDay(struct timeval *tv, struct timezone *tz) | |
94 | { | |
95 | return FT_GetTimeOfDay(tv, tz); | |
96 | } | |
97 | ||
98 | int | |
99 | FT_AGetTimeOfDay(struct timeval *tv, struct timezone *tz) | |
100 | { | |
101 | if (FT_LastTime.tv_sec) { | |
102 | tv->tv_sec = FT_LastTime.tv_sec; | |
103 | tv->tv_usec = FT_LastTime.tv_usec; | |
104 | return 0; | |
105 | } | |
106 | return FT_GetTimeOfDay(tv, tz); | |
107 | } | |
108 | ||
109 | #ifdef AFS_PTHREAD_ENV | |
110 | unsigned int FT_ApproxTime(void) | |
111 | { | |
112 | return time(0); | |
113 | } | |
114 | #else | |
115 | unsigned int | |
116 | FT_ApproxTime(void) | |
117 | { | |
118 | if (!FT_LastTime.tv_sec) { | |
119 | FT_GetTimeOfDay(&FT_LastTime, 0); | |
120 | } | |
121 | return FT_LastTime.tv_sec; | |
122 | } | |
123 | #endif |