[wing/wip/monotonic: 2/2] Add utility to get a proper monotonic on windows



commit 7816860229eaed23d3c498e565635caf4b4167bf
Author: Ignacio Casal Quinteiro <qignacio amazon com>
Date:   Wed Mar 29 10:37:47 2017 +0200

    Add utility to get a proper monotonic on windows
    
    Currently glib provides a monotonic that works on Windows XP
    but that does not provide a accurate monotonic.

 wing/meson.build |    5 +++++
 wing/wing-init.c |   44 ++++++++++++++++++++++++++++++++++++++++++++
 wing/wing-init.h |   25 +++++++++++++++++++++++++
 wing/wingutils.c |   40 ++++++++++++++++++++++++++++++++++++++++
 wing/wingutils.h |    3 +++
 5 files changed, 117 insertions(+), 0 deletions(-)
---
diff --git a/wing/meson.build b/wing/meson.build
index 74855aa..c696a68 100644
--- a/wing/meson.build
+++ b/wing/meson.build
@@ -10,7 +10,12 @@ headers = [
   'wingutils.h',
 ]
 
+private_headers = [
+  'wing-init.h',
+]
+
 sources = [
+  'wing-init.c',
   'wingnamedpipeclient.c',
   'wingnamedpipeconnection.c',
   'wingnamedpipelistener.c',
diff --git a/wing/wing-init.c b/wing/wing-init.c
new file mode 100644
index 0000000..2537217
--- /dev/null
+++ b/wing/wing-init.c
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2016 NICE s.r.l.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "wing-init.h"
+#include <windows.h>
+
+BOOL WINAPI DllMain (HINSTANCE hinstDLL,
+                     DWORD     fdwReason,
+                     LPVOID    lpvReserved);
+
+HMODULE wing_dll;
+
+BOOL WINAPI
+DllMain (HINSTANCE hinstDLL,
+         DWORD     fdwReason,
+         LPVOID    lpvReserved)
+{
+  switch (fdwReason)
+    {
+    case DLL_PROCESS_ATTACH:
+      wing_dll = hinstDLL;
+      wing_init_monotonic_time ();
+      break;
+    default:
+      /* do nothing */
+      ;
+    }
+
+  return TRUE;
+}
diff --git a/wing/wing-init.h b/wing/wing-init.h
new file mode 100644
index 0000000..8fb66f1
--- /dev/null
+++ b/wing/wing-init.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright © 2016 NICE s.r.l.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2 of the licence or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Ignacio Casal Quinteiro <ignacio casal nice-software com>
+ */
+
+#ifndef WING_INIT_H
+#define WING_INIT_H
+
+void  wing_init_monotonic_time  (void);
+
+#endif /* WING_INIT_H */
diff --git a/wing/wingutils.c b/wing/wingutils.c
index c743386..c182ecf 100644
--- a/wing/wingutils.c
+++ b/wing/wingutils.c
@@ -72,3 +72,43 @@ wing_get_version_number (gint *major,
 
   return TRUE;
 }
+
+static gint64 monotonic_ticks_per_sec = 0;
+
+void
+wing_init_monotonic_time (void)
+{
+  LARGE_INTEGER freq;
+
+  if (!QueryPerformanceFrequency(&freq) || freq.QuadPart == 0)
+    {
+      g_warning("Unable to use QueryPerformanceCounter (%d). Fallback to low resolution timer", 
GetLastError());
+      monotonic_ticks_per_sec = 0;
+      return;
+    }
+
+  monotonic_ticks_per_sec = freq.QuadPart;
+}
+
+gint64
+wing_get_monotonic_time (void)
+{
+  if (G_LIKELY(monotonic_ticks_per_sec != 0))
+    {
+      LARGE_INTEGER ticks;
+
+      if (QueryPerformanceCounter(&ticks))
+        {
+          gint64 time;
+
+          time = ticks.QuadPart * G_USEC_PER_SEC; /* multiply first to avoid loss of precision */
+
+          return time / monotonic_ticks_per_sec;
+        }
+
+      g_warning("QueryPerformanceCounter Failed (%d). Permanently fallback to low resolution timer", 
GetLastError());
+      monotonic_ticks_per_sec = 0;
+    }
+
+  return g_get_monotonic_time();
+}
diff --git a/wing/wingutils.h b/wing/wingutils.h
index 390ad20..23220b0 100644
--- a/wing/wingutils.h
+++ b/wing/wingutils.h
@@ -33,6 +33,9 @@ WING_AVAILABLE_IN_ALL
 gboolean     wing_get_version_number   (gint *major,
                                         gint *minor);
 
+WING_AVAILABLE_IN_ALL
+gint64       wing_get_monotonic_time   (void);
+
 G_END_DECLS
 
 #endif /* WING_UTILS_H */


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