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;
30 if (!freq.QuadPart && !QueryPerformanceFrequency (&freq))
31 return mono_100ns_datetime ();
32 QueryPerformanceCounter (&value);
33 return value.QuadPart * MTICKS_PER_SEC / freq.QuadPart;
37 * Magic number to convert FILETIME base Jan 1, 1601 to DateTime - base Jan, 1, 0001
39 #define FILETIME_ADJUST ((guint64)504911232000000000LL)
41 /* Returns the number of 100ns ticks since 1/1/1, UTC timezone */
43 mono_100ns_datetime (void)
49 SystemTimeToFileTime (&st, &ft);
50 return (gint64) FILETIME_ADJUST + ((((gint64)ft.dwHighDateTime)<<32) | ft.dwLowDateTime);
55 #ifdef HAVE_SYS_TIME_H
64 /* FIXME: use sysctl (kern.boottime) on OSX */
65 FILE *uptime = fopen ("/proc/uptime", "r");
68 if (fscanf (uptime, "%lf", &upt) == 1) {
69 gint64 now = mono_100ns_ticks ();
71 return now - (gint64)(upt * MTICKS_PER_SEC);
75 /* a made up uptime of 300 seconds */
76 return (gint64)300 * MTICKS_PER_SEC;
79 /* Returns the number of milliseconds from boot time: this should be monotonic */
81 mono_msec_ticks (void)
83 static gint64 boot_time = 0;
86 boot_time = get_boot_time ();
87 now = mono_100ns_ticks ();
88 /*printf ("now: %llu (boot: %llu) ticks: %llu\n", (gint64)now, (gint64)boot_time, (gint64)(now - boot_time));*/
89 return (now - boot_time)/10000;
92 /* Returns the number of 100ns ticks from unspecified time: this should be monotonic */
94 mono_100ns_ticks (void)
97 #ifdef CLOCK_MONOTONIC
98 struct timespec tspec;
99 static struct timespec tspec_freq = {0};
100 static int can_use_clock = 0;
101 if (!tspec_freq.tv_nsec) {
102 can_use_clock = clock_getres (CLOCK_MONOTONIC, &tspec_freq) == 0;
103 /*printf ("resolution: %lu.%lu\n", tspec_freq.tv_sec, tspec_freq.tv_nsec);*/
106 if (clock_gettime (CLOCK_MONOTONIC, &tspec) == 0) {
107 /*printf ("time: %lu.%lu\n", tspec.tv_sec, tspec.tv_nsec); */
108 return ((gint64)tspec.tv_sec * MTICKS_PER_SEC + tspec.tv_nsec / 100);
113 if (gettimeofday (&tv, NULL) == 0)
114 return ((gint64)tv.tv_sec * 1000000 + tv.tv_usec) * 10;
119 * Magic number to convert a time which is relative to
120 * Jan 1, 1970 into a value which is relative to Jan 1, 0001.
122 #define EPOCH_ADJUST ((guint64)62135596800LL)
124 /* Returns the number of 100ns ticks since 1/1/1, UTC timezone */
126 mono_100ns_datetime (void)
129 if (gettimeofday (&tv, NULL) == 0)
130 return (((gint64)tv.tv_sec + EPOCH_ADJUST) * 1000000 + tv.tv_usec) * 10;