From ab548d240a9c2862ea7f7685c68b6013a68bf0c8 Mon Sep 17 00:00:00 2001 From: Ryan Lortie Date: Fri, 22 Oct 2010 18:42:32 +0200 Subject: [PATCH] Add g_get_monotonic_time() Gets the system monotonic time on systems that have it. Otherwise, call g_get_current_time(). --- docs/reference/glib/glib-sections.txt | 1 + glib/glib.symbols | 1 + glib/gmain.c | 70 ++++++++++++++++++++++++++- glib/gmain.h | 1 + 4 files changed, 72 insertions(+), 1 deletion(-) diff --git a/docs/reference/glib/glib-sections.txt b/docs/reference/glib/glib-sections.txt index d51ffc727..c33912ca1 100644 --- a/docs/reference/glib/glib-sections.txt +++ b/docs/reference/glib/glib-sections.txt @@ -1321,6 +1321,7 @@ g_time_val_to_iso8601 GTimeSpec +g_get_monotonic_time GDate diff --git a/glib/glib.symbols b/glib/glib.symbols index 226a9ff3d..f9ae89577 100644 --- a/glib/glib.symbols +++ b/glib/glib.symbols @@ -683,6 +683,7 @@ g_child_watch_add g_child_watch_add_full g_child_watch_source_new g_get_current_time +g_get_monotonic_time g_main_context_acquire g_main_context_add_poll g_main_context_check diff --git a/glib/gmain.c b/glib/gmain.c index 31473c653..d0e76a7b1 100644 --- a/glib/gmain.c +++ b/glib/gmain.c @@ -1816,11 +1816,79 @@ g_get_current_time (GTimeVal *result) * GTimeSpec: * * Represents a precise time, with seconds and nanoseconds. This is - * similar to POSIX struct timespec. + * similar to POSIX struct timespec. This + * structure can be filled in with g_get_monotonic_time(). * * Since: 2.28 **/ +/** + * g_get_monotonic_time: + * @result: #GTimeSpec structure in which to store the time + * + * Queries the system monotonic time, if available. + * + * On POSIX systems with clock_gettime() and %CLOCK_MONOTONIC this call + * is a very shallow wrapper for that. Otherwise, we make a best effort + * that probably involves returning the wall clock time (with at least + * microsecond accuracy, subject to the limitations of the OS kernel). + * + * Note that, on Windows, "limitations of the OS kernel" is a rather + * substantial statement. Depending on the configuration of the system, + * the wall clock time is updated as infrequently as 64 times a second + * (which is approximately every 16ms). + * + * Since: 2.28 + **/ +void +g_get_monotonic_time (GTimeSpec *result) +{ + g_return_if_fail (result != NULL); + +#ifdef HAVE_CLOCK_GETTIME + /* librt clock_gettime() is our first choice */ + { + static int clockid = CLOCK_REALTIME; + struct timespec ts; + +#ifdef HAVE_MONOTONIC_CLOCK + /* We have to check if we actually have monotonic clock support. + * + * There is no thread safety issue here since there is no harm if we + * check twice. + */ + { + static gboolean checked; + + if G_UNLIKELY (!checked) + { + if (sysconf (_SC_MONOTONIC_CLOCK) >= 0) + clockid = CLOCK_MONOTONIC; + checked = TRUE; + } + } +#endif + + clock_gettime (clockid, &ts); + result->tv_sec = ts.tv_sec; + result->tv_nsec = ts.tv_nsec; + } +#else + /* It may look like we are discarding accuracy on Windows (since its + * current time is expressed in 100s of nanoseconds) but according to + * many sources, the time is only updated 64 times per second, so + * microsecond accuracy is more than enough. + */ + { + GTimeVal tv; + + g_get_current_time (&tv); + result->tv_sec = tv.tv_sec; + result->tv_nsec = tv.tv_usec * 1000; + } +#endif +} + static void g_main_dispatch_free (gpointer dispatch) { diff --git a/glib/gmain.h b/glib/gmain.h index b221a63f9..eab20e737 100644 --- a/glib/gmain.h +++ b/glib/gmain.h @@ -380,6 +380,7 @@ GSource *g_timeout_source_new_seconds (guint interval); /* Miscellaneous functions */ void g_get_current_time (GTimeVal *result); +void g_get_monotonic_time (GTimeSpec *result); /* ============== Compat main loop stuff ================== */