--- /dev/null
+/* 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__*/
#include "sync.h"
#include "sigproc.h"
#include "pinfo.h"
+#include "hires.h"
#define FACTOR (0x19db1ded53e8000LL)
#define NSPERSEC 10000000LL
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);
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);
+}