2 * Time utility functions.
3 * Author: Paolo Molaro (<lupus@ximian.com>)
4 * Copyright (C) 2008 Novell, Inc.
7 #include <utils/mono-time.h>
11 #define MTICKS_PER_SEC 10000000
17 mono_msec_ticks (void)
19 /* GetTickCount () is reportedly monotonic */
20 return GetTickCount ();
23 /* Returns the number of 100ns ticks from unspecified time: this should be monotonic */
25 mono_100ns_ticks (void)
27 static LARGE_INTEGER freq;
28 static UINT64 start_time;
33 if (!QueryPerformanceFrequency (&freq))
34 return mono_100ns_datetime ();
35 QueryPerformanceCounter (&value);
36 start_time = value.QuadPart;
38 QueryPerformanceCounter (&value);
39 cur_time = value.QuadPart;
40 /* we use unsigned numbers and return the difference to avoid overflows */
41 return (cur_time - start_time) * (double)MTICKS_PER_SEC / freq.QuadPart;
45 * Magic number to convert FILETIME base Jan 1, 1601 to DateTime - base Jan, 1, 0001
47 #define FILETIME_ADJUST ((guint64)504911232000000000LL)
49 /* Returns the number of 100ns ticks since 1/1/1, UTC timezone */
51 mono_100ns_datetime (void)
55 if (sizeof(ft) != sizeof(FILETIME))
56 g_assert_not_reached ();
58 GetSystemTimeAsFileTime ((FILETIME*) &ft);
59 return FILETIME_ADJUST + ft.QuadPart;
64 #ifdef HAVE_SYS_TIME_H
68 #if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__)
69 #include <sys/param.h>
70 #include <sys/sysctl.h>
73 #if defined(PLATFORM_MACOSX)
74 #include <mach/mach.h>
75 #include <mach/mach_time.h>
83 #if defined(PLATFORM_MACOSX) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__)
87 struct timeval boottime;
92 mib [1] = KERN_BOOTTIME;
94 size = sizeof(boottime);
96 if (sysctl(mib, 2, &boottime, &size, NULL, 0) != -1)
97 return (gint64)((now - boottime.tv_sec) * MTICKS_PER_SEC);
99 FILE *uptime = fopen ("/proc/uptime", "r");
102 if (fscanf (uptime, "%lf", &upt) == 1) {
103 gint64 now = mono_100ns_ticks ();
105 return now - (gint64)(upt * MTICKS_PER_SEC);
110 /* a made up uptime of 300 seconds */
111 return (gint64)300 * MTICKS_PER_SEC;
114 /* Returns the number of milliseconds from boot time: this should be monotonic */
116 mono_msec_ticks (void)
118 static gint64 boot_time = 0;
121 boot_time = get_boot_time ();
122 now = mono_100ns_ticks ();
123 /*printf ("now: %llu (boot: %llu) ticks: %llu\n", (gint64)now, (gint64)boot_time, (gint64)(now - boot_time));*/
124 return (now - boot_time)/10000;
127 /* Returns the number of 100ns ticks from unspecified time: this should be monotonic */
129 mono_100ns_ticks (void)
132 #ifdef CLOCK_MONOTONIC
133 struct timespec tspec;
134 static struct timespec tspec_freq = {0};
135 static int can_use_clock = 0;
136 if (!tspec_freq.tv_nsec) {
137 can_use_clock = clock_getres (CLOCK_MONOTONIC, &tspec_freq) == 0;
138 /*printf ("resolution: %lu.%lu\n", tspec_freq.tv_sec, tspec_freq.tv_nsec);*/
141 if (clock_gettime (CLOCK_MONOTONIC, &tspec) == 0) {
142 /*printf ("time: %lu.%lu\n", tspec.tv_sec, tspec.tv_nsec); */
143 return ((gint64)tspec.tv_sec * MTICKS_PER_SEC + tspec.tv_nsec / 100);
147 #elif defined(PLATFORM_MACOSX)
148 /* http://developer.apple.com/library/mac/#qa/qa1398/_index.html */
149 static mach_timebase_info_data_t timebase;
150 guint64 now = mach_absolute_time ();
151 if (timebase.denom == 0) {
152 mach_timebase_info (&timebase);
153 timebase.denom *= 100; /* we return 100ns ticks */
155 return now * timebase.numer / timebase.denom;
157 if (gettimeofday (&tv, NULL) == 0)
158 return ((gint64)tv.tv_sec * 1000000 + tv.tv_usec) * 10;
163 * Magic number to convert a time which is relative to
164 * Jan 1, 1970 into a value which is relative to Jan 1, 0001.
166 #define EPOCH_ADJUST ((guint64)62135596800LL)
168 /* Returns the number of 100ns ticks since 1/1/1, UTC timezone */
170 mono_100ns_datetime (void)
173 if (gettimeofday (&tv, NULL) == 0)
174 return (((gint64)tv.tv_sec + EPOCH_ADJUST) * 1000000 + tv.tv_usec) * 10;