Streamline time/times functionality. Remove last remains of former

Windows 9x compatibility.
	* fhandler_disk_file.cc (fhandler_base::fstat_helper): Drop now unneeded
	casts in calls to_timestruc_t.
	(fhandler_base::utimens_fs): Ditto for timespec_to_filetime.
	* fhandler_proc.cc (format_proc_stat): Ditto for to_time_t.
	* hires.h (class hires_ms): Remove unused member initime_ns.
	Remove declarations for timeGetTime_ns and prime.
	(hires_ms::uptime): Remove.
	* posix_ipc.cc (ipc_cond_timedwait): Ditto for timespec_to_filetime.
	* fhandler_registry.cc (fhandler_registry::fstat): Add cast.
	* resource.cc (fill_rusage): Call NtQueryInformationProcess rather than
	GetProcessTimes to deal with LARGE_INTEGER rather than FILETIME.
	* times.cc: Simplify time handling.  Throughout, use LARGE_INTEGER
	rather than FILETIME to simplify computations.  Throughout use
	{u}int64_t rather than {unsigned} long long.  Drop unneeded casts since
	NSPERSEC is 64 bit anyway.
	(systime_ns): Remove.
	(times): Call NtQuerySystemInformation to fetch boot time.  Call
	NtQueryInformationProcess rather than GetProcessTimes to deal with
	LARGE_INTEGER rather than FILETIME.  Call GetSystemTimeAsFileTime.
	(totimeval): Use constant 1000000 as in other functions.
	(time_t_to_filetime): Remove.
	(to_time_t): Change return type to time_t.
	(time_as_timestruc_t): Rename filetime to systime.
	(time): Ditto. Add cast.
	(hires_ns::nsecs): Fix return type cast.
	(hires_ms::timeGetTime_ns): Remove.
	(hires_ns::prime): Remove.
	(hires_ms::nsecs): Drop call to prime.  Call GetSystemTimeAsFileTime
	directly.  Subtract FACTOR here since it's the only function needing
	to do so.
	(minperiod): Cosmetically change to ULONG.
	(hires_ns::resolution): Fix return type cast.
	(hires_ms::resolution): Simplify, rely on NtQueryTimerResolution.
	* winsup.h: Align time related prototypes to above changes.
This commit is contained in:
Corinna Vinschen 2013-06-14 09:09:41 +00:00
parent ba763af559
commit 0ff057d5a5
9 changed files with 141 additions and 214 deletions

View File

@ -1,3 +1,42 @@
2013-06-13 Corinna Vinschen <corinna@vinschen.de>
Streamline time/times functionality. Remove last remains of former
Windows 9x compatibility.
* fhandler_disk_file.cc (fhandler_base::fstat_helper): Drop now unneeded
casts in calls to_timestruc_t.
(fhandler_base::utimens_fs): Ditto for timespec_to_filetime.
* fhandler_proc.cc (format_proc_stat): Ditto for to_time_t.
* hires.h (class hires_ms): Remove unused member initime_ns.
Remove declarations for timeGetTime_ns and prime.
(hires_ms::uptime): Remove.
* posix_ipc.cc (ipc_cond_timedwait): Ditto for timespec_to_filetime.
* fhandler_registry.cc (fhandler_registry::fstat): Add cast.
* resource.cc (fill_rusage): Call NtQueryInformationProcess rather than
GetProcessTimes to deal with LARGE_INTEGER rather than FILETIME.
* times.cc: Simplify time handling. Throughout, use LARGE_INTEGER
rather than FILETIME to simplify computations. Throughout use
{u}int64_t rather than {unsigned} long long. Drop unneeded casts since
NSPERSEC is 64 bit anyway.
(systime_ns): Remove.
(times): Call NtQuerySystemInformation to fetch boot time. Call
NtQueryInformationProcess rather than GetProcessTimes to deal with
LARGE_INTEGER rather than FILETIME. Call GetSystemTimeAsFileTime.
(totimeval): Use constant 1000000 as in other functions.
(time_t_to_filetime): Remove.
(to_time_t): Change return type to time_t.
(time_as_timestruc_t): Rename filetime to systime.
(time): Ditto. Add cast.
(hires_ns::nsecs): Fix return type cast.
(hires_ms::timeGetTime_ns): Remove.
(hires_ns::prime): Remove.
(hires_ms::nsecs): Drop call to prime. Call GetSystemTimeAsFileTime
directly. Subtract FACTOR here since it's the only function needing
to do so.
(minperiod): Cosmetically change to ULONG.
(hires_ns::resolution): Fix return type cast.
(hires_ms::resolution): Simplify, rely on NtQueryTimerResolution.
* winsup.h: Align time related prototypes to above changes.
2013-06-13 Corinna Vinschen <corinna@vinschen.de>
* net.cc (gen_old_if_name): New function to generate short interface

View File

@ -518,14 +518,14 @@ fhandler_base::fstat_helper (struct stat *buf,
PFILE_NETWORK_OPEN_INFORMATION pfnoi = pc.fnoi ();
ULONG attributes = pc.file_attributes ();
to_timestruc_t ((PFILETIME) &pfnoi->LastAccessTime, &buf->st_atim);
to_timestruc_t ((PFILETIME) &pfnoi->LastWriteTime, &buf->st_mtim);
to_timestruc_t (&pfnoi->LastAccessTime, &buf->st_atim);
to_timestruc_t (&pfnoi->LastWriteTime, &buf->st_mtim);
/* If the ChangeTime is 0, the underlying FS doesn't support this timestamp
(FAT for instance). If so, it's faked using LastWriteTime. */
to_timestruc_t (pfnoi->ChangeTime.QuadPart ? (PFILETIME) &pfnoi->ChangeTime
: (PFILETIME) &pfnoi->LastWriteTime,
to_timestruc_t (pfnoi->ChangeTime.QuadPart ? &pfnoi->ChangeTime
: &pfnoi->LastWriteTime,
&buf->st_ctim);
to_timestruc_t ((PFILETIME) &pfnoi->CreationTime, &buf->st_birthtim);
to_timestruc_t (&pfnoi->CreationTime, &buf->st_birthtim);
buf->st_dev = get_dev ();
/* CV 2011-01-13: Observations on the Cygwin mailing list point to an
interesting behaviour in some Windows versions. Apparently the size of
@ -1343,8 +1343,8 @@ fhandler_base::utimens_fs (const struct timespec *tvp)
fbi.CreationTime.QuadPart = 0LL;
/* UTIME_OMIT is handled in timespec_to_filetime by setting FILETIME to 0. */
timespec_to_filetime (&tmp[0], (LPFILETIME) &fbi.LastAccessTime);
timespec_to_filetime (&tmp[1], (LPFILETIME) &fbi.LastWriteTime);
timespec_to_filetime (&tmp[0], &fbi.LastAccessTime);
timespec_to_filetime (&tmp[1], &fbi.LastWriteTime);
fbi.ChangeTime.QuadPart = 0LL;
fbi.FileAttributes = 0;
NTSTATUS status = NtSetInformationFile (get_handle (), &io, &fbi, sizeof fbi,

View File

@ -570,7 +570,7 @@ format_proc_stat (void *, char *&destbuf)
swap_in = spi->PagesRead;
swap_out = spi->PagefilePagesWritten;
context_switches = spi->ContextSwitches;
boot_time = to_time_t ((FILETIME *) &stodi.BootTime.QuadPart);
boot_time = to_time_t (&stodi.BootTime);
eobuf += __small_sprintf (eobuf, "page %u %u\n"
"swap %u %u\n"

View File

@ -508,7 +508,7 @@ fhandler_registry::fstat (struct stat *buf)
RegQueryInfoKeyW (hKey, NULL, NULL, NULL, &subkey_count, NULL,
NULL, NULL, NULL, NULL, NULL, &ftLastWriteTime))
{
to_timestruc_t (&ftLastWriteTime, &buf->st_mtim);
to_timestruc_t ((PLARGE_INTEGER) &ftLastWriteTime, &buf->st_mtim);
buf->st_ctim = buf->st_birthtim = buf->st_mtim;
time_as_timestruc_t (&buf->st_atim);
if (file_type > virt_none)

View File

@ -1,6 +1,6 @@
/* hires.h: Definitions for hires clock calculations
Copyright 2002, 2003, 2004, 2005, 2009, 2010, 2011, 2012 Red Hat, Inc.
Copyright 2002, 2003, 2004, 2005, 2009, 2010, 2011, 2012, 2013 Red Hat, Inc.
This file is part of Cygwin.
@ -55,15 +55,11 @@ class hires_ns : public hires_base
class hires_ms : public hires_base
{
LONGLONG initime_ns;
LONGLONG timeGetTime_ns ();
void prime ();
public:
LONGLONG nsecs ();
LONGLONG usecs () {return nsecs () / 10LL;}
LONGLONG msecs () {return nsecs () / 10000LL;}
UINT resolution ();
LONGLONG uptime () {return (nsecs () - initime_ns) / 10000LL;}
};
extern hires_ms gtod;

View File

@ -199,7 +199,7 @@ ipc_cond_timedwait (HANDLE evt, HANDLE mtx, const struct timespec *abstime)
NotificationTimer);
if (!NT_SUCCESS (status))
return geterrno_from_nt_status (status);
timespec_to_filetime (abstime, (FILETIME *) &duetime);
timespec_to_filetime (abstime, &duetime);
status = NtSetTimer (w4[timer_idx], &duetime, NULL, NULL, FALSE, 0, NULL);
if (!NT_SUCCESS (status))
{

View File

@ -65,18 +65,16 @@ add_rusage (struct rusage *r1, struct rusage *r2)
void __stdcall
fill_rusage (struct rusage *r, HANDLE h)
{
FILETIME creation_time = {0,0};
FILETIME exit_time = {0,0};
FILETIME kernel_time = {0,0};
FILETIME user_time = {0,0};
KERNEL_USER_TIMES kut;
struct timeval tv;
memset (r, 0, sizeof (*r));
GetProcessTimes (h, &creation_time, &exit_time, &kernel_time, &user_time);
totimeval (&tv, &kernel_time, 0, 0);
memset (&kut, 0, sizeof kut);
memset (r, 0, sizeof *r);
NtQueryInformationProcess (h, ProcessTimes, &kut, sizeof kut, NULL);
totimeval (&tv, &kut.KernelTime, 0, 0);
add_timeval (&r->ru_stime, &tv);
totimeval (&tv, &user_time, 0, 0);
totimeval (&tv, &kut.UserTime, 0, 0);
add_timeval (&r->ru_utime, &tv);
VM_COUNTERS vmc;

View File

@ -1,7 +1,7 @@
/* times.cc
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
2007, 2008, 2009, 2010, 2011, 2012 Red Hat, Inc.
2007, 2008, 2009, 2010, 2011, 2012, 2013 Red Hat, Inc.
This file is part of Cygwin.
@ -31,28 +31,17 @@ hires_ms NO_COPY gtod;
hires_ns NO_COPY ntod;
static inline LONGLONG
systime_ns ()
{
LARGE_INTEGER x;
GetSystemTimeAsFileTime ((LPFILETIME) &x);
x.QuadPart -= FACTOR; /* Add conversion factor for UNIX vs. Windows base time */
return x.QuadPart;
}
/* Cygwin internal */
static unsigned long long __stdcall
__to_clock_t (FILETIME *src, int flag)
static uint64_t __stdcall
__to_clock_t (PLARGE_INTEGER src, int flag)
{
unsigned long long total = ((unsigned long long) src->dwHighDateTime << 32) + ((unsigned)src->dwLowDateTime);
syscall_printf ("dwHighDateTime %u, dwLowDateTime %u", src->dwHighDateTime, src->dwLowDateTime);
uint64_t total = src->QuadPart;
/* Convert into clock ticks - the total is in 10ths of a usec. */
if (flag)
total -= FACTOR;
total /= (unsigned long long) (NSPERSEC / CLOCKS_PER_SEC);
syscall_printf ("total %08x %08x", (unsigned) (total>>32), (unsigned) (total));
total /= NSPERSEC / CLOCKS_PER_SEC;
debug_printf ("total %016X", total);
return total;
}
@ -60,31 +49,37 @@ __to_clock_t (FILETIME *src, int flag)
extern "C" clock_t
times (struct tms *buf)
{
FILETIME creation_time, exit_time, kernel_time, user_time;
myfault efault;
if (efault.faulted (EFAULT))
return ((clock_t) -1);
LONGLONG ticks = gtod.uptime ();
/* Ticks is in milliseconds, convert to our ticks. Use long long to prevent
overflow. */
clock_t tc = (clock_t) (ticks * CLOCKS_PER_SEC / 1000);
static SYSTEM_TIMEOFDAY_INFORMATION stodi;
KERNEL_USER_TIMES kut;
LARGE_INTEGER ticks;
GetProcessTimes (GetCurrentProcess (), &creation_time, &exit_time,
&kernel_time, &user_time);
/* Fetch boot time if we haven't already. */
if (!stodi.BootTime.QuadPart)
NtQuerySystemInformation (SystemTimeOfDayInformation,
&stodi, sizeof stodi, NULL);
NtQueryInformationProcess (NtCurrentProcess (), ProcessTimes,
&kut, sizeof kut, NULL);
GetSystemTimeAsFileTime ((LPFILETIME) &ticks);
/* uptime */
ticks.QuadPart -= stodi.BootTime.QuadPart;
/* ticks is in in 100ns, convert to clock ticks. */
clock_t tc = (clock_t) (ticks.QuadPart * CLOCKS_PER_SEC / NSPERSEC);
syscall_printf ("ticks %D, CLOCKS_PER_SEC %d", ticks, CLOCKS_PER_SEC);
syscall_printf ("user_time %D, kernel_time %D, "
"creation_time %D, exit_time %D",
user_time, kernel_time,
creation_time, exit_time);
buf->tms_stime = __to_clock_t (&kernel_time, 0);
buf->tms_utime = __to_clock_t (&user_time, 0);
timeval_to_filetime (&myself->rusage_children.ru_stime, &kernel_time);
buf->tms_cstime = __to_clock_t (&kernel_time, 1);
timeval_to_filetime (&myself->rusage_children.ru_utime, &user_time);
buf->tms_cutime = __to_clock_t (&user_time, 1);
syscall_printf ("UserTime %D, KernelTime %D, CreationTime %D, ExitTime %D",
kut.UserTime, kut.KernelTime, kut.CreateTime, kut.ExitTime);
buf->tms_stime = __to_clock_t (&kut.KernelTime, 0);
buf->tms_utime = __to_clock_t (&kut.UserTime, 0);
timeval_to_filetime (&myself->rusage_children.ru_stime, &kut.KernelTime);
buf->tms_cstime = __to_clock_t (&kut.KernelTime, 1);
timeval_to_filetime (&myself->rusage_children.ru_utime, &kut.UserTime);
buf->tms_cutime = __to_clock_t (&kut.UserTime, 1);
return tc;
}
@ -142,15 +137,15 @@ timezone (void)
/* Cygwin internal */
void __stdcall
totimeval (struct timeval *dst, FILETIME *src, int sub, int flag)
totimeval (struct timeval *dst, PLARGE_INTEGER src, int sub, int flag)
{
long long x = __to_clock_t (src, flag);
int64_t x = __to_clock_t (src, flag);
x *= (int) (1e6) / CLOCKS_PER_SEC; /* Turn x into usecs */
x -= (long long) sub * (int) (1e6);
x *= (int64_t) 1000000 / CLOCKS_PER_SEC; /* Turn x into usecs */
x -= (int64_t) sub * 1000000;
dst->tv_usec = x % (long long) (1e6); /* And split */
dst->tv_sec = x / (long long) (1e6);
dst->tv_usec = x % 1000000; /* And split */
dst->tv_sec = x / 1000000;
}
/* FIXME: Make thread safe */
@ -183,38 +178,23 @@ gettimeofday (struct timeval *tv, void *tzvp)
EXPORT_ALIAS (gettimeofday, _gettimeofday)
/* Cygwin internal */
void
time_t_to_filetime (time_t time_in, FILETIME *out)
{
long long x = time_in * NSPERSEC + FACTOR;
out->dwHighDateTime = x >> 32;
out->dwLowDateTime = x;
}
/* Cygwin internal */
void __stdcall
timespec_to_filetime (const struct timespec *time_in, FILETIME *out)
timespec_to_filetime (const struct timespec *time_in, PLARGE_INTEGER out)
{
if (time_in->tv_nsec == UTIME_OMIT)
out->dwHighDateTime = out->dwLowDateTime = 0;
out->QuadPart = 0;
else
{
long long x = time_in->tv_sec * NSPERSEC +
time_in->tv_nsec / (1000000000/NSPERSEC) + FACTOR;
out->dwHighDateTime = x >> 32;
out->dwLowDateTime = x;
}
out->QuadPart = time_in->tv_sec * NSPERSEC
+ time_in->tv_nsec / (1000000000/NSPERSEC) + FACTOR;
}
/* Cygwin internal */
void __stdcall
timeval_to_filetime (const struct timeval *time_in, FILETIME *out)
timeval_to_filetime (const struct timeval *time_in, PLARGE_INTEGER out)
{
long long x = time_in->tv_sec * NSPERSEC +
time_in->tv_usec * (NSPERSEC/1000000) + FACTOR;
out->dwHighDateTime = x >> 32;
out->dwLowDateTime = x;
out->QuadPart = time_in->tv_sec * NSPERSEC
+ time_in->tv_usec * (NSPERSEC/1000000) + FACTOR;
}
/* Cygwin internal */
@ -253,36 +233,36 @@ timeval_to_timespec (const struct timeval *tvp, struct timespec *tmp)
/* Cygwin internal */
/* Convert a Win32 time to "UNIX" format. */
long __stdcall
to_time_t (FILETIME *ptr)
time_t __stdcall
to_time_t (PLARGE_INTEGER ptr)
{
/* A file time is the number of 100ns since jan 1 1601
stuffed into two long words.
A time_t is the number of seconds since jan 1 1970. */
long long x = ((long long) ptr->dwHighDateTime << 32) + ((unsigned)ptr->dwLowDateTime);
int64_t x = ptr->QuadPart;
/* pass "no time" as epoch */
if (x == 0)
return 0;
x -= FACTOR; /* number of 100ns between 1601 and 1970 */
x /= (long long) NSPERSEC; /* number of 100ns in a second */
x /= NSPERSEC; /* number of 100ns in a second */
return x;
}
/* Cygwin internal */
/* Convert a Win32 time to "UNIX" timestruc_t format. */
void __stdcall
to_timestruc_t (FILETIME *ptr, timestruc_t *out)
to_timestruc_t (PLARGE_INTEGER 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);
int64_t rem;
int64_t x = ptr->QuadPart;
/* pass "no time" as epoch */
if (x == 0)
@ -293,8 +273,8 @@ to_timestruc_t (FILETIME *ptr, timestruc_t *out)
}
x -= FACTOR; /* number of 100ns between 1601 and 1970 */
rem = x % ((long long)NSPERSEC);
x /= (long long) NSPERSEC; /* number of 100ns in a second */
rem = x % NSPERSEC;
x /= NSPERSEC; /* number of 100ns in a second */
out->tv_nsec = rem * 100; /* as tv_nsec is in nanoseconds */
out->tv_sec = x;
}
@ -304,10 +284,10 @@ to_timestruc_t (FILETIME *ptr, timestruc_t *out)
void __stdcall
time_as_timestruc_t (timestruc_t * out)
{
FILETIME filetime;
LARGE_INTEGER systime;
GetSystemTimeAsFileTime (&filetime);
to_timestruc_t (&filetime, out);
GetSystemTimeAsFileTime ((LPFILETIME) &systime);
to_timestruc_t (&systime, out);
}
/* time: POSIX 4.5.1.1, C 4.12.2.4 */
@ -316,10 +296,10 @@ extern "C" time_t
time (time_t * ptr)
{
time_t res;
FILETIME filetime;
LARGE_INTEGER systime;
GetSystemTimeAsFileTime (&filetime);
res = to_time_t (&filetime);
GetSystemTimeAsFileTime ((LPFILETIME) &systime);
res = to_time_t (&systime);
if (ptr)
*ptr = res;
@ -486,7 +466,7 @@ hires_ns::nsecs (bool monotonic)
if (inited < 0)
{
set_errno (ENOSYS);
return (long long) -1;
return (LONGLONG) -1;
}
LARGE_INTEGER now;
@ -502,73 +482,13 @@ hires_ns::nsecs (bool monotonic)
return now.QuadPart;
}
LONGLONG
hires_ms::timeGetTime_ns ()
{
LARGE_INTEGER t;
/* This is how timeGetTime is implemented in winmm.dll.
The real timeGetTime subtracts and adds some values which are constant
over the lifetime of the process. Since we don't need absolute accuracy
of the value returned by timeGetTime, only relative accuracy, we can skip
this step. However, if we ever find out that we need absolute accuracy,
here's how it works in it's full beauty:
- At process startup, winmm initializes two calibration values:
DWORD tick_count_start;
LARGE_INTEGER int_time_start;
do
{
tick_count_start = GetTickCount ();
do
{
int_time_start.HighPart = SharedUserData.InterruptTime.High1Time;
int_time_start.LowPart = SharedUserData.InterruptTime.LowPart;
}
while (int_time_start.HighPart
!= SharedUserData.InterruptTime.High2Time);
}
while (tick_count_start != GetTickCount ();
- timeGetTime computes its return value in the loop as below, and then:
t.QuadPart -= int_time_start.QuadPart;
t.QuadPart /= 10000;
t.LowPart += tick_count_start;
return t.LowPart;
*/
do
{
t.HighPart = SharedUserData.InterruptTime.High1Time;
t.LowPart = SharedUserData.InterruptTime.LowPart;
}
while (t.HighPart != SharedUserData.InterruptTime.High2Time);
/* We use the value in full 100ns resolution in the calling functions
anyway, so we can skip dividing by 10000 here. */
return t.QuadPart;
}
void
hires_ms::prime ()
{
if (!inited)
{
int priority = GetThreadPriority (GetCurrentThread ());
SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_TIME_CRITICAL);
initime_ns = systime_ns () - timeGetTime_ns ();
inited = true;
SetThreadPriority (GetCurrentThread (), priority);
}
return;
}
LONGLONG
hires_ms::nsecs ()
{
if (!inited)
prime ();
return systime_ns ();
LARGE_INTEGER systime;
GetSystemTimeAsFileTime ((LPFILETIME) &systime);
/* Add conversion factor for UNIX vs. Windows base time */
return systime.QuadPart - FACTOR;
}
extern "C" int
@ -579,8 +499,7 @@ clock_gettime (clockid_t clk_id, struct timespec *tp)
pid_t pid = CLOCKID_TO_PID (clk_id);
HANDLE hProcess;
KERNEL_USER_TIMES kut;
ULONG sizeof_kut = sizeof (KERNEL_USER_TIMES);
long long x;
int64_t x;
if (pid == 0)
pid = getpid ();
@ -593,11 +512,12 @@ clock_gettime (clockid_t clk_id, struct timespec *tp)
}
hProcess = OpenProcess (PROCESS_QUERY_INFORMATION, 0, p->dwProcessId);
NtQueryInformationProcess (hProcess, ProcessTimes, &kut, sizeof_kut, &sizeof_kut);
NtQueryInformationProcess (hProcess, ProcessTimes,
&kut, sizeof kut, NULL);
x = kut.KernelTime.QuadPart + kut.UserTime.QuadPart;
tp->tv_sec = x / (long long) NSPERSEC;
tp->tv_nsec = (x % (long long) NSPERSEC) * 100LL;
tp->tv_sec = x / NSPERSEC;
tp->tv_nsec = (x % NSPERSEC) * 100LL;
CloseHandle (hProcess);
return 0;
@ -608,8 +528,7 @@ clock_gettime (clockid_t clk_id, struct timespec *tp)
long thr_id = CLOCKID_TO_THREADID (clk_id);
HANDLE hThread;
KERNEL_USER_TIMES kut;
ULONG sizeof_kut = sizeof (KERNEL_USER_TIMES);
long long x;
int64_t x;
if (thr_id == 0)
thr_id = pthread::self ()->getsequence_np ();
@ -621,11 +540,12 @@ clock_gettime (clockid_t clk_id, struct timespec *tp)
return -1;
}
NtQueryInformationThread (hThread, ThreadTimes, &kut, sizeof_kut, &sizeof_kut);
NtQueryInformationThread (hThread, ThreadTimes,
&kut, sizeof kut, NULL);
x = kut.KernelTime.QuadPart + kut.UserTime.QuadPart;
tp->tv_sec = x / (long long) NSPERSEC;
tp->tv_nsec = (x % (long long) NSPERSEC) * 100LL;
tp->tv_sec = x / NSPERSEC;
tp->tv_nsec = (x % NSPERSEC) * 100LL;
CloseHandle (hThread);
return 0;
@ -689,7 +609,7 @@ clock_settime (clockid_t clk_id, const struct timespec *tp)
return settimeofday (&tv, NULL);
}
static DWORD minperiod; // FIXME: Maintain period after a fork.
static ULONG minperiod; // FIXME: Maintain period after a fork.
LONGLONG
hires_ns::resolution ()
@ -699,7 +619,7 @@ hires_ns::resolution ()
if (inited < 0)
{
set_errno (ENOSYS);
return (long long) -1;
return (LONGLONG) -1;
}
return (freq <= 1.0) ? 1LL : (LONGLONG) freq;
@ -710,39 +630,13 @@ hires_ms::resolution ()
{
if (!minperiod)
{
NTSTATUS status;
ULONG coarsest, finest, actual;
status = NtQueryTimerResolution (&coarsest, &finest, &actual);
if (NT_SUCCESS (status))
/* The actual resolution of the OS timer is a system-wide setting which
can be changed any time, by any process. The only fixed value we
can rely on is the coarsest value. */
minperiod = coarsest;
else
{
/* There's no good reason that NtQueryTimerResolution should fail
at all, but let's play it safe. Try to empirically determine
current timer resolution */
int priority = GetThreadPriority (GetCurrentThread ());
SetThreadPriority (GetCurrentThread (),
THREAD_PRIORITY_TIME_CRITICAL);
LONGLONG period = 0;
for (int i = 0; i < 4; i++)
{
LONGLONG now;
LONGLONG then = timeGetTime_ns ();
while ((now = timeGetTime_ns ()) == then)
continue;
then = now;
while ((now = timeGetTime_ns ()) == then)
continue;
period += now - then;
}
SetThreadPriority (GetCurrentThread (), priority);
period /= 4L;
minperiod = (DWORD) period;
}
NtQueryTimerResolution (&coarsest, &finest, &actual);
/* The actual resolution of the OS timer is a system-wide setting which
can be changed any time, by any process. The only fixed value we
can rely on is the coarsest value. */
minperiod = coarsest;
}
return minperiod;
}

View File

@ -214,12 +214,12 @@ void __reg2 nofinalslash (const char *src, char *dst);
void __reg3 *hook_or_detect_cygwin (const char *, const void *, WORD&, HANDLE h = NULL);
/* Time related */
void __stdcall totimeval (struct timeval *, FILETIME *, int, int);
long __stdcall to_time_t (FILETIME *);
void __stdcall to_timestruc_t (FILETIME *, timestruc_t *);
void __stdcall totimeval (struct timeval *, PLARGE_INTEGER, int, int);
time_t __stdcall to_time_t (PLARGE_INTEGER);
void __stdcall to_timestruc_t (PLARGE_INTEGER, timestruc_t *);
void __stdcall time_as_timestruc_t (timestruc_t *);
void __stdcall timespec_to_filetime (const struct timespec *, FILETIME *);
void __stdcall timeval_to_filetime (const struct timeval *, FILETIME *);
void __stdcall timeval_to_filetime (const struct timeval *, PLARGE_INTEGER);
void __stdcall timespec_to_filetime (const struct timespec *, PLARGE_INTEGER);
/* Console related */
void __stdcall set_console_title (char *);