[glib/wip/monotonic: 3/9] Add g_get_monotonic_time()



commit 849fcaa4f10bfe083fdf83034031c5eaf6fe78b8
Author: Ryan Lortie <desrt desrt ca>
Date:   Fri Oct 22 18:42:32 2010 +0200

    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 deletions(-)
---
diff --git a/docs/reference/glib/glib-sections.txt b/docs/reference/glib/glib-sections.txt
index 8142584..c43ad07 100644
--- a/docs/reference/glib/glib-sections.txt
+++ b/docs/reference/glib/glib-sections.txt
@@ -1319,6 +1319,7 @@ g_time_val_to_iso8601
 
 <SUBSECTION>
 GTimeSpec
+g_get_monotonic_time
 
 <SUBSECTION>
 GDate
diff --git a/glib/glib.symbols b/glib/glib.symbols
index 226a9ff..f9ae895 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 31473c6..d0e76a7 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 <structname>struct timespec</structname>.
+ * similar to POSIX <structname>struct timespec</structname>.  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 b221a63..eab20e7 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 ================== */
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]