Fix g_get_monotonic_time on non-Intel processors
https://bugzilla.gnome.org/show_bug.cgi?id=728123
https://bug728123.bugzilla-attachments.gnome.org/attachment.cgi?id=275596
--- glib/gmain.c.orig 2017-11-13 11:02:33.000000000 -0600
+++ glib/gmain.c 2017-11-22 21:47:59.000000000 -0600
g_get_monotonic_time (void)
static mach_timebase_info_data_t timebase_info;
+ static double absolute_to_micro;
if (timebase_info.denom == 0)
- /* This is a fraction that we must use to scale
- * mach_absolute_time() by in order to reach nanoseconds.
- * We've only ever observed this to be 1/1, but maybe it could be
- * 1000/1 if mach time is microseconds already, or 1/1000 if
- * picoseconds. Try to deal nicely with that.
+ /* mach_absolute_time() returns "absolute time units", rather than
+ seconds; the mach_timebase_info_data_t struct provides a
+ fraction that can be used to convert these units into seconds.
mach_timebase_info (&timebase_info);
- /* We actually want microseconds... */
- if (timebase_info.numer % 1000 == 0)
- timebase_info.numer /= 1000;
- timebase_info.denom *= 1000;
- /* We want to make the numer 1 to avoid having to multiply... */
- if (timebase_info.denom % timebase_info.numer == 0)
- timebase_info.denom /= timebase_info.numer;
- timebase_info.numer = 1;
- /* We could just multiply by timebase_info.numer below, but why
- * bother for a case that may never actually exist...
- * Plus -- performing the multiplication would risk integer
- * overflow. If we ever actually end up in this situation, we
- * should more carefully evaluate the correct course of action.
- mach_timebase_info (&timebase_info); /* Get a fresh copy for a better message */
- g_error ("Got weird mach timebase info of %d/%d. Please file a bug against GLib.",
- timebase_info.numer, timebase_info.denom);
+ absolute_to_micro = 1e-3 * timebase_info.numer / timebase_info.denom;
- return mach_absolute_time () / timebase_info.denom;
+ if (timebase_info.denom == 1 && timebase_info.numer == 1)
+ /* On Intel, the fraction has been 1/1 to date, so we can shortcut
+ the conversion into microseconds.
+ return mach_absolute_time () / 1000;