* cygheap.h (init_cygheap::_gtod): Remove.

* cygwin.din: Export clock_getres and clock_setres.
* hires.h (hires_ms::minperiod): Delete declaration.
(hires_ms::began_period): Ditto.
(hires_ms::prime): Make void.
(hires_ms::resolution): Just define here.
(hires_ms::usecs): Remove unneeded argument.
(gtod): Redeclare as a variable.
* timer.cc (timer_thread): Eliminate argument to gtod.usecs().
(timer_tracker::gettime): Ditto.
(timer_tracker::settime): Ditto.
* times.cc (gettimeofday): Ditto.
(hires_ms::began_period): Delete declaration.
(hires_us::prime): Remove debugging.
(hires_ms::prime): Make void.  Eliminate period stuff.
(hires_ms::usecs): Eliminate argument to gtod.usecs().
(hires_ms::resolution): New function.
(clock_getres): Ditto.
(clock_setres): Ditto.
* version.h: Bump API version to 143.
* include/cygwin/time.h: New file.
This commit is contained in:
Christopher Faylor 2005-11-11 16:42:15 +00:00
parent 37bd11ed12
commit ecb908f699
8 changed files with 145 additions and 58 deletions

View File

@ -1,3 +1,27 @@
2005-11-11 Christopher Faylor <cgf@timesys.com>
* cygheap.h (init_cygheap::_gtod): Remove.
* cygwin.din: Export clock_getres and clock_setres.
* hires.h (hires_ms::minperiod): Delete declaration.
(hires_ms::began_period): Ditto.
(hires_ms::prime): Make void.
(hires_ms::resolution): Just define here.
(hires_ms::usecs): Remove unneeded argument.
(gtod): Redeclare as a variable.
* timer.cc (timer_thread): Eliminate argument to gtod.usecs().
(timer_tracker::gettime): Ditto.
(timer_tracker::settime): Ditto.
* times.cc (gettimeofday): Ditto.
(hires_ms::began_period): Delete declaration.
(hires_us::prime): Remove debugging.
(hires_ms::prime): Make void. Eliminate period stuff.
(hires_ms::usecs): Eliminate argument to gtod.usecs().
(hires_ms::resolution): New function.
(clock_getres): Ditto.
(clock_setres): Ditto.
* version.h: Bump API version to 143.
* include/cygwin/time.h: New file.
2005-11-10 Christopher Faylor <cgf@timesys.com> 2005-11-10 Christopher Faylor <cgf@timesys.com>
* times.cc (hires_ms::prime): Comment out call to timeBeginPeriod for * times.cc (hires_ms::prime): Comment out call to timeBeginPeriod for

View File

@ -300,7 +300,6 @@ struct init_cygheap
pid_t pid; /* my pid */ pid_t pid; /* my pid */
HANDLE pid_handle; /* handle for my pid */ HANDLE pid_handle; /* handle for my pid */
hook_chain hooks; hook_chain hooks;
hires_ms _gtod;
void close_ctty (); void close_ctty ();
}; };

View File

@ -254,6 +254,8 @@ _clearerr = clearerr NOSIGFE
clock SIGFE clock SIGFE
_clock = clock SIGFE _clock = clock SIGFE
clock_gettime SIGFE clock_gettime SIGFE
clock_getres SIGFE
clock_setres SIGFE
close SIGFE close SIGFE
_close = close SIGFE _close = close SIGFE
closedir SIGFE closedir SIGFE

View File

@ -41,15 +41,12 @@ class hires_ms : hires_base
{ {
DWORD initime_ms; DWORD initime_ms;
LARGE_INTEGER initime_us; LARGE_INTEGER initime_us;
UINT minperiod; void prime ();
static bool began_period;
UINT prime ();
public: public:
LONGLONG usecs (bool justdelta); LONGLONG usecs ();
UINT dmsecs () { return timeGetTime (); } UINT dmsecs () { return timeGetTime (); }
UINT resolution () { return minperiod ?: prime (); } UINT resolution ();
}; };
#define gtod cygheap->_gtod extern hires_ms gtod;
#endif /*__HIRES_H__*/ #endif /*__HIRES_H__*/

View File

@ -0,0 +1,25 @@
/* time.h
Copyright 2005 Red Hat Inc.
This file is part of Cygwin.
This software is a copyrighted work licensed under the terms of the
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
details. */
#ifndef _CYGWIN_TIME_H
#define _CYGWIN_TIME_H
#include <sys/select.h>
#ifdef __cplusplus
extern "C"
{
#endif
int clock_setres (clockid_t, struct timespec *);
#ifdef __cplusplus
}
#endif
#endif /* _CYGWIN_TIME_H */

View File

@ -280,12 +280,13 @@ details. */
140: Export mlock, munlock. 140: Export mlock, munlock.
141: Export futimes, lutimes. 141: Export futimes, lutimes.
142: Export memmem 142: Export memmem
143: Export clock_getres, clock_setres
*/ */
/* Note that we forgot to bump the api for ualarm, strtoll, strtoull */ /* Note that we forgot to bump the api for ualarm, strtoll, strtoull */
#define CYGWIN_VERSION_API_MAJOR 0 #define CYGWIN_VERSION_API_MAJOR 0
#define CYGWIN_VERSION_API_MINOR 142 #define CYGWIN_VERSION_API_MINOR 143
/* There is also a compatibity version number associated with the /* There is also a compatibity version number associated with the
shared memory regions. It is incremented when incompatible shared memory regions. It is incremented when incompatible

View File

@ -133,7 +133,7 @@ timer_thread (VOID *x)
long sleep_ms; long sleep_ms;
/* Account for delays in starting thread /* Account for delays in starting thread
and sending the signal */ and sending the signal */
now = gtod.usecs (false); now = gtod.usecs ();
sleep_us = sleepto_us - now; sleep_us = sleepto_us - now;
if (sleep_us > 0) if (sleep_us > 0)
{ {
@ -226,7 +226,7 @@ timer_tracker::settime (int in_flags, const itimerspec *value, itimerspec *ovalu
|| it_bad (value->it_interval)) || it_bad (value->it_interval))
return -1; return -1;
long long now = in_flags & TIMER_ABSTIME ? 0 : gtod.usecs (false); long long now = in_flags & TIMER_ABSTIME ? 0 : gtod.usecs ();
lock_timer_tracker here; lock_timer_tracker here;
cancel (); cancel ();
@ -263,7 +263,7 @@ timer_tracker::gettime (itimerspec *ovalue)
else else
{ {
ovalue->it_interval = it_interval; ovalue->it_interval = it_interval;
long long now = gtod.usecs (false); long long now = gtod.usecs ();
long long left_us = sleepto_us - now; long long left_us = sleepto_us - now;
if (left_us < 0) if (left_us < 0)
left_us = 0; left_us = 0;

View File

@ -144,17 +144,14 @@ totimeval (struct timeval *dst, FILETIME *src, int sub, int flag)
dst->tv_sec = x / (long long) (1e6); dst->tv_sec = x / (long long) (1e6);
} }
bool NO_COPY hires_ms::began_period; /* minperiod needs to be NO_COPY since it hires_ms NO_COPY gtod;
is a trigger for setting timeBeginPeriod
which needs to be set once for every
program. */
/* FIXME: Make thread safe */ /* FIXME: Make thread safe */
extern "C" int extern "C" int
gettimeofday (struct timeval *tv, struct timezone *tz) gettimeofday (struct timeval *tv, struct timezone *tz)
{ {
static bool tzflag; static bool tzflag;
LONGLONG now = gtod.usecs (false); LONGLONG now = gtod.usecs ();
if (now == (LONGLONG) -1) if (now == (LONGLONG) -1)
return -1; return -1;
@ -566,35 +563,25 @@ void
hires_us::prime () hires_us::prime ()
{ {
LARGE_INTEGER ifreq; LARGE_INTEGER ifreq;
stupid_printf ("before QueryPerformanceFrequency"); // DELETEME
if (!QueryPerformanceFrequency (&ifreq)) if (!QueryPerformanceFrequency (&ifreq))
{ {
stupid_printf ("QueryPerformanceFrequency failed"); // DELETEME
inited = -1; inited = -1;
return; return;
} }
stupid_printf ("after QueryPerformanceFrequency"); // DELETEME
FILETIME f; FILETIME f;
int priority = GetThreadPriority (GetCurrentThread ()); int priority = GetThreadPriority (GetCurrentThread ());
stupid_printf ("before SetThreadPriority(THREAD_PRIORITY_TIME_CRITICAL)"); // DELETEME
SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_TIME_CRITICAL); SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_TIME_CRITICAL);
stupid_printf ("after SetThreadPriority(THREAD_PRIORITY_TIME_CRITICAL)"); // DELETEME
if (!QueryPerformanceCounter (&primed_pc)) if (!QueryPerformanceCounter (&primed_pc))
{ {
stupid_printf ("QueryPerformanceCounter failed, %E");
SetThreadPriority (GetCurrentThread (), priority); SetThreadPriority (GetCurrentThread (), priority);
stupid_printf ("After failing SetThreadPriority");
inited = -1; inited = -1;
return; return;
} }
stupid_printf ("after QueryPerformanceCounter"); // DELETEME
GetSystemTimeAsFileTime (&f); GetSystemTimeAsFileTime (&f);
stupid_printf ("after GetSystemTimeAsFileTime"); // DELETEME
SetThreadPriority (GetCurrentThread (), priority); SetThreadPriority (GetCurrentThread (), priority);
stupid_printf ("after SetThreadPriority(%d)", priority); // DELETEME
inited = 1; inited = 1;
primed_ft.HighPart = f.dwHighDateTime; primed_ft.HighPart = f.dwHighDateTime;
@ -628,36 +615,12 @@ hires_us::usecs (bool justdelta)
return res; return res;
} }
UINT void
hires_ms::prime () hires_ms::prime ()
{ {
TIMECAPS tc;
FILETIME f;
stupid_printf ("entering, minperiod %d, began_period %d", minperiod, began_period);
if (minperiod)
/* done previously */;
else if (timeGetDevCaps (&tc, sizeof (tc)) != TIMERR_NOERROR)
{stupid_printf ("timeGetDevCaps failed, %E");
minperiod = 1;
}
else
{
minperiod = min (max (tc.wPeriodMin, 1), tc.wPeriodMax);
stupid_printf ("timeGetDevCaps succeeded. tc.wPeriodMin %u, tc.wPeriodMax %u, minperiod %u", tc.wPeriodMin, tc.wPeriodMax, minperiod); }
stupid_printf ("inited %d, minperiod %u, began_period %d", minperiod, began_period);
if (!began_period)
{
#if 0
timeBeginPeriod (minperiod);
#endif
began_period = true;
stupid_printf ("timeBeginPeriod called");
}
if (!inited) if (!inited)
{ {
FILETIME f;
int priority = GetThreadPriority (GetCurrentThread ()); int priority = GetThreadPriority (GetCurrentThread ());
stupid_printf ("priority %d", priority); stupid_printf ("priority %d", priority);
SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_TIME_CRITICAL); SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_TIME_CRITICAL);
@ -676,14 +639,14 @@ stupid_printf ("SetThreadPriority(%p, %d)", GetCurrentThread(), priority);
initime_us.QuadPart /= 10; initime_us.QuadPart /= 10;
} }
stupid_printf ("returning"); stupid_printf ("returning");
return minperiod; return;
} }
LONGLONG LONGLONG
hires_ms::usecs (bool justdelta) hires_ms::usecs ()
{ {
stupid_printf ("before call to prime(), minperiod %u, process priority %d", minperiod, GetThreadPriority (GetCurrentThread ())); stupid_printf ("before call to prime(), process priority %d", GetThreadPriority (GetCurrentThread ()));
if (!inited || !began_period) /* NO_COPY variable */ if (!inited)
prime (); prime ();
stupid_printf ("after call to prime(), process priority %d", GetThreadPriority (GetCurrentThread ())); stupid_printf ("after call to prime(), process priority %d", GetThreadPriority (GetCurrentThread ()));
@ -711,7 +674,7 @@ clock_gettime (clockid_t clk_id, struct timespec *tp)
return -1; return -1;
} }
LONGLONG now = gtod.usecs (false); LONGLONG now = gtod.usecs ();
if (now == (LONGLONG) -1) if (now == (LONGLONG) -1)
return -1; return -1;
@ -719,3 +682,79 @@ clock_gettime (clockid_t clk_id, struct timespec *tp)
tp->tv_nsec = (now % 1000000) * 1000; tp->tv_nsec = (now % 1000000) * 1000;
return 0; return 0;
} }
static DWORD minperiod; // FIXME: Maintain period after a fork.
UINT
hires_ms::resolution ()
{
if (!minperiod)
{
/* Try to empirically determine current timer resolution */
int priority = GetThreadPriority (GetCurrentThread ());
SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_TIME_CRITICAL);
DWORD period = 0;
for (int i = 0; i < 4; i++)
{
DWORD now;
DWORD then = timeGetTime ();
while ((now = timeGetTime ()) == then)
continue;
then = now;
while ((now = timeGetTime ()) == then)
continue;
period += now - then;
}
SetThreadPriority (GetCurrentThread (), priority);
period /= 4;
minperiod = period;
}
return minperiod;
}
extern "C" int
clock_getres (clockid_t clk_id, struct timespec *tp)
{
if (clk_id != CLOCK_REALTIME)
{
set_errno (ENOSYS);
return -1;
}
DWORD period = gtod.resolution ();
tp->tv_sec = period / 1000000;
tp->tv_nsec = (period % 1000000) * 1000;
return 0;
}
extern "C" int
clock_setres (clockid_t clk_id, struct timespec *tp)
{
static NO_COPY bool period_set;
if (clk_id != CLOCK_REALTIME)
{
set_errno (ENOSYS);
return -1;
}
if (period_set)
timeEndPeriod (minperiod);
DWORD period = (tp->tv_sec * 1000) + ((tp->tv_nsec) / 1000);
if (timeBeginPeriod (period))
{
minperiod = period;
period_set = true;
}
else
{
__seterrno ();
timeBeginPeriod (minperiod);
return -1;
}
return 0;
}