Whamcloud - gitweb
Branch HEAD
[fs/lustre-release.git] / lnet / include / libcfs / winnt / winnt-time.h
1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=4:tabstop=4:
3  *
4  * Copyright (C) 2004 Cluster File Systems, Inc.
5  *
6  * This file is part of Lustre, http://www.lustre.org.
7  *
8  * Lustre is free software; you can redistribute it and/or modify it under the
9  * terms of version 2 of the GNU General Public License as published by the
10  * Free Software Foundation.
11  *
12  * Lustre is distributed in the hope that it will be useful, but WITHOUT ANY
13  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
15  * details.
16  *
17  * You should have received a copy of the GNU General Public License along
18  * with Lustre; if not, write to the Free Software Foundation, Inc., 675 Mass
19  * Ave, Cambridge, MA 02139, USA.
20  *
21  * Implementation of portable time API for Winnt (kernel and user-level).
22  *
23  */
24
25 #ifndef __LIBCFS_WINNT_LINUX_TIME_H__
26 #define __LIBCFS_WINNT_LINUX_TIME_H__
27
28 #ifndef __LIBCFS_LIBCFS_H__
29 #error Do not #include this file directly. #include <libcfs/libcfs.h> instead
30 #endif
31
32 /* Portable time API */
33
34 /*
35  * Platform provides three opaque data-types:
36  *
37  *  cfs_time_t        represents point in time. This is internal kernel
38  *                    time rather than "wall clock". This time bears no
39  *                    relation to gettimeofday().
40  *
41  *  cfs_duration_t    represents time interval with resolution of internal
42  *                    platform clock
43  *
44  *  cfs_fs_time_t     represents instance in world-visible time. This is
45  *                    used in file-system time-stamps
46  *
47  *  cfs_time_t     cfs_time_current(void);
48  *  cfs_time_t     cfs_time_add    (cfs_time_t, cfs_duration_t);
49  *  cfs_duration_t cfs_time_sub    (cfs_time_t, cfs_time_t);
50  *  int            cfs_time_before (cfs_time_t, cfs_time_t);
51  *  int            cfs_time_beforeq(cfs_time_t, cfs_time_t);
52  *
53  *  cfs_duration_t cfs_duration_build(int64_t);
54  *
55  *  time_t         cfs_duration_sec (cfs_duration_t);
56  *  void           cfs_duration_usec(cfs_duration_t, struct timeval *);
57  *  void           cfs_duration_nsec(cfs_duration_t, struct timespec *);
58  *
59  *  void           cfs_fs_time_current(cfs_fs_time_t *);
60  *  time_t         cfs_fs_time_sec    (cfs_fs_time_t *);
61  *  void           cfs_fs_time_usec   (cfs_fs_time_t *, struct timeval *);
62  *  void           cfs_fs_time_nsec   (cfs_fs_time_t *, struct timespec *);
63  *  int            cfs_fs_time_before (cfs_fs_time_t *, cfs_fs_time_t *);
64  *  int            cfs_fs_time_beforeq(cfs_fs_time_t *, cfs_fs_time_t *);
65  *
66  *  CFS_TIME_FORMAT
67  *  CFS_DURATION_FORMAT
68  *
69  */
70
71 #define ONE_BILLION ((u_int64_t)1000000000)
72 #define ONE_MILLION ((u_int64_t)   1000000)
73
74 #define HZ (100)
75
76 struct timeval {
77         time_t          tv_sec;         /* seconds */
78         suseconds_t     tv_usec;        /* microseconds */
79 };
80
81 struct timespec {
82     ulong_ptr tv_sec;
83     ulong_ptr tv_nsec;
84 };
85
86 #ifdef __KERNEL__
87
88 #include <libcfs/winnt/portals_compat25.h>
89
90 /*
91  * Generic kernel stuff
92  */
93
94 typedef struct timeval cfs_fs_time_t;
95
96 typedef u_int64_t cfs_time_t;
97 typedef int64_t cfs_duration_t;
98
99 static inline void do_gettimeofday(struct timeval *tv)
100 {
101     LARGE_INTEGER Time;
102
103     KeQuerySystemTime(&Time);
104
105     tv->tv_sec  = (long_ptr) (Time.QuadPart / 10000000);
106     tv->tv_usec = (long_ptr) (Time.QuadPart % 10000000) / 10;
107 }
108
109 static inline cfs_time_t JIFFIES()
110 {
111     LARGE_INTEGER Tick;
112     LARGE_INTEGER Elapse;
113
114     KeQueryTickCount(&Tick);
115
116     Elapse.QuadPart  = Tick.QuadPart * KeQueryTimeIncrement();
117     Elapse.QuadPart /= (10000000 / HZ);
118
119     return Elapse.QuadPart;
120 }
121
122 static inline cfs_time_t cfs_time_current(void)
123 {
124     return JIFFIES();
125 }
126
127 static inline cfs_time_t cfs_time_current_sec(void)
128 {
129     return (JIFFIES() / HZ);
130 }
131
132 static inline cfs_time_t cfs_time_add(cfs_time_t t, cfs_duration_t d)
133 {
134     return (t + d);
135 }
136
137 static inline cfs_duration_t cfs_time_sub(cfs_time_t t1, cfs_time_t t2)
138 {
139     return (t1 - t2);
140 }
141
142 static inline int cfs_time_before(cfs_time_t t1, cfs_time_t t2)
143 {
144     return ((int64_t)t1 - (int64_t)t2) < 0; 
145 }
146
147 static inline int cfs_time_beforeq(cfs_time_t t1, cfs_time_t t2)
148 {
149     return ((int64_t)t1 - (int64_t)t2) <= 0;
150 }
151
152 static inline void cfs_fs_time_current(cfs_fs_time_t *t)
153 {
154     ULONG         Linux;
155     LARGE_INTEGER Sys;
156
157     KeQuerySystemTime(&Sys);
158
159     RtlTimeToSecondsSince1970(&Sys, &Linux);
160
161     t->tv_sec  = Linux;
162     t->tv_usec = (Sys.LowPart % 10000000) / 10;
163 }
164
165 static inline cfs_time_t cfs_fs_time_sec(cfs_fs_time_t *t)
166 {
167     return t->tv_sec;
168 }
169
170 static inline u_int64_t __cfs_fs_time_flat(cfs_fs_time_t *t)
171 {
172     return ((u_int64_t)t->tv_sec) * ONE_MILLION + t->tv_usec;
173 }
174
175 static inline int cfs_fs_time_before(cfs_fs_time_t *t1, cfs_fs_time_t *t2)
176 {
177     return (__cfs_fs_time_flat(t1) < __cfs_fs_time_flat(t2));
178 }
179
180 static inline int cfs_fs_time_beforeq(cfs_fs_time_t *t1, cfs_fs_time_t *t2)
181 {
182     return (__cfs_fs_time_flat(t1) <= __cfs_fs_time_flat(t2));
183 }
184
185 static inline cfs_duration_t cfs_time_seconds(int seconds)
186 {
187     return (cfs_duration_t)seconds * HZ;
188 }
189
190 static inline cfs_time_t cfs_duration_sec(cfs_duration_t d)
191 {
192         return d / HZ;
193 }
194
195 static inline void cfs_duration_usec(cfs_duration_t d, struct timeval *s)
196 {
197         s->tv_sec = (suseconds_t) (d / HZ);
198         s->tv_usec = (time_t)((d - (cfs_duration_t)s->tv_sec * HZ) *
199                               ONE_MILLION / HZ);
200 }
201
202 static inline void cfs_duration_nsec(cfs_duration_t d, struct timespec *s)
203 {
204         s->tv_sec = (suseconds_t) (d / HZ);
205         s->tv_nsec = (time_t)((d - (cfs_duration_t)s->tv_sec * HZ) *
206                               ONE_BILLION / HZ);
207 }
208
209 static inline void cfs_fs_time_usec(cfs_fs_time_t *t, struct timeval *v)
210 {
211         *v = *t;
212 }
213
214 static inline void cfs_fs_time_nsec(cfs_fs_time_t *t, struct timespec *s)
215 {
216         s->tv_sec  = t->tv_sec;
217         s->tv_nsec = t->tv_usec * 1000;
218 }
219
220 #define cfs_time_current_64 cfs_time_current
221 #define cfs_time_add_64     cfs_time_add
222 #define cfs_time_shift_64   cfs_time_shift
223 #define cfs_time_before_64  cfs_time_before
224 #define cfs_time_beforeq_64 cfs_time_beforeq
225
226 /*
227  * One jiffy
228  */
229 #define CFS_TICK                (1)
230
231 #define LTIME_S(t)                      (t)
232
233 #define CFS_TIME_T              "%I64u"
234 #define CFS_DURATION_T          "%I64d"
235
236 #else   /* !__KERNEL__ */
237
238 /*
239  * Liblustre. time(2) based implementation.
240  */
241 #include <libcfs/user-time.h>
242
243
244 //
245 // Time routines ...
246 //
247
248 NTSYSAPI
249 CCHAR
250 NTAPI
251 NtQuerySystemTime(
252     OUT PLARGE_INTEGER  CurrentTime
253     );
254
255
256 NTSYSAPI
257 BOOLEAN
258 NTAPI
259 RtlTimeToSecondsSince1970(
260     IN PLARGE_INTEGER  Time,
261     OUT PULONG  ElapsedSeconds
262     );
263
264
265 NTSYSAPI
266 VOID
267 NTAPI
268 RtlSecondsSince1970ToTime(
269     IN ULONG  ElapsedSeconds,
270     OUT PLARGE_INTEGER  Time
271     );
272
273 NTSYSAPI
274 VOID
275 NTAPI
276 Sleep(
277   DWORD dwMilliseconds   // sleep time in milliseconds
278 );
279
280
281 static inline void sleep(int time)
282 {
283     DWORD Time = 1000 * time;
284     Sleep(Time);
285 }
286
287
288 static inline void do_gettimeofday(struct timeval *tv)
289 {
290     LARGE_INTEGER Time;
291
292     NtQuerySystemTime(&Time);
293
294     tv->tv_sec  = (long_ptr) (Time.QuadPart / 10000000);
295     tv->tv_usec = (long_ptr) (Time.QuadPart % 10000000) / 10;
296 }
297
298 static inline int gettimeofday(struct timeval *tv, void * tz)
299 {
300     do_gettimeofday(tv);
301     return 0;
302 }
303
304 #endif /* __KERNEL__ */
305
306 /* __LIBCFS_LINUX_LINUX_TIME_H__ */
307 #endif
308 /*
309  * Local variables:
310  * c-indentation-style: "K&R"
311  * c-basic-offset: 8
312  * tab-width: 8
313  * fill-column: 80
314  * scroll-step: 1
315  * End:
316  */