aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--winsup/cygwin/ChangeLog24
-rw-r--r--winsup/cygwin/cygheap.h1
-rw-r--r--winsup/cygwin/cygwin.din2
-rw-r--r--winsup/cygwin/hires.h11
-rw-r--r--winsup/cygwin/include/cygwin/sys_time.h25
-rw-r--r--winsup/cygwin/include/cygwin/version.h3
-rw-r--r--winsup/cygwin/timer.cc6
-rw-r--r--winsup/cygwin/times.cc131
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;
+}