Whamcloud - gitweb
Mass conversion of all copyright messages to Oracle.
[fs/lustre-release.git] / libcfs / include / libcfs / darwin / darwin-time.h
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  * GPL HEADER START
5  *
6  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License version 2 only,
10  * as published by the Free Software Foundation.
11  *
12  * This program is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * General Public License version 2 for more details (a copy is included
16  * in the LICENSE file that accompanied this code).
17  *
18  * You should have received a copy of the GNU General Public License
19  * version 2 along with this program; If not, see
20  * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
21  *
22  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
23  * CA 95054 USA or visit www.sun.com if you need additional information or
24  * have any questions.
25  *
26  * GPL HEADER END
27  */
28 /*
29  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
30  * Use is subject to license terms.
31  */
32 /*
33  * This file is part of Lustre, http://www.lustre.org/
34  * Lustre is a trademark of Sun Microsystems, Inc.
35  *
36  * libcfs/include/libcfs/darwin/darwin-time.h
37  *
38  * Implementation of portable time API for XNU kernel
39  *
40  * Author: Nikita Danilov <nikita@clusterfs.com>
41  */
42
43 #ifndef __LIBCFS_DARWIN_DARWIN_TIME_H__
44 #define __LIBCFS_DARWIN_DARWIN_TIME_H__
45
46 #ifndef __LIBCFS_LIBCFS_H__
47 #error Do not #include this file directly. #include <libcfs/libcfs.h> instead
48 #endif
49
50 /* Portable time API */
51
52 /*
53  * Platform provides three opaque data-types:
54  *
55  *  cfs_time_t        represents point in time. This is internal kernel
56  *                    time rather than "wall clock". This time bears no
57  *                    relation to gettimeofday().
58  *
59  *  cfs_duration_t    represents time interval with resolution of internal
60  *                    platform clock
61  *
62  *  cfs_fs_time_t     represents instance in world-visible time. This is
63  *                    used in file-system time-stamps
64  *
65  *  cfs_time_t     cfs_time_current(void);
66  *  cfs_time_t     cfs_time_add    (cfs_time_t, cfs_duration_t);
67  *  cfs_duration_t cfs_time_sub    (cfs_time_t, cfs_time_t);
68  *  int            cfs_time_before (cfs_time_t, cfs_time_t);
69  *  int            cfs_time_beforeq(cfs_time_t, cfs_time_t);
70  *
71  *  cfs_duration_t cfs_duration_build(int64_t);
72  *
73  *  time_t         cfs_duration_sec (cfs_duration_t);
74  *  void           cfs_duration_usec(cfs_duration_t, struct timeval *);
75  *  void           cfs_duration_nsec(cfs_duration_t, struct timespec *);
76  *
77  *  void           cfs_fs_time_current(cfs_fs_time_t *);
78  *  time_t         cfs_fs_time_sec    (cfs_fs_time_t *);
79  *  void           cfs_fs_time_usec   (cfs_fs_time_t *, struct timeval *);
80  *  void           cfs_fs_time_nsec   (cfs_fs_time_t *, struct timespec *);
81  *  int            cfs_fs_time_before (cfs_fs_time_t *, cfs_fs_time_t *);
82  *  int            cfs_fs_time_beforeq(cfs_fs_time_t *, cfs_fs_time_t *);
83  *
84  *  CFS_TIME_FORMAT
85  *  CFS_DURATION_FORMAT
86  *
87  */
88
89 #define ONE_BILLION ((u_int64_t)1000000000)
90 #define ONE_MILLION 1000000
91
92 #ifdef __KERNEL__
93 #include <sys/types.h>
94 #include <sys/systm.h>
95
96 #include <sys/kernel.h>
97
98 #include <mach/mach_types.h>
99 #include <mach/time_value.h>
100 #include <kern/clock.h>
101 #include <sys/param.h>
102
103 #include <libcfs/darwin/darwin-types.h>
104 #include <libcfs/darwin/darwin-utils.h>
105 #include <libcfs/darwin/darwin-lock.h>
106
107 /*
108  * There are three way to measure time in OS X:
109  * 1. nanoseconds
110  * 2. absolute time (abstime unit equal to the length of one bus cycle),
111  *    schedule of thread/timer are counted by absolute time, but abstime
112  *    in different mac can be different also, so we wouldn't use it.
113  * 3. clock interval (1sec = 100hz). But clock interval only taken by KPI
114  *    like tsleep().
115  *
116  * We use nanoseconds (uptime, not calendar time)
117  *
118  * clock_get_uptime()   :get absolute time since bootup.
119  * nanouptime()         :get nanoseconds since bootup
120  * microuptime()        :get microseonds since bootup
121  * nanotime()           :get nanoseconds since epoch
122  * microtime()          :get microseconds since epoch
123  */
124 typedef u_int64_t cfs_time_t; /* nanoseconds */
125 typedef int64_t cfs_duration_t;
126
127 #define CFS_TIME_T              "%llu"
128 #define CFS_DURATION_T          "%lld"
129
130 typedef struct timeval cfs_fs_time_t;
131
132 static inline cfs_time_t cfs_time_current(void)
133 {
134         struct timespec instant;
135
136         nanouptime(&instant);
137         return ((u_int64_t)instant.tv_sec) * NSEC_PER_SEC + instant.tv_nsec;
138 }
139
140 static inline time_t cfs_time_current_sec(void)
141 {
142         struct timespec instant;
143
144         nanouptime(&instant);
145         return instant.tv_sec;
146 }
147
148 static inline cfs_time_t cfs_time_add(cfs_time_t t, cfs_duration_t d)
149 {
150         return t + d;
151 }
152
153 static inline cfs_duration_t cfs_time_sub(cfs_time_t t1, cfs_time_t t2)
154 {
155         return t1 - t2;
156 }
157
158 static inline int cfs_time_before(cfs_time_t t1, cfs_time_t t2)
159 {
160         return (int64_t)t1 - (int64_t)t2 < 0;
161 }
162
163 static inline int cfs_time_beforeq(cfs_time_t t1, cfs_time_t t2)
164 {
165         return (int64_t)t1 - (int64_t)t2 <= 0;
166 }
167
168 static inline void cfs_fs_time_current(cfs_fs_time_t *t)
169 {
170         microtime((struct timeval *)t);
171 }
172
173 static inline time_t cfs_fs_time_sec(cfs_fs_time_t *t)
174 {
175         return t->tv_sec;
176 }
177
178 static inline void cfs_fs_time_usec(cfs_fs_time_t *t, struct timeval *v)
179 {
180         *v = *t;
181 }
182
183 static inline void cfs_fs_time_nsec(cfs_fs_time_t *t, struct timespec *s)
184 {
185         s->tv_sec  = t->tv_sec;
186         s->tv_nsec = t->tv_usec * NSEC_PER_USEC;
187 }
188
189 static inline cfs_duration_t cfs_time_seconds(int seconds)
190 {
191         return (NSEC_PER_SEC * (int64_t)seconds);
192 }
193
194 /*
195  * internal helper function used by cfs_fs_time_before*()
196  */
197 static inline int64_t __cfs_fs_time_flat(cfs_fs_time_t *t)
198 {
199         return ((int64_t)t->tv_sec)*NSEC_PER_SEC + t->tv_usec*NSEC_PER_USEC;
200 }
201
202 static inline int cfs_fs_time_before(cfs_fs_time_t *t1, cfs_fs_time_t *t2)
203 {
204         return __cfs_fs_time_flat(t1) - __cfs_fs_time_flat(t2) < 0;
205 }
206
207 static inline int cfs_fs_time_beforeq(cfs_fs_time_t *t1, cfs_fs_time_t *t2)
208 {
209         return __cfs_fs_time_flat(t1) - __cfs_fs_time_flat(t2) <= 0;
210 }
211
212 static inline time_t cfs_duration_sec(cfs_duration_t d)
213 {
214         return d / NSEC_PER_SEC;
215 }
216
217 static inline void cfs_duration_usec(cfs_duration_t d, struct timeval *s)
218 {
219         s->tv_sec = d / NSEC_PER_SEC;
220         s->tv_usec = (d - ((int64_t)s->tv_sec) * NSEC_PER_SEC) / NSEC_PER_USEC;
221 }
222
223 static inline void cfs_duration_nsec(cfs_duration_t d, struct timespec *s)
224 {
225         s->tv_sec = d / NSEC_PER_SEC;
226         s->tv_nsec = d - ((int64_t)s->tv_sec) * NSEC_PER_SEC;
227 }
228
229 #define cfs_time_current_64 cfs_time_current
230 #define cfs_time_add_64     cfs_time_add
231 #define cfs_time_shift_64   cfs_time_shift
232 #define cfs_time_before_64  cfs_time_before
233 #define cfs_time_beforeq_64 cfs_time_beforeq
234
235 /* 
236  * One jiffy (in nanoseconds)
237  *
238  * osfmk/kern/sched_prim.c
239  * #define DEFAULT_PREEMPTION_RATE      100
240  */
241 #define CFS_TICK                (NSEC_PER_SEC / (u_int64_t)100)
242
243 #define LTIME_S(t)              (t)
244
245 /* __KERNEL__ */
246 #else
247
248 /*
249  * User level
250  */
251 #include <libcfs/user-time.h>
252
253 /* __KERNEL__ */
254 #endif
255
256 /* __LIBCFS_DARWIN_DARWIN_TIME_H__ */
257 #endif
258 /*
259  * Local variables:
260  * c-indentation-style: "K&R"
261  * c-basic-offset: 8
262  * tab-width: 8
263  * fill-column: 80
264  * scroll-step: 1
265  * End:
266  */