diff options
Diffstat (limited to 'winsup/cygwin')
-rw-r--r-- | winsup/cygwin/ChangeLog | 7 | ||||
-rw-r--r-- | winsup/cygwin/hires.h | 24 | ||||
-rw-r--r-- | winsup/cygwin/times.cc | 88 |
3 files changed, 96 insertions, 23 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 8224c9d..9275108 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,10 @@ +2002-02-15 Christopher Faylor <cgf@redhat.com> + + * hires.h: New file. + * times.cc (gettimeofday): Use hires class for calculating current time. + (hires::prime): New method. + (hires::utime): Ditto. + 2002-02-14 Christopher Faylor <cgf@redhat.com> * include/sys/cygwin.h (cygwin_getinfo_types): New CW_STRACE_ACTIVE. diff --git a/winsup/cygwin/hires.h b/winsup/cygwin/hires.h new file mode 100644 index 0000000..06a0016 --- /dev/null +++ b/winsup/cygwin/hires.h @@ -0,0 +1,24 @@ +/* hires.h: Definitions for hires clock calculations + + Copyright 2002 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 __HIRES_H__ +#define __HIRES_H__ + +class hires +{ + int inited; + LARGE_INTEGER primed_ft; + LARGE_INTEGER primed_pc; + double freq; + void prime (); + public: + LONGLONG utime (); +}; +#endif /*__HIRES_H__*/ diff --git a/winsup/cygwin/times.cc b/winsup/cygwin/times.cc index 1993c58..a30374a 100644 --- a/winsup/cygwin/times.cc +++ b/winsup/cygwin/times.cc @@ -24,6 +24,7 @@ details. */ #include "sync.h" #include "sigproc.h" #include "pinfo.h" +#include "hires.h" #define FACTOR (0x19db1ded53e8000LL) #define NSPERSEC 10000000LL @@ -149,34 +150,21 @@ totimeval (struct timeval *dst, FILETIME *src, int sub, int flag) dst->tv_sec = x / (long long) (1e6); } -/* gettimeofday: BSD */ +/* FIXME: Make thread safe */ extern "C" int -gettimeofday (struct timeval *p, struct timezone *z) +gettimeofday(struct timeval *tv, struct timezone *tz) { - int res = 0; - - if (p != NULL) - { - FILETIME f; - - GetSystemTimeAsFileTime (&f); - totimeval (p, &f, 0, 1); - } - - if (z != NULL) - { - tzset(); - z->tz_minuteswest = _timezone / 60; - z->tz_dsttime = _daylight; - } - - syscall_printf ("%d = gettimeofday (%x, %x)", res, p, z); + static hires gtod; + LONGLONG now = gtod.utime (); + if (now == (LONGLONG) -1) + return -1; - return res; + tv->tv_sec = now / 1000000; + tv->tv_usec = now % 1000000; + return 0; } -extern "C" -int +extern "C" int _gettimeofday (struct timeval *p, struct timezone *z) { return gettimeofday (p, z); @@ -569,3 +557,57 @@ void cygwin_tzset () { } + +void +hires::prime () +{ + LARGE_INTEGER ifreq; + if (!QueryPerformanceFrequency (&ifreq)) + { + inited = -1; + return; + } + + FILETIME f; + int priority = GetThreadPriority (GetCurrentThread ()); + SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_TIME_CRITICAL); + if (!QueryPerformanceCounter (&primed_pc)) + { + inited = -1; + return; + } + + GetSystemTimeAsFileTime (&f); + SetThreadPriority (GetCurrentThread (), priority); + + inited = 1; + primed_ft.HighPart = f.dwHighDateTime; + primed_ft.LowPart = f.dwLowDateTime; + primed_ft.QuadPart -= FACTOR; + primed_ft.QuadPart /= 10; + freq = (double) ((double) 1000000. / (double) ifreq.QuadPart); + return; +} + +LONGLONG +hires::utime () +{ + if (!inited) + prime (); + if (inited < 0) + { + set_errno (ENOSYS); + return (long long) -1; + } + + LARGE_INTEGER now; + if (!QueryPerformanceCounter (&now)) + { + set_errno (ENOSYS); + return -1; + } + + now.QuadPart -= primed_pc.QuadPart; + // FIXME: Use round() here? + return primed_ft.QuadPart + (LONGLONG) ((double) now.QuadPart * freq); +} |