[newlib-cygwin] Cygwin: timers: use spinlock to prime hires_ns thread-safe
Corinna Vinschen
corinna@sourceware.org
Mon Nov 26 16:59:00 GMT 2018
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;
}
More information about the Cygwin-cvs
mailing list