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:
Diffstat (limited to 'winsup/cygwin/times.cc')
-rw-r--r--winsup/cygwin/times.cc248
1 files changed, 174 insertions, 74 deletions
diff --git a/winsup/cygwin/times.cc b/winsup/cygwin/times.cc
index e5635ddff..6bb981d1a 100644
--- a/winsup/cygwin/times.cc
+++ b/winsup/cygwin/times.cc
@@ -1,6 +1,6 @@
/* times.cc
- Copyright 1996, 1997, 1998, 1999, 2000, 2001 Red Hat, Inc.
+ Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
This file is part of Cygwin.
@@ -17,13 +17,11 @@ details. */
#include <stdlib.h>
#include <errno.h>
#include "cygerrno.h"
-#include "perprocess.h"
#include "security.h"
#include "fhandler.h"
#include "path.h"
-#include "sync.h"
-#include "sigproc.h"
#include "pinfo.h"
+#include "hires.h"
#define FACTOR (0x19db1ded53e8000LL)
#define NSPERSEC 10000000LL
@@ -48,7 +46,7 @@ __to_clock_t (FILETIME * src, int flag)
/* times: POSIX 4.5.2.1 */
extern "C" clock_t
-times (struct tms * buf)
+_times (struct tms * buf)
{
FILETIME creation_time, exit_time, kernel_time, user_time;
@@ -88,12 +86,6 @@ times (struct tms * buf)
return tc;
}
-extern "C" clock_t
-_times (struct tms * buf)
-{
- return times (buf);
-}
-
/* settimeofday: BSD */
extern "C" int
settimeofday (const struct timeval *tv, const struct timezone *tz)
@@ -104,7 +96,7 @@ settimeofday (const struct timeval *tv, const struct timezone *tz)
tz = tz; /* silence warning about unused variable */
- ptm = gmtime(&tv->tv_sec);
+ ptm = gmtime (&tv->tv_sec);
st.wYear = ptm->tm_year + 1900;
st.wMonth = ptm->tm_mon + 1;
st.wDayOfWeek = ptm->tm_wday;
@@ -114,7 +106,7 @@ settimeofday (const struct timeval *tv, const struct timezone *tz)
st.wSecond = ptm->tm_sec;
st.wMilliseconds = tv->tv_usec / 1000;
- res = !SetSystemTime(&st);
+ res = !SetSystemTime (&st);
syscall_printf ("%d = settimeofday (%x, %x)", res, tv, tz);
@@ -126,13 +118,13 @@ extern "C" char *
timezone ()
{
#ifdef _MT_SAFE
- char *b=_reent_winsup()->timezone_buf;
+ char *b=_reent_winsup ()->timezone_buf;
#else
static NO_COPY char b[20] = {0};
#endif
- tzset();
- __small_sprintf (b,"GMT%+d:%02d", (int) (-_timezone / 3600), (int) (abs(_timezone / 60) % 60));
+ tzset ();
+ __small_sprintf (b,"GMT%+d:%02d", (int) (-_timezone / 3600), (int) (abs (_timezone / 60) % 60));
return b;
}
@@ -149,61 +141,39 @@ 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;
+ static hires_ms gtod;
+ static bool tzflag;
+ LONGLONG now = gtod.usecs (false);
+ if (now == (LONGLONG) -1)
+ return -1;
- GetSystemTimeAsFileTime (&f);
- totimeval (p, &f, 0, 1);
- }
+ tv->tv_sec = now / 1000000;
+ tv->tv_usec = now % 1000000;
- if (z != NULL)
+ if (tz != NULL)
{
- tzset();
- z->tz_minuteswest = _timezone / 60;
- z->tz_dsttime = _daylight;
+ if (!tzflag)
+ {
+ tzset ();
+ tzflag = true;
+ }
+ tz->tz_minuteswest = _timezone / 60;
+ tz->tz_dsttime = _daylight;
}
- syscall_printf ("%d = gettimeofday (%x, %x)", res, p, z);
-
- return res;
+ return 0;
}
-extern "C"
-int
+extern "C" int
_gettimeofday (struct timeval *p, struct timezone *z)
{
return gettimeofday (p, z);
}
-#if 0
-/* Work out magic constant below */
-genf ()
-{
- SYSTEMTIME s;
- FILETIME f;
- s.wYear = 1970;
- s.wMonth = 1;
- s.wDayOfWeek = 4;
- s.wDay = 1;
- s.wHour = 0;
- s.wMinute = 0;
- s.wSecond = 0;
- s.wMilliseconds = 0;
- SystemTimeToFileTime (&s, &f);
-
- small_printf ("FILE TIME is %08x%08x\n",
- f.dwHighDateTime,
- f.dwLowDateTime);
-}
-#endif
-
/* Cygwin internal */
void
time_t_to_filetime (time_t time_in, FILETIME *out)
@@ -242,7 +212,6 @@ to_time_t (FILETIME *ptr)
stuffed into two long words.
A time_t is the number of seconds since jan 1 1970. */
- long rem;
long long x = ((long long) ptr->dwHighDateTime << 32) + ((unsigned)ptr->dwLowDateTime);
/* pass "no time" as epoch */
@@ -250,13 +219,51 @@ to_time_t (FILETIME *ptr)
return 0;
x -= FACTOR; /* number of 100ns between 1601 and 1970 */
- rem = x % ((long long)NSPERSEC);
- rem += (NSPERSEC / 2);
x /= (long long) NSPERSEC; /* number of 100ns in a second */
- x += (long long) (rem / NSPERSEC);
return x;
}
+/* Cygwin internal */
+/* Convert a Win32 time to "UNIX" timestruc_t format. */
+void __stdcall
+to_timestruc_t (FILETIME *ptr, timestruc_t *out)
+{
+ /* A file time is the number of 100ns since jan 1 1601
+ stuffed into two long words.
+ A timestruc_t is the number of seconds and microseconds since jan 1 1970
+ stuffed into a time_t and a long. */
+
+ long rem;
+ long long x = ((long long) ptr->dwHighDateTime << 32) + ((unsigned)ptr->dwLowDateTime);
+
+ /* pass "no time" as epoch */
+ if (x == 0)
+ {
+ out->tv_sec = 0;
+ out->tv_nsec = 0;
+ return;
+ }
+
+ x -= FACTOR; /* number of 100ns between 1601 and 1970 */
+ rem = x % ((long long)NSPERSEC);
+ x /= (long long) NSPERSEC; /* number of 100ns in a second */
+ out->tv_nsec = rem * 100; /* as tv_nsec is in nanoseconds */
+ out->tv_sec = x;
+}
+
+/* Cygwin internal */
+/* Get the current time as a "UNIX" timestruc_t format. */
+void __stdcall
+time_as_timestruc_t (timestruc_t * out)
+{
+ SYSTEMTIME systemtime;
+ FILETIME filetime;
+
+ GetSystemTime (&systemtime);
+ SystemTimeToFileTime (&systemtime, &filetime);
+ to_timestruc_t (&filetime, out);
+}
+
/* time: POSIX 4.5.1.1, C 4.12.2.4 */
/* Return number of seconds since 00:00 UTC on jan 1, 1970 */
extern "C"
@@ -461,22 +468,18 @@ utimes (const char *path, struct timeval *tvp)
}
/* MSDN suggests using FILE_FLAG_BACKUP_SEMANTICS for accessing
- the times of directories. FIXME: what about Win95??? */
+ the times of directories. */
/* Note: It's not documented in MSDN that FILE_WRITE_ATTRIBUTES is
sufficient to change the timestamps... */
- HANDLE h = CreateFileA (win32.get_win32 (),
- wincap.has_specific_access_rights () ?
- FILE_WRITE_ATTRIBUTES : GENERIC_WRITE,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- &sec_none_nih,
- OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS,
- 0);
+ HANDLE h = CreateFile (win32, FILE_WRITE_ATTRIBUTES,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ &sec_none_nih, OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS,
+ 0);
if (h == INVALID_HANDLE_VALUE)
{
- if ((res = GetFileAttributes (win32.get_win32 ())) != -1 &&
- (res & FILE_ATTRIBUTE_DIRECTORY))
+ if (win32.isdir ())
{
/* What we can do with directories more? */
res = 0;
@@ -565,8 +568,105 @@ ftime (struct timeb *tp)
}
/* obsolete, changed to cygwin_tzset when localtime.c was added - dj */
-extern "C"
-void
+extern "C" void
cygwin_tzset ()
{
}
+
+void
+hires_us::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))
+ {
+ SetThreadPriority (GetCurrentThread (), priority);
+ 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_us::usecs (bool justdelta)
+{
+ if (!inited)
+ prime ();
+ if (inited < 0)
+ {
+ set_errno (ENOSYS);
+ return (long long) -1;
+ }
+
+ LARGE_INTEGER now;
+ if (!QueryPerformanceCounter (&now))
+ {
+ set_errno (ENOSYS);
+ return -1;
+ }
+
+ // FIXME: Use round() here?
+ now.QuadPart = (LONGLONG) (freq * (double) (now.QuadPart - primed_pc.QuadPart));
+ return justdelta ? now.QuadPart : primed_ft.QuadPart + now.QuadPart;
+}
+
+void
+hires_ms::prime ()
+{
+ TIMECAPS tc;
+ FILETIME f;
+ int priority = GetThreadPriority (GetCurrentThread ());
+ SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_TIME_CRITICAL);
+
+ if (timeGetDevCaps (&tc, sizeof (tc)) != TIMERR_NOERROR)
+ minperiod = 0;
+ else
+ {
+ minperiod = min (max (tc.wPeriodMin, 1), tc.wPeriodMax);
+ timeBeginPeriod (minperiod);
+ }
+
+ initime_ms = timeGetTime ();
+ GetSystemTimeAsFileTime (&f);
+ SetThreadPriority (GetCurrentThread (), priority);
+
+ inited = 1;
+ initime_us.HighPart = f.dwHighDateTime;
+ initime_us.LowPart = f.dwLowDateTime;
+ initime_us.QuadPart -= FACTOR;
+ initime_us.QuadPart /= 10;
+}
+
+LONGLONG
+hires_ms::usecs (bool justdelta)
+{
+ if (!inited)
+ prime ();
+ DWORD now = timeGetTime ();
+ // FIXME: Not sure how this will handle the 49.71 day wrap around
+ LONGLONG res = initime_us.QuadPart + ((LONGLONG) (now - initime_ms) * 1000);
+ return res;
+}
+
+hires_ms::~hires_ms ()
+{
+ timeEndPeriod (minperiod);
+}