VirtualBox

source: vbox/trunk/src/VBox/Runtime/r0drv/linux/time-r0drv-linux.c@ 21337

Last change on this file since 21337 was 21337, checked in by vboxsync, 15 years ago

IPRT,HostDrv,AddDrv: Export public IPRT symbols for the linux kernel (pain).

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 5.2 KB
Line 
1/* $Id: time-r0drv-linux.c 21337 2009-07-07 14:58:27Z vboxsync $ */
2/** @file
3 * IPRT - Time, Ring-0 Driver, Linux.
4 */
5
6/*
7 * Copyright (C) 2006-2008 Sun Microsystems, Inc.
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 *
26 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
27 * Clara, CA 95054 USA or visit http://www.sun.com if you need
28 * additional information or have any questions.
29 */
30
31
32/*******************************************************************************
33* Header Files *
34*******************************************************************************/
35#define LOG_GROUP RTLOGGROUP_TIME
36#include "the-linux-kernel.h"
37#include "internal/iprt.h"
38#include <iprt/time.h>
39#include <iprt/asm.h>
40
41
42
43DECLINLINE(uint64_t) rtTimeGetSystemNanoTS(void)
44{
45#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 16) /* This must match timer-r0drv-linux.c! */
46 /*
47 * Use ktime_get_ts, this is also what clock_gettime(CLOCK_MONOTONIC,) is using.
48 */
49 uint64_t u64;
50 struct timespec Ts;
51 ktime_get_ts(&Ts);
52 u64 = Ts.tv_sec * UINT64_C(1000000000) + Ts.tv_nsec;
53 return u64;
54
55#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 60)
56 /*
57 * Seems there is no way of getting to the exact source of
58 * sys_clock_gettime(CLOCK_MONOTONIC, &ts) here, I think. But
59 * 64-bit jiffies adjusted for the initial value should be pretty
60 * much the same I hope.
61 */
62 uint64_t u64 = get_jiffies_64();
63# ifdef INITIAL_JIFFIES
64 u64 += INITIAL_JIFFIES;
65# endif
66 u64 *= TICK_NSEC;
67 return u64;
68
69#else /* < 2.5.60 */
70# if BITS_PER_LONG >= 64
71 /*
72 * This is the same as above, except that there is no get_jiffies_64()
73 * here and we rely on long, and therefor jiffies, being 64-bit instead.
74 */
75 uint64_t u64 = jiffies;
76# ifdef INITIAL_JIFFIES
77 u64 += INITIAL_JIFFIES;
78# endif
79 u64 *= TICK_NSEC;
80 return u64;
81
82# else /* 32 bit jiffies */
83 /*
84 * We'll have to try track jiffy rollovers here or we'll be
85 * in trouble every time it flips.
86 *
87 * The high dword of the s_u64Last is the rollover count, the
88 * low dword is the previous jiffies. Updating is done by
89 * atomic compare & exchange of course.
90 */
91 static uint64_t volatile s_u64Last = 0;
92 uint64_t u64;
93
94 for (;;)
95 {
96 uint64_t u64NewLast;
97 int32_t iDelta;
98 uint32_t cRollovers;
99 uint32_t u32LastJiffies;
100
101 /* sample the values */
102 unsigned long ulNow = jiffies;
103 uint64_t u64Last = s_u64Last;
104 if (ulNow != jiffies)
105 continue; /* try again */
106# ifdef INITIAL_JIFFIES
107 ulNow += INITIAL_JIFFIES;
108# endif
109
110 u32LastJiffies = (uint32_t)u64Last;
111 cRollovers = u64Last >> 32;
112
113 /*
114 * Check for rollover and update the static last value.
115 *
116 * We have to make sure we update it successfully to rule out
117 * an underrun because of racing someone.
118 */
119 iDelta = ulNow - u32LastJiffies;
120 if (iDelta < 0)
121 {
122 cRollovers++;
123 u64NewLast = RT_MAKE_U64(ulNow, cRollovers);
124 if (!ASMAtomicCmpXchgU64(&s_u64Last, u64NewLast, u64Last))
125 continue; /* race, try again */
126 }
127 else
128 {
129 u64NewLast = RT_MAKE_U64(ulNow, cRollovers);
130 ASMAtomicCmpXchgU64(&s_u64Last, u64NewLast, u64Last);
131 }
132
133 /* calcuate the return value */
134 u64 = ulNow;
135 u64 *= TICK_NSEC;
136 u64 += cRollovers * (_4G * TICK_NSEC);
137 break;
138 }
139
140 return u64;
141# endif /* 32 bit jiffies */
142#endif /* < 2.5.60 */
143}
144
145
146RTDECL(uint64_t) RTTimeNanoTS(void)
147{
148 return rtTimeGetSystemNanoTS();
149}
150RT_EXPORT_SYMBOL(RTTimeNanoTS);
151
152
153RTDECL(uint64_t) RTTimeMilliTS(void)
154{
155 return rtTimeGetSystemNanoTS() / 1000000;
156}
157RT_EXPORT_SYMBOL(RTTimeMilliTS);
158
159
160RTDECL(uint64_t) RTTimeSystemNanoTS(void)
161{
162 return rtTimeGetSystemNanoTS();
163}
164RT_EXPORT_SYMBOL(RTTimeSystemNanoTS);
165
166
167RTDECL(uint64_t) RTTimeSystemMilliTS(void)
168{
169 return rtTimeGetSystemNanoTS() / 1000000;
170}
171RT_EXPORT_SYMBOL(RTTimeSystemMilliTS);
172
173
174RTDECL(PRTTIMESPEC) RTTimeNow(PRTTIMESPEC pTime)
175{
176#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 16)
177 struct timespec Ts;
178 ktime_get_real_ts(&Ts);
179 return RTTimeSpecSetTimespec(pTime, &Ts);
180
181#else /* < 2.6.16 */
182 struct timeval Tv;
183 do_gettimeofday(&Tv);
184 return RTTimeSpecSetTimeval(pTime, &Tv);
185#endif
186}
187RT_EXPORT_SYMBOL(RTTimeNow);
188
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette