void mono_process_get_times (gpointer pid, gint64 *start_time, gint64 *user_time, gint64 *kernel_time) { if (user_time) *user_time = mono_process_get_data (pid, MONO_PROCESS_USER_TIME); if (kernel_time) *kernel_time = mono_process_get_data (pid, MONO_PROCESS_SYSTEM_TIME); if (start_time) { *start_time = 0; #if USE_SYSCTL && defined(kinfo_starttime_member) { KINFO_PROC processi; if (sysctl_kinfo_proc (pid, &processi)) *start_time = mono_100ns_datetime_from_timeval (processi.kinfo_starttime_member); } #endif if (*start_time == 0) { static guint64 boot_time = 0; if (!boot_time) boot_time = mono_100ns_datetime () - ((guint64)mono_msec_ticks ()) * 10000; *start_time = boot_time + mono_process_get_data (pid, MONO_PROCESS_ELAPSED); } } }
/* Returns the number of 100ns ticks from unspecified time: this should be monotonic */ gint64 mono_100ns_ticks (void) { static LARGE_INTEGER freq; static UINT64 start_time; UINT64 cur_time; LARGE_INTEGER value; if (!freq.QuadPart) { if (!QueryPerformanceFrequency (&freq)) return mono_100ns_datetime (); QueryPerformanceCounter (&value); start_time = value.QuadPart; } QueryPerformanceCounter (&value); cur_time = value.QuadPart; /* we use unsigned numbers and return the difference to avoid overflows */ return (cur_time - start_time) * (double)MTICKS_PER_SEC / freq.QuadPart; }