Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYaakov Selkowitz <yselkowi@redhat.com>2010-08-09 20:47:48 +0400
committerYaakov Selkowitz <yselkowi@redhat.com>2010-08-09 20:47:48 +0400
commitb150f5236b5dd8318bb9fef8188517894e3f186c (patch)
treeab518fe7711d0c3867cfdb56e1eb2a7703c7377a /winsup/cygwin/times.cc
parentf717289618baa1a709a7b6d5d91c4904fe2426a1 (diff)
Implement POSIX.1-2004 Monotonic Clock.
* hires.h: Change hires_us to hires_ns, with nanosecond resolution. (hires_ns::primed_ft): Remove. (hires_ns::nsecs): New prototype. (hires_ns::usecs): Rewrite in terms of nsecs. (hires_ns::resolution): New prototype. * times.cc: Change hires_us to hires_ns. (ntod): Declare. (systime): Remove. (hires_ns::prime): Increase resolution to nanoseconds. (hires_ns::nsecs): Rename usecs to nsecs to reflect increased resolution. Remove justdelta argument. (hires_ns::resolution): New function. (clock_gettime): Accept CLOCK_MONOTONIC. Use EINVAL instead of ENOSYS per POSIX.1-2004. (clock_getres): Ditto. (clock_setres): Use EINVAL instead of ENOSYS to conform with other implementations. * strace.cc (strace::microseconds): Adjust for hires_ns. * sysconf.cc (sca): Set _SC_MONOTONIC_CLOCK to _POSIX_MONOTONIC_CLOCK. * include/cygwin/version.h (CYGWIN_VERSION_API_MINOR): Bump.
Diffstat (limited to 'winsup/cygwin/times.cc')
-rw-r--r--winsup/cygwin/times.cc96
1 files changed, 66 insertions, 30 deletions
diff --git a/winsup/cygwin/times.cc b/winsup/cygwin/times.cc
index 3b154164c..c911cfe54 100644
--- a/winsup/cygwin/times.cc
+++ b/winsup/cygwin/times.cc
@@ -36,6 +36,8 @@ details. */
to handle that case. */
hires_ms gtod __attribute__((section (".cygwin_dll_common"), shared));
+hires_ns NO_COPY ntod;
+
static inline LONGLONG
systime_ns ()
{
@@ -48,12 +50,6 @@ systime_ns ()
return x.QuadPart;
}
-static inline LONGLONG
-systime ()
-{
- return systime_ns () / 10;
-}
-
/* Cygwin internal */
static unsigned long long __stdcall
__to_clock_t (FILETIME *src, int flag)
@@ -623,7 +619,7 @@ cygwin_tzset ()
#define stupid_printf if (cygwin_finished_initializing) debug_printf
void
-hires_us::prime ()
+hires_ns::prime ()
{
LARGE_INTEGER ifreq;
if (!QueryPerformanceFrequency (&ifreq))
@@ -642,14 +638,13 @@ hires_us::prime ()
return;
}
- primed_ft.QuadPart = systime ();
- freq = (double) ((double) 1000000. / (double) ifreq.QuadPart);
+ freq = (double) ((double) 1000000000. / (double) ifreq.QuadPart);
inited = true;
SetThreadPriority (GetCurrentThread (), priority);
}
LONGLONG
-hires_us::usecs (bool justdelta)
+hires_ns::nsecs ()
{
if (!inited)
prime ();
@@ -668,8 +663,7 @@ hires_us::usecs (bool justdelta)
// FIXME: Use round() here?
now.QuadPart = (LONGLONG) (freq * (double) (now.QuadPart - primed_pc.QuadPart));
- LONGLONG res = justdelta ? now.QuadPart : primed_ft.QuadPart + now.QuadPart;
- return res;
+ return now.QuadPart;
}
void
@@ -706,23 +700,53 @@ hires_ms::nsecs ()
extern "C" int
clock_gettime (clockid_t clk_id, struct timespec *tp)
{
- if (clk_id != CLOCK_REALTIME)
+ switch (clk_id)
{
- set_errno (ENOSYS);
- return -1;
+ case CLOCK_REALTIME:
+ {
+ LONGLONG now = gtod.nsecs ();
+ if (now == (LONGLONG) -1)
+ return -1;
+ tp->tv_sec = now / NSPERSEC;
+ tp->tv_nsec = (now % NSPERSEC) * (1000000000 / NSPERSEC);
+ break;
+ }
+
+ case CLOCK_MONOTONIC:
+ {
+ LONGLONG now = ntod.nsecs ();
+ if (now == (LONGLONG) -1)
+ return -1;
+
+ tp->tv_sec = now / 1000000000;
+ tp->tv_nsec = (now % 1000000000);
+ break;
+ }
+
+ default:
+ set_errno (EINVAL);
+ return -1;
}
- LONGLONG now = gtod.nsecs ();
- if (now == (LONGLONG) -1)
- return -1;
-
- tp->tv_sec = now / NSPERSEC;
- tp->tv_nsec = (now % NSPERSEC) * (1000000000 / NSPERSEC);
return 0;
}
static DWORD minperiod; // FIXME: Maintain period after a fork.
+LONGLONG
+hires_ns::resolution()
+{
+ if (!inited)
+ prime ();
+ if (inited < 0)
+ {
+ set_errno (ENOSYS);
+ return (long long) -1;
+ }
+
+ return (LONGLONG) freq;
+}
+
UINT
hires_ms::resolution ()
{
@@ -753,17 +777,29 @@ hires_ms::resolution ()
extern "C" int
clock_getres (clockid_t clk_id, struct timespec *tp)
{
- if (clk_id != CLOCK_REALTIME)
+ switch (clk_id)
{
- set_errno (ENOSYS);
- return -1;
+ case CLOCK_REALTIME:
+ {
+ DWORD period = gtod.resolution ();
+ tp->tv_sec = period / 1000;
+ tp->tv_nsec = (period % 1000) * 1000000;
+ break;
+ }
+
+ case CLOCK_MONOTONIC:
+ {
+ LONGLONG period = ntod.resolution ();
+ tp->tv_sec = period / 1000000000;
+ tp->tv_nsec = period % 1000000000;
+ break;
+ }
+
+ default:
+ set_errno (EINVAL);
+ return -1;
}
- DWORD period = gtod.resolution ();
-
- tp->tv_sec = period / 1000;
- tp->tv_nsec = (period % 1000) * 1000000;
-
return 0;
}
@@ -773,7 +809,7 @@ clock_setres (clockid_t clk_id, struct timespec *tp)
static NO_COPY bool period_set;
if (clk_id != CLOCK_REALTIME)
{
- set_errno (ENOSYS);
+ set_errno (EINVAL);
return -1;
}