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