diff options
-rw-r--r-- | winsup/cygwin/ChangeLog | 24 | ||||
-rw-r--r-- | winsup/cygwin/cygheap.h | 1 | ||||
-rw-r--r-- | winsup/cygwin/cygwin.din | 2 | ||||
-rw-r--r-- | winsup/cygwin/hires.h | 11 | ||||
-rw-r--r-- | winsup/cygwin/include/cygwin/sys_time.h | 25 | ||||
-rw-r--r-- | winsup/cygwin/include/cygwin/version.h | 3 | ||||
-rw-r--r-- | winsup/cygwin/timer.cc | 6 | ||||
-rw-r--r-- | winsup/cygwin/times.cc | 131 |
8 files changed, 145 insertions, 58 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 14da5b4..ae5185e 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -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> * times.cc (hires_ms::prime): Comment out call to timeBeginPeriod for diff --git a/winsup/cygwin/cygheap.h b/winsup/cygwin/cygheap.h index e9e000f..ea4fb1c 100644 --- a/winsup/cygwin/cygheap.h +++ b/winsup/cygwin/cygheap.h @@ -300,7 +300,6 @@ struct init_cygheap pid_t pid; /* my pid */ HANDLE pid_handle; /* handle for my pid */ hook_chain hooks; - hires_ms _gtod; void close_ctty (); }; diff --git a/winsup/cygwin/cygwin.din b/winsup/cygwin/cygwin.din index c6acea4..82fea5f 100644 --- a/winsup/cygwin/cygwin.din +++ b/winsup/cygwin/cygwin.din @@ -254,6 +254,8 @@ _clearerr = clearerr NOSIGFE clock SIGFE _clock = clock SIGFE clock_gettime SIGFE +clock_getres SIGFE +clock_setres SIGFE close SIGFE _close = close SIGFE closedir SIGFE diff --git a/winsup/cygwin/hires.h b/winsup/cygwin/hires.h index 369b087..ddc6705 100644 --- a/winsup/cygwin/hires.h +++ b/winsup/cygwin/hires.h @@ -41,15 +41,12 @@ class hires_ms : hires_base { DWORD initime_ms; LARGE_INTEGER initime_us; - UINT minperiod; - static bool began_period; - UINT prime (); + void prime (); public: - LONGLONG usecs (bool justdelta); + LONGLONG usecs (); UINT dmsecs () { return timeGetTime (); } - UINT resolution () { return minperiod ?: prime (); } - + UINT resolution (); }; -#define gtod cygheap->_gtod +extern hires_ms gtod; #endif /*__HIRES_H__*/ diff --git a/winsup/cygwin/include/cygwin/sys_time.h b/winsup/cygwin/include/cygwin/sys_time.h new file mode 100644 index 0000000..a5e95f9 --- /dev/null +++ b/winsup/cygwin/include/cygwin/sys_time.h @@ -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 */ diff --git a/winsup/cygwin/include/cygwin/version.h b/winsup/cygwin/include/cygwin/version.h index 9b54196..057ea09 100644 --- a/winsup/cygwin/include/cygwin/version.h +++ b/winsup/cygwin/include/cygwin/version.h @@ -280,12 +280,13 @@ details. */ 140: Export mlock, munlock. 141: Export futimes, lutimes. 142: Export memmem + 143: Export clock_getres, clock_setres */ /* Note that we forgot to bump the api for ualarm, strtoll, strtoull */ #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 shared memory regions. It is incremented when incompatible diff --git a/winsup/cygwin/timer.cc b/winsup/cygwin/timer.cc index e936534..74319ea 100644 --- a/winsup/cygwin/timer.cc +++ b/winsup/cygwin/timer.cc @@ -133,7 +133,7 @@ timer_thread (VOID *x) long sleep_ms; /* Account for delays in starting thread and sending the signal */ - now = gtod.usecs (false); + now = gtod.usecs (); sleep_us = sleepto_us - now; if (sleep_us > 0) { @@ -226,7 +226,7 @@ timer_tracker::settime (int in_flags, const itimerspec *value, itimerspec *ovalu || it_bad (value->it_interval)) 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; cancel (); @@ -263,7 +263,7 @@ timer_tracker::gettime (itimerspec *ovalue) else { ovalue->it_interval = it_interval; - long long now = gtod.usecs (false); + long long now = gtod.usecs (); long long left_us = sleepto_us - now; if (left_us < 0) left_us = 0; diff --git a/winsup/cygwin/times.cc b/winsup/cygwin/times.cc index be091da..9edd460 100644 --- a/winsup/cygwin/times.cc +++ b/winsup/cygwin/times.cc @@ -144,17 +144,14 @@ totimeval (struct timeval *dst, FILETIME *src, int sub, int flag) dst->tv_sec = x / (long long) (1e6); } -bool NO_COPY hires_ms::began_period; /* minperiod needs to be NO_COPY since it - is a trigger for setting timeBeginPeriod - which needs to be set once for every - program. */ +hires_ms NO_COPY gtod; /* FIXME: Make thread safe */ extern "C" int gettimeofday (struct timeval *tv, struct timezone *tz) { static bool tzflag; - LONGLONG now = gtod.usecs (false); + LONGLONG now = gtod.usecs (); if (now == (LONGLONG) -1) return -1; @@ -566,35 +563,25 @@ void hires_us::prime () { LARGE_INTEGER ifreq; -stupid_printf ("before QueryPerformanceFrequency"); // DELETEME if (!QueryPerformanceFrequency (&ifreq)) { -stupid_printf ("QueryPerformanceFrequency failed"); // DELETEME inited = -1; return; } -stupid_printf ("after QueryPerformanceFrequency"); // DELETEME FILETIME f; int priority = GetThreadPriority (GetCurrentThread ()); -stupid_printf ("before SetThreadPriority(THREAD_PRIORITY_TIME_CRITICAL)"); // DELETEME SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_TIME_CRITICAL); -stupid_printf ("after SetThreadPriority(THREAD_PRIORITY_TIME_CRITICAL)"); // DELETEME if (!QueryPerformanceCounter (&primed_pc)) { -stupid_printf ("QueryPerformanceCounter failed, %E"); SetThreadPriority (GetCurrentThread (), priority); -stupid_printf ("After failing SetThreadPriority"); inited = -1; return; } -stupid_printf ("after QueryPerformanceCounter"); // DELETEME GetSystemTimeAsFileTime (&f); -stupid_printf ("after GetSystemTimeAsFileTime"); // DELETEME SetThreadPriority (GetCurrentThread (), priority); -stupid_printf ("after SetThreadPriority(%d)", priority); // DELETEME inited = 1; primed_ft.HighPart = f.dwHighDateTime; @@ -628,36 +615,12 @@ hires_us::usecs (bool justdelta) return res; } -UINT +void 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) { + FILETIME f; int priority = GetThreadPriority (GetCurrentThread ()); stupid_printf ("priority %d", priority); SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_TIME_CRITICAL); @@ -676,14 +639,14 @@ stupid_printf ("SetThreadPriority(%p, %d)", GetCurrentThread(), priority); initime_us.QuadPart /= 10; } stupid_printf ("returning"); - return minperiod; + return; } LONGLONG -hires_ms::usecs (bool justdelta) +hires_ms::usecs () { -stupid_printf ("before call to prime(), minperiod %u, process priority %d", minperiod, GetThreadPriority (GetCurrentThread ())); - if (!inited || !began_period) /* NO_COPY variable */ +stupid_printf ("before call to prime(), process priority %d", GetThreadPriority (GetCurrentThread ())); + if (!inited) prime (); 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; } - LONGLONG now = gtod.usecs (false); + LONGLONG now = gtod.usecs (); if (now == (LONGLONG) -1) return -1; @@ -719,3 +682,79 @@ clock_gettime (clockid_t clk_id, struct timespec *tp) tp->tv_nsec = (now % 1000000) * 1000; 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; +} |