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>
This commit is contained in:
parent
161d0fd27b
commit
5eaa64f9d8
|
@ -40,7 +40,7 @@ details. */
|
||||||
|
|
||||||
class hires_ns
|
class hires_ns
|
||||||
{
|
{
|
||||||
int inited;
|
LONG inited;
|
||||||
LARGE_INTEGER primed_pc;
|
LARGE_INTEGER primed_pc;
|
||||||
double freq;
|
double freq;
|
||||||
void prime ();
|
void prime ();
|
||||||
|
|
|
@ -24,6 +24,7 @@ details. */
|
||||||
#include "thread.h"
|
#include "thread.h"
|
||||||
#include "cygtls.h"
|
#include "cygtls.h"
|
||||||
#include "ntdll.h"
|
#include "ntdll.h"
|
||||||
|
#include "spinlock.h"
|
||||||
|
|
||||||
hires_ms NO_COPY gtod;
|
hires_ms NO_COPY gtod;
|
||||||
|
|
||||||
|
@ -465,19 +466,16 @@ ftime (struct timeb *tp)
|
||||||
void
|
void
|
||||||
hires_ns::prime ()
|
hires_ns::prime ()
|
||||||
{
|
{
|
||||||
LARGE_INTEGER ifreq;
|
spinlock hspin (inited, 1);
|
||||||
|
if (!hspin)
|
||||||
|
{
|
||||||
|
LARGE_INTEGER ifreq;
|
||||||
|
|
||||||
/* On XP or later the perf counter functions will always succeed. */
|
/* On XP or later the perf counter functions will always succeed. */
|
||||||
QueryPerformanceFrequency (&ifreq);
|
QueryPerformanceFrequency (&ifreq);
|
||||||
|
freq = (double) ((double) NSPERSEC / (double) ifreq.QuadPart);
|
||||||
int priority = GetThreadPriority (GetCurrentThread ());
|
QueryPerformanceCounter (&primed_pc);
|
||||||
|
}
|
||||||
SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_TIME_CRITICAL);
|
|
||||||
QueryPerformanceCounter (&primed_pc);
|
|
||||||
|
|
||||||
freq = (double) ((double) NSPERSEC / (double) ifreq.QuadPart);
|
|
||||||
inited = true;
|
|
||||||
SetThreadPriority (GetCurrentThread (), priority);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LONGLONG
|
LONGLONG
|
||||||
|
@ -485,7 +483,7 @@ hires_ns::nsecs (bool monotonic)
|
||||||
{
|
{
|
||||||
LARGE_INTEGER now;
|
LARGE_INTEGER now;
|
||||||
|
|
||||||
if (!inited)
|
if (inited <= 0)
|
||||||
prime ();
|
prime ();
|
||||||
QueryPerformanceCounter (&now);
|
QueryPerformanceCounter (&now);
|
||||||
// FIXME: Use round() here?
|
// FIXME: Use round() here?
|
||||||
|
@ -627,7 +625,7 @@ static ULONG minperiod; // FIXME: Maintain period after a fork.
|
||||||
LONGLONG
|
LONGLONG
|
||||||
hires_ns::resolution ()
|
hires_ns::resolution ()
|
||||||
{
|
{
|
||||||
if (!inited)
|
if (inited <= 0)
|
||||||
prime ();
|
prime ();
|
||||||
return (freq <= 1.0) ? 1LL : (LONGLONG) freq;
|
return (freq <= 1.0) ? 1LL : (LONGLONG) freq;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue