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
|
||||
{
|
||||
int inited;
|
||||
LONG inited;
|
||||
LARGE_INTEGER primed_pc;
|
||||
double freq;
|
||||
void prime ();
|
||||
|
|
|
@ -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;
|
||||
spinlock hspin (inited, 1);
|
||||
if (!hspin)
|
||||
{
|
||||
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);
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue