mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-12-26 15:36:14 +01:00
gmain: fix fetching timebase on non-Intel Darwin
Co-authored-by: Misty De Meo <mistydemeo@gmail.com>
This commit is contained in:
parent
3cabce39e8
commit
eb3409a9c9
65
glib/gmain.c
65
glib/gmain.c
@ -2906,47 +2906,40 @@ g_get_monotonic_time (void)
|
|||||||
gint64
|
gint64
|
||||||
g_get_monotonic_time (void)
|
g_get_monotonic_time (void)
|
||||||
{
|
{
|
||||||
static mach_timebase_info_data_t timebase_info;
|
mach_timebase_info_data_t timebase_info;
|
||||||
|
guint64 val;
|
||||||
|
|
||||||
if (timebase_info.denom == 0)
|
/* we get nanoseconds from mach_absolute_time() using timebase_info */
|
||||||
|
mach_timebase_info (&timebase_info);
|
||||||
|
val = mach_absolute_time ();
|
||||||
|
|
||||||
|
if (timebase_info.numer != timebase_info.denom)
|
||||||
{
|
{
|
||||||
/* This is a fraction that we must use to scale
|
#ifdef HAVE_UINT128_T
|
||||||
* mach_absolute_time() by in order to reach nanoseconds.
|
val = ((__uint128_t) val * (__uint128_t) timebase_info.numer) / timebase_info.denom / 1000;
|
||||||
*
|
#else
|
||||||
* We've only ever observed this to be 1/1, but maybe it could be
|
guint64 t_high, t_low;
|
||||||
* 1000/1 if mach time is microseconds already, or 1/1000 if
|
guint64 result_high, result_low;
|
||||||
* picoseconds. Try to deal nicely with that.
|
|
||||||
*/
|
|
||||||
mach_timebase_info (&timebase_info);
|
|
||||||
|
|
||||||
/* We actually want microseconds... */
|
/* 64 bit x 32 bit / 32 bit with 96-bit intermediate
|
||||||
if (timebase_info.numer % 1000 == 0)
|
* algorithm lifted from qemu */
|
||||||
timebase_info.numer /= 1000;
|
t_low = (val & 0xffffffffLL) * (guint64) timebase_info.numer;
|
||||||
else
|
t_high = (val >> 32) * (guint64) timebase_info.numer;
|
||||||
timebase_info.denom *= 1000;
|
t_high += (t_low >> 32);
|
||||||
|
result_high = t_high / (guint64) timebase_info.denom;
|
||||||
/* We want to make the numer 1 to avoid having to multiply... */
|
result_low = (((t_high % (guint64) timebase_info.denom) << 32) +
|
||||||
if (timebase_info.denom % timebase_info.numer == 0)
|
(t_low & 0xffffffff)) /
|
||||||
{
|
(guint64) timebase_info.denom;
|
||||||
timebase_info.denom /= timebase_info.numer;
|
val = ((result_high << 32) | result_low) / 1000;
|
||||||
timebase_info.numer = 1;
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* We could just multiply by timebase_info.numer below, but why
|
/* nanoseconds to microseconds */
|
||||||
* bother for a case that may never actually exist...
|
val = val / 1000;
|
||||||
*
|
|
||||||
* 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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return mach_absolute_time () / timebase_info.denom;
|
return val;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
gint64
|
gint64
|
||||||
|
11
meson.build
11
meson.build
@ -772,6 +772,17 @@ if cc.links('''#include <sys/eventfd.h>
|
|||||||
glib_conf.set('HAVE_EVENTFD', 1)
|
glib_conf.set('HAVE_EVENTFD', 1)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
# Check for __uint128_t (gcc) by checking for 128-bit division
|
||||||
|
uint128_t_src = '''int main() {
|
||||||
|
static __uint128_t v1 = 100;
|
||||||
|
static __uint128_t v2 = 10;
|
||||||
|
static __uint128_t u;
|
||||||
|
u = v1 / v2;
|
||||||
|
}'''
|
||||||
|
if cc.compiles(uint128_t_src, name : '__uint128_t available')
|
||||||
|
glib_conf.set('HAVE_UINT128_T', 1)
|
||||||
|
endif
|
||||||
|
|
||||||
clock_gettime_test_code = '''
|
clock_gettime_test_code = '''
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
struct timespec t;
|
struct timespec t;
|
||||||
|
Loading…
Reference in New Issue
Block a user