This is the mail archive of the cygwin-cvs@cygwin.com mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[newlib-cygwin] Cygwin: timers: use spinlock to prime hires_ns thread-safe


https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=5eaa64f9d86cae422016c3b08476b1cea556628e

commit 5eaa64f9d86cae422016c3b08476b1cea556628e
Author: Corinna Vinschen <corinna@vinschen.de>
Date:   Mon Nov 26 17:47:53 2018 +0100

    Cygwin: timers: use spinlock to prime hires_ns thread-safe
    
    The current method to make hires_ns priming thread-safe isn't
    thread-safe.  Rather than hoping that running the thread in
    TIME_CRITICAL priority is doing the right thing, use a spinlock.
    
    Signed-off-by: Corinna Vinschen <corinna@vinschen.de>

Diff:
---
 winsup/cygwin/hires.h  |  2 +-
 winsup/cygwin/times.cc | 26 ++++++++++++--------------
 2 files changed, 13 insertions(+), 15 deletions(-)

diff --git a/winsup/cygwin/hires.h b/winsup/cygwin/hires.h
index d07bf39..10aed7b 100644
--- a/winsup/cygwin/hires.h
+++ b/winsup/cygwin/hires.h
@@ -40,7 +40,7 @@ details. */
 
 class hires_ns
 {
-  int inited;
+  LONG inited;
   LARGE_INTEGER primed_pc;
   double freq;
   void prime ();
diff --git a/winsup/cygwin/times.cc b/winsup/cygwin/times.cc
index 1ead18e..4e405b2 100644
--- a/winsup/cygwin/times.cc
+++ b/winsup/cygwin/times.cc
@@ -24,6 +24,7 @@ details. */
 #include "thread.h"
 #include "cygtls.h"
 #include "ntdll.h"
+#include "spinlock.h"
 
 hires_ms NO_COPY gtod;
 
@@ -465,19 +466,16 @@ ftime (struct timeb *tp)
 void
 hires_ns::prime ()
 {
-  LARGE_INTEGER ifreq;
-
-  /* On XP or later the perf counter functions will always succeed. */
-  QueryPerformanceFrequency (&ifreq);
-
-  int priority = GetThreadPriority (GetCurrentThread ());
-
-  SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_TIME_CRITICAL);
-  QueryPerformanceCounter (&primed_pc);
+  spinlock hspin (inited, 1);
+  if (!hspin)
+    {
+      LARGE_INTEGER ifreq;
 
-  freq = (double) ((double) NSPERSEC / (double) ifreq.QuadPart);
-  inited = true;
-  SetThreadPriority (GetCurrentThread (), priority);
+      /* On XP or later the perf counter functions will always succeed. */
+      QueryPerformanceFrequency (&ifreq);
+      freq = (double) ((double) NSPERSEC / (double) ifreq.QuadPart);
+      QueryPerformanceCounter (&primed_pc);
+    }
 }
 
 LONGLONG
@@ -485,7 +483,7 @@ hires_ns::nsecs (bool monotonic)
 {
   LARGE_INTEGER now;
 
-  if (!inited)
+  if (inited <= 0)
     prime ();
   QueryPerformanceCounter (&now);
   // FIXME: Use round() here?
@@ -627,7 +625,7 @@ static ULONG minperiod;	// FIXME: Maintain period after a fork.
 LONGLONG
 hires_ns::resolution ()
 {
-  if (!inited)
+  if (inited <= 0)
     prime ();
   return (freq <= 1.0) ? 1LL : (LONGLONG) freq;
 }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]