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.
This commit is contained in:
parent
f717289618
commit
b150f5236b
|
@ -1,3 +1,27 @@
|
||||||
|
2010-08-09 Yaakov Selkowitz <yselkowitz@users.sourceforge.net>
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
2010-08-09 Yaakov Selkowitz <yselkowitz@users.sourceforge.net>
|
2010-08-09 Yaakov Selkowitz <yselkowitz@users.sourceforge.net>
|
||||||
|
|
||||||
* fhandler_proc.cc: Add /proc/filesystems virtual file.
|
* fhandler_proc.cc: Add /proc/filesystems virtual file.
|
||||||
|
|
|
@ -29,14 +29,15 @@ class hires_base
|
||||||
void reset() {inited = false;}
|
void reset() {inited = false;}
|
||||||
};
|
};
|
||||||
|
|
||||||
class hires_us : public hires_base
|
class hires_ns : public hires_base
|
||||||
{
|
{
|
||||||
LARGE_INTEGER primed_ft;
|
|
||||||
LARGE_INTEGER primed_pc;
|
LARGE_INTEGER primed_pc;
|
||||||
double freq;
|
double freq;
|
||||||
void prime ();
|
void prime ();
|
||||||
public:
|
public:
|
||||||
LONGLONG usecs (bool justdelta);
|
LONGLONG nsecs ();
|
||||||
|
LONGLONG usecs () {return nsecs () / 1000LL;}
|
||||||
|
LONGLONG resolution();
|
||||||
};
|
};
|
||||||
|
|
||||||
class hires_ms : public hires_base
|
class hires_ms : public hires_base
|
||||||
|
|
|
@ -389,12 +389,13 @@ details. */
|
||||||
227: Add pseudo_reloc_start, pseudo_reloc_end, image_base to per_process.
|
227: Add pseudo_reloc_start, pseudo_reloc_end, image_base to per_process.
|
||||||
228: CW_STRERROR added.
|
228: CW_STRERROR added.
|
||||||
229: Add mkostemp, mkostemps.
|
229: Add mkostemp, mkostemps.
|
||||||
|
230: Add CLOCK_MONOTONIC.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* 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 229
|
#define CYGWIN_VERSION_API_MINOR 230
|
||||||
|
|
||||||
/* 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
|
||||||
|
|
|
@ -74,8 +74,8 @@ strace::hello ()
|
||||||
int
|
int
|
||||||
strace::microseconds ()
|
strace::microseconds ()
|
||||||
{
|
{
|
||||||
static hires_us now;
|
static hires_ns now;
|
||||||
return (int) now.usecs (true);
|
return (int) now.usecs ();
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __stdcall
|
static int __stdcall
|
||||||
|
|
|
@ -165,7 +165,7 @@ static struct
|
||||||
{cons, {c:IOV_MAX}}, /* 66, _SC_IOV_MAX */
|
{cons, {c:IOV_MAX}}, /* 66, _SC_IOV_MAX */
|
||||||
{cons, {c:_POSIX_IPV6}}, /* 67, _SC_IPV6 */
|
{cons, {c:_POSIX_IPV6}}, /* 67, _SC_IPV6 */
|
||||||
{cons, {c:LINE_MAX}}, /* 68, _SC_LINE_MAX */
|
{cons, {c:LINE_MAX}}, /* 68, _SC_LINE_MAX */
|
||||||
{cons, {c:-1L}}, /* 69, _SC_MONOTONIC_CLOCK */
|
{cons, {c:_POSIX_MONOTONIC_CLOCK}}, /* 69, _SC_MONOTONIC_CLOCK */
|
||||||
{cons, {c:_POSIX_RAW_SOCKETS}}, /* 70, _SC_RAW_SOCKETS */
|
{cons, {c:_POSIX_RAW_SOCKETS}}, /* 70, _SC_RAW_SOCKETS */
|
||||||
{cons, {c:_POSIX_READER_WRITER_LOCKS}}, /* 71, _SC_READER_WRITER_LOCKS */
|
{cons, {c:_POSIX_READER_WRITER_LOCKS}}, /* 71, _SC_READER_WRITER_LOCKS */
|
||||||
{cons, {c:_POSIX_REGEXP}}, /* 72, _SC_REGEXP */
|
{cons, {c:_POSIX_REGEXP}}, /* 72, _SC_REGEXP */
|
||||||
|
|
|
@ -36,6 +36,8 @@ details. */
|
||||||
to handle that case. */
|
to handle that case. */
|
||||||
hires_ms gtod __attribute__((section (".cygwin_dll_common"), shared));
|
hires_ms gtod __attribute__((section (".cygwin_dll_common"), shared));
|
||||||
|
|
||||||
|
hires_ns NO_COPY ntod;
|
||||||
|
|
||||||
static inline LONGLONG
|
static inline LONGLONG
|
||||||
systime_ns ()
|
systime_ns ()
|
||||||
{
|
{
|
||||||
|
@ -48,12 +50,6 @@ systime_ns ()
|
||||||
return x.QuadPart;
|
return x.QuadPart;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline LONGLONG
|
|
||||||
systime ()
|
|
||||||
{
|
|
||||||
return systime_ns () / 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Cygwin internal */
|
/* Cygwin internal */
|
||||||
static unsigned long long __stdcall
|
static unsigned long long __stdcall
|
||||||
__to_clock_t (FILETIME *src, int flag)
|
__to_clock_t (FILETIME *src, int flag)
|
||||||
|
@ -623,7 +619,7 @@ cygwin_tzset ()
|
||||||
|
|
||||||
#define stupid_printf if (cygwin_finished_initializing) debug_printf
|
#define stupid_printf if (cygwin_finished_initializing) debug_printf
|
||||||
void
|
void
|
||||||
hires_us::prime ()
|
hires_ns::prime ()
|
||||||
{
|
{
|
||||||
LARGE_INTEGER ifreq;
|
LARGE_INTEGER ifreq;
|
||||||
if (!QueryPerformanceFrequency (&ifreq))
|
if (!QueryPerformanceFrequency (&ifreq))
|
||||||
|
@ -642,14 +638,13 @@ hires_us::prime ()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
primed_ft.QuadPart = systime ();
|
freq = (double) ((double) 1000000000. / (double) ifreq.QuadPart);
|
||||||
freq = (double) ((double) 1000000. / (double) ifreq.QuadPart);
|
|
||||||
inited = true;
|
inited = true;
|
||||||
SetThreadPriority (GetCurrentThread (), priority);
|
SetThreadPriority (GetCurrentThread (), priority);
|
||||||
}
|
}
|
||||||
|
|
||||||
LONGLONG
|
LONGLONG
|
||||||
hires_us::usecs (bool justdelta)
|
hires_ns::nsecs ()
|
||||||
{
|
{
|
||||||
if (!inited)
|
if (!inited)
|
||||||
prime ();
|
prime ();
|
||||||
|
@ -668,8 +663,7 @@ hires_us::usecs (bool justdelta)
|
||||||
|
|
||||||
// FIXME: Use round() here?
|
// FIXME: Use round() here?
|
||||||
now.QuadPart = (LONGLONG) (freq * (double) (now.QuadPart - primed_pc.QuadPart));
|
now.QuadPart = (LONGLONG) (freq * (double) (now.QuadPart - primed_pc.QuadPart));
|
||||||
LONGLONG res = justdelta ? now.QuadPart : primed_ft.QuadPart + now.QuadPart;
|
return now.QuadPart;
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -706,23 +700,53 @@ hires_ms::nsecs ()
|
||||||
extern "C" int
|
extern "C" int
|
||||||
clock_gettime (clockid_t clk_id, struct timespec *tp)
|
clock_gettime (clockid_t clk_id, struct timespec *tp)
|
||||||
{
|
{
|
||||||
if (clk_id != CLOCK_REALTIME)
|
switch (clk_id)
|
||||||
{
|
{
|
||||||
set_errno (ENOSYS);
|
case CLOCK_REALTIME:
|
||||||
return -1;
|
{
|
||||||
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static DWORD minperiod; // FIXME: Maintain period after a fork.
|
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
|
UINT
|
||||||
hires_ms::resolution ()
|
hires_ms::resolution ()
|
||||||
{
|
{
|
||||||
|
@ -753,17 +777,29 @@ hires_ms::resolution ()
|
||||||
extern "C" int
|
extern "C" int
|
||||||
clock_getres (clockid_t clk_id, struct timespec *tp)
|
clock_getres (clockid_t clk_id, struct timespec *tp)
|
||||||
{
|
{
|
||||||
if (clk_id != CLOCK_REALTIME)
|
switch (clk_id)
|
||||||
{
|
{
|
||||||
set_errno (ENOSYS);
|
case CLOCK_REALTIME:
|
||||||
return -1;
|
{
|
||||||
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -773,7 +809,7 @@ clock_setres (clockid_t clk_id, struct timespec *tp)
|
||||||
static NO_COPY bool period_set;
|
static NO_COPY bool period_set;
|
||||||
if (clk_id != CLOCK_REALTIME)
|
if (clk_id != CLOCK_REALTIME)
|
||||||
{
|
{
|
||||||
set_errno (ENOSYS);
|
set_errno (EINVAL);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue