* cygtls.h (struct _local_storage): Add cw_timer member.

* cygtls.cc (_cygtls::init_thread): Initialize locals.cw_timer.
(_cygtls::fixup_after_fork): Ditto.
* tlsoffsets.h: Regenerate.
* ntdll.h (enum _TIMER_INFORMATION_CLASS): Define.
(struct _TIMER_BASIC_INFORMATION): Define.
(NtQueryTimer): Declare function.
* thread.h (cancelable_wait): Change timeout argument to
PLARGE_INTEGER and provide NULL default.
(fast_mutex::lock): Adjust accordingly.
(pthread_cond::wait): Change timeout argument to PLARGE_INTEGER
and default to NULL.
* thread.cc (cancelable_wait): Change timeout argument to
PLARGE_INTEGER.  Initialize _cygtls.locals.cw_timer if needed.
Use NT waitable timers for handling timeout.  Return remaining time
to timeout argument if timeout was relative.
(pthread_cond::wait): Change timeout argument to PLARGE_INTEGER.
Adjust to change in cancelable_wait.
(pthread_mutex::lock): Adjust to change in cancelable_wait.
(pthread_spinlock::lock): Ditto.
(pthread::join): Ditto.
(__pthread_cond_dowait): Change waitlength argument to PLARGE_INTEGER.
Adjust to changes in cancelable_wait and pthread_cond::wait.
(pthread_cond_timedwait): Adjust to change in __pthread_cond_dowait.
(pthread_cond_wait): Ditto.
(semaphore::_timedwait): Adjust to change in cancelable_wait.
(semaphore::_wait): Ditto.
* exceptions.cc (handle_sigsuspend): Ditto.
* signal.cc (nanosleep): Ditto.
* wait.cc (wait4): Ditto. Fix copyright dates.
* times.cc (FACTOR, NSPERSEC): Move from here...
* hires.h (FACTOR, NSPERSEC): ...to here.
This commit is contained in:
Yaakov Selkowitz 2011-08-03 16:40:48 +00:00
parent 529aa781b6
commit f0968c1e7e
12 changed files with 197 additions and 139 deletions

View File

@ -1,3 +1,38 @@
2011-08-03 Yaakov Selkowitz <yselkowitz@users.sourceforge.net>
* cygtls.h (struct _local_storage): Add cw_timer member.
* cygtls.cc (_cygtls::init_thread): Initialize locals.cw_timer.
(_cygtls::fixup_after_fork): Ditto.
* tlsoffsets.h: Regenerate.
* ntdll.h (enum _TIMER_INFORMATION_CLASS): Define.
(struct _TIMER_BASIC_INFORMATION): Define.
(NtQueryTimer): Declare function.
* thread.h (cancelable_wait): Change timeout argument to
PLARGE_INTEGER and provide NULL default.
(fast_mutex::lock): Adjust accordingly.
(pthread_cond::wait): Change timeout argument to PLARGE_INTEGER
and default to NULL.
* thread.cc (cancelable_wait): Change timeout argument to
PLARGE_INTEGER. Initialize _cygtls.locals.cw_timer if needed.
Use NT waitable timers for handling timeout. Return remaining time
to timeout argument if timeout was relative.
(pthread_cond::wait): Change timeout argument to PLARGE_INTEGER.
Adjust to change in cancelable_wait.
(pthread_mutex::lock): Adjust to change in cancelable_wait.
(pthread_spinlock::lock): Ditto.
(pthread::join): Ditto.
(__pthread_cond_dowait): Change waitlength argument to PLARGE_INTEGER.
Adjust to changes in cancelable_wait and pthread_cond::wait.
(pthread_cond_timedwait): Adjust to change in __pthread_cond_dowait.
(pthread_cond_wait): Ditto.
(semaphore::_timedwait): Adjust to change in cancelable_wait.
(semaphore::_wait): Ditto.
* exceptions.cc (handle_sigsuspend): Ditto.
* signal.cc (nanosleep): Ditto.
* wait.cc (wait4): Ditto. Fix copyright dates.
* times.cc (FACTOR, NSPERSEC): Move from here...
* hires.h (FACTOR, NSPERSEC): ...to here.
2011-08-01 Corinna Vinschen <corinna@vinschen.de> 2011-08-01 Corinna Vinschen <corinna@vinschen.de>
* syscalls.cc (faccessat): Fix parens in flag expression when calling * syscalls.cc (faccessat): Fix parens in flag expression when calling

View File

@ -98,6 +98,7 @@ _cygtls::init_thread (void *x, DWORD (*func) (void *, void *))
thread_id = GetCurrentThreadId (); thread_id = GetCurrentThreadId ();
initialized = CYGTLS_INITIALIZED; initialized = CYGTLS_INITIALIZED;
errno_addr = &(local_clib._errno); errno_addr = &(local_clib._errno);
locals.cw_timer = NULL;
if ((void *) func == (void *) cygthread::stub if ((void *) func == (void *) cygthread::stub
|| (void *) func == (void *) cygthread::simplestub) || (void *) func == (void *) cygthread::simplestub)
@ -127,6 +128,7 @@ _cygtls::fixup_after_fork ()
} }
stacklock = spinning = 0; stacklock = spinning = 0;
locals.select.sockevt = NULL; locals.select.sockevt = NULL;
locals.cw_timer = NULL;
wq.thread_ev = NULL; wq.thread_ev = NULL;
} }

View File

@ -131,6 +131,9 @@ struct _local_storage
int setmode_file; int setmode_file;
int setmode_mode; int setmode_mode;
/* thread.cc */
HANDLE cw_timer;
/* All functions requiring temporary path buffers. */ /* All functions requiring temporary path buffers. */
tls_pathbuf pathbufs; tls_pathbuf pathbufs;
char ttybuf[32]; char ttybuf[32];

View File

@ -719,7 +719,7 @@ handle_sigsuspend (sigset_t tempmask)
sigproc_printf ("oldmask %p, newmask %p", oldmask, tempmask); sigproc_printf ("oldmask %p, newmask %p", oldmask, tempmask);
pthread_testcancel (); pthread_testcancel ();
cancelable_wait (signal_arrived, INFINITE); cancelable_wait (signal_arrived);
set_sig_errno (EINTR); // Per POSIX set_sig_errno (EINTR); // Per POSIX

View File

@ -29,6 +29,11 @@ details. */
and rounding won't exceed HIRES_DELAY_MAX */ and rounding won't exceed HIRES_DELAY_MAX */
#define HIRES_DELAY_MAX ((((UINT_MAX - 10000) / 1000) * 1000) + 10) #define HIRES_DELAY_MAX ((((UINT_MAX - 10000) / 1000) * 1000) + 10)
/* 100ns difference between Windows and UNIX timebase. */
#define FACTOR (0x19db1ded53e8000LL)
/* # of 100ns intervals per second. */
#define NSPERSEC 10000000LL
class hires_base class hires_base
{ {
protected: protected:

View File

@ -986,6 +986,15 @@ typedef struct _THREAD_BASIC_INFORMATION {
KPRIORITY BasePriority; KPRIORITY BasePriority;
} THREAD_BASIC_INFORMATION, *PTHREAD_BASIC_INFORMATION; } THREAD_BASIC_INFORMATION, *PTHREAD_BASIC_INFORMATION;
typedef enum _TIMER_INFORMATION_CLASS {
TimerBasicInformation = 0
} TIMER_INFORMATION_CLASS, *PTIMER_INFORMATION_CLASS;
typedef struct _TIMER_BASIC_INFORMATION {
LARGE_INTEGER TimeRemaining;
BOOLEAN SignalState;
} TIMER_BASIC_INFORMATION, *PTIMER_BASIC_INFORMATION;
#define RTL_QUERY_REGISTRY_SUBKEY 0x01 #define RTL_QUERY_REGISTRY_SUBKEY 0x01
#define RTL_QUERY_REGISTRY_TOPKEY 0x02 #define RTL_QUERY_REGISTRY_TOPKEY 0x02
#define RTL_QUERY_REGISTRY_REQUIRED 0x04 #define RTL_QUERY_REGISTRY_REQUIRED 0x04
@ -1155,6 +1164,8 @@ extern "C"
NTSTATUS NTAPI NtQuerySecurityObject (HANDLE, SECURITY_INFORMATION, NTSTATUS NTAPI NtQuerySecurityObject (HANDLE, SECURITY_INFORMATION,
PSECURITY_DESCRIPTOR, ULONG, PULONG); PSECURITY_DESCRIPTOR, ULONG, PULONG);
NTSTATUS NTAPI NtQuerySymbolicLinkObject (HANDLE, PUNICODE_STRING, PULONG); NTSTATUS NTAPI NtQuerySymbolicLinkObject (HANDLE, PUNICODE_STRING, PULONG);
NTSTATUS NTAPI NtQueryTimer (HANDLE, TIMER_INFORMATION_CLASS, PVOID,
ULONG, PULONG);
NTSTATUS NTAPI NtQueryTimerResolution (PULONG, PULONG, PULONG); NTSTATUS NTAPI NtQueryTimerResolution (PULONG, PULONG, PULONG);
NTSTATUS NTAPI NtQueryValueKey (HANDLE, PUNICODE_STRING, NTSTATUS NTAPI NtQueryValueKey (HANDLE, PUNICODE_STRING,
KEY_VALUE_INFORMATION_CLASS, PVOID, ULONG, KEY_VALUE_INFORMATION_CLASS, PVOID, ULONG,

View File

@ -92,61 +92,31 @@ nanosleep (const struct timespec *rqtp, struct timespec *rmtp)
set_errno (EINVAL); set_errno (EINVAL);
return -1; return -1;
} }
unsigned int sec = rqtp->tv_sec; LARGE_INTEGER timeout;
DWORD resolution = gtod.resolution ();
bool done = false;
DWORD req;
DWORD rem;
while (!done) timeout.QuadPart = (LONGLONG) rqtp->tv_sec * NSPERSEC
+ ((LONGLONG) rqtp->tv_nsec + 99LL) / 100LL;
timeout.QuadPart *= -1LL;
syscall_printf ("nanosleep (%ld.%09ld)", rqtp->tv_sec, rqtp->tv_nsec);
int rc = cancelable_wait (signal_arrived, &timeout);
if (rc == WAIT_OBJECT_0)
{ {
/* Divide user's input into transactions no larger than 49.7 _my_tls.call_signal_handler ();
days at a time. */ set_errno (EINTR);
if (sec > HIRES_DELAY_MAX / 1000) res = -1;
{
req = ((HIRES_DELAY_MAX + resolution - 1)
/ resolution * resolution);
sec -= HIRES_DELAY_MAX / 1000;
}
else
{
req = ((sec * 1000 + (rqtp->tv_nsec + 999999) / 1000000
+ resolution - 1) / resolution) * resolution;
sec = 0;
done = true;
}
DWORD end_time = gtod.dmsecs () + req;
syscall_printf ("nanosleep (%ld)", req);
int rc = cancelable_wait (signal_arrived, req);
if ((rem = end_time - gtod.dmsecs ()) > HIRES_DELAY_MAX)
rem = 0;
if (rc == WAIT_OBJECT_0)
{
_my_tls.call_signal_handler ();
set_errno (EINTR);
res = -1;
break;
}
} }
if (rmtp) if (rmtp)
{ {
rmtp->tv_sec = sec + rem / 1000; rmtp->tv_sec = (time_t) (timeout.QuadPart / NSPERSEC);
rmtp->tv_nsec = (rem % 1000) * 1000000; rmtp->tv_nsec = (long) ((timeout.QuadPart % NSPERSEC) * 100LL);
if (sec)
{
rmtp->tv_nsec += rqtp->tv_nsec;
if (rmtp->tv_nsec >= 1000000000)
{
rmtp->tv_nsec -= 1000000000;
rmtp->tv_sec++;
}
}
} }
syscall_printf ("%d = nanosleep (%ld, %ld)", res, req, rem); syscall_printf ("%d = nanosleep (%ld.%09ld, %ld.%09.ld)", res, rqtp->tv_sec,
rqtp->tv_nsec, rmtp ? rmtp->tv_sec : 0,
rmtp ? rmtp->tv_nsec : 0);
return res; return res;
} }

View File

@ -906,13 +906,13 @@ pthread::static_cancel_self ()
} }
DWORD DWORD
cancelable_wait (HANDLE object, DWORD timeout, cancelable_wait (HANDLE object, PLARGE_INTEGER timeout,
const cw_cancel_action cancel_action, const cw_cancel_action cancel_action,
const enum cw_sig_wait sig_wait) const enum cw_sig_wait sig_wait)
{ {
DWORD res; DWORD res;
DWORD num = 0; DWORD num = 0;
HANDLE wait_objects[3]; HANDLE wait_objects[4];
pthread_t thread = pthread::self (); pthread_t thread = pthread::self ();
/* Do not change the wait order. /* Do not change the wait order.
@ -939,15 +939,30 @@ cancelable_wait (HANDLE object, DWORD timeout,
wait_objects[sig_n] = signal_arrived; wait_objects[sig_n] = signal_arrived;
} }
DWORD timeout_n;
if (!timeout)
timeout_n = WAIT_TIMEOUT + 1;
else
{
timeout_n = WAIT_OBJECT_0 + num++;
if (!_my_tls.locals.cw_timer)
NtCreateTimer (&_my_tls.locals.cw_timer, TIMER_ALL_ACCESS, NULL,
NotificationTimer);
NtSetTimer (_my_tls.locals.cw_timer, timeout, NULL, NULL, FALSE, 0, NULL);
wait_objects[timeout_n] = _my_tls.locals.cw_timer;
}
while (1) while (1)
{ {
res = WaitForMultipleObjects (num, wait_objects, FALSE, timeout); res = WaitForMultipleObjects (num, wait_objects, FALSE, INFINITE);
if (res == cancel_n) if (res == cancel_n)
{ {
if (cancel_action == cw_cancel_self) if (cancel_action == cw_cancel_self)
pthread::static_cancel_self (); pthread::static_cancel_self ();
res = WAIT_CANCELED; res = WAIT_CANCELED;
} }
else if (res == timeout_n)
res = WAIT_TIMEOUT;
else if (res != sig_n) else if (res != sig_n)
/* all set */; /* all set */;
else if (sig_wait == cw_sig_eintr) else if (sig_wait == cw_sig_eintr)
@ -959,6 +974,21 @@ cancelable_wait (HANDLE object, DWORD timeout,
} }
break; break;
} }
if (timeout)
{
const size_t sizeof_tbi = sizeof (TIMER_BASIC_INFORMATION);
PTIMER_BASIC_INFORMATION tbi = (PTIMER_BASIC_INFORMATION) malloc (sizeof_tbi);
NtQueryTimer (_my_tls.locals.cw_timer, TimerBasicInformation, tbi,
sizeof_tbi, NULL);
/* if timer expired, TimeRemaining is negative and represents the
system uptime when signalled */
if (timeout->QuadPart < 0LL)
timeout->QuadPart = tbi->SignalState ? 0LL : tbi->TimeRemaining.QuadPart;
NtCancelTimer (_my_tls.locals.cw_timer, NULL);
}
return res; return res;
} }
@ -1228,7 +1258,7 @@ pthread_cond::unblock (const bool all)
} }
int int
pthread_cond::wait (pthread_mutex_t mutex, DWORD dwMilliseconds) pthread_cond::wait (pthread_mutex_t mutex, PLARGE_INTEGER timeout)
{ {
DWORD rv; DWORD rv;
@ -1249,7 +1279,7 @@ pthread_cond::wait (pthread_mutex_t mutex, DWORD dwMilliseconds)
++mutex->condwaits; ++mutex->condwaits;
mutex->unlock (); mutex->unlock ();
rv = cancelable_wait (sem_wait, dwMilliseconds, cw_no_cancel_self, cw_sig_eintr); rv = cancelable_wait (sem_wait, timeout, cw_no_cancel_self, cw_sig_eintr);
mtx_out.lock (); mtx_out.lock ();
@ -1764,7 +1794,7 @@ pthread_mutex::lock ()
else if (type == PTHREAD_MUTEX_NORMAL /* potentially causes deadlock */ else if (type == PTHREAD_MUTEX_NORMAL /* potentially causes deadlock */
|| !pthread::equal (owner, self)) || !pthread::equal (owner, self))
{ {
cancelable_wait (win32_obj_id, INFINITE, cw_no_cancel, cw_sig_resume); cancelable_wait (win32_obj_id, NULL, cw_no_cancel, cw_sig_resume);
set_owner (self); set_owner (self);
} }
else else
@ -1899,8 +1929,13 @@ pthread_spinlock::lock ()
} }
else if (pthread::equal (owner, self)) else if (pthread::equal (owner, self))
result = EDEADLK; result = EDEADLK;
else /* Minimal timeout to minimize CPU usage while still spinning. */ else
cancelable_wait (win32_obj_id, 1L, cw_no_cancel, cw_sig_resume); {
/* Minimal timeout to minimize CPU usage while still spinning. */
LARGE_INTEGER timeout;
timeout.QuadPart = -10000LL;
cancelable_wait (win32_obj_id, &timeout, cw_no_cancel, cw_sig_resume);
}
} }
while (result == -1); while (result == -1);
pthread_printf ("spinlock %p, self %p, owner %p", this, self, owner); pthread_printf ("spinlock %p, self %p, owner %p", this, self, owner);
@ -2377,7 +2412,7 @@ pthread::join (pthread_t *thread, void **return_val)
(*thread)->attr.joinable = PTHREAD_CREATE_DETACHED; (*thread)->attr.joinable = PTHREAD_CREATE_DETACHED;
(*thread)->mutex.unlock (); (*thread)->mutex.unlock ();
switch (cancelable_wait ((*thread)->win32_obj_id, INFINITE, cw_no_cancel_self, cw_sig_resume)) switch (cancelable_wait ((*thread)->win32_obj_id, NULL, cw_no_cancel_self, cw_sig_resume))
{ {
case WAIT_OBJECT_0: case WAIT_OBJECT_0:
if (return_val) if (return_val)
@ -2702,7 +2737,7 @@ pthread_cond_signal (pthread_cond_t *cond)
static int static int
__pthread_cond_dowait (pthread_cond_t *cond, pthread_mutex_t *mutex, __pthread_cond_dowait (pthread_cond_t *cond, pthread_mutex_t *mutex,
DWORD waitlength) PLARGE_INTEGER waitlength)
{ {
if (!pthread_mutex::is_good_object (mutex)) if (!pthread_mutex::is_good_object (mutex))
return EINVAL; return EINVAL;
@ -2722,7 +2757,7 @@ pthread_cond_timedwait (pthread_cond_t *cond, pthread_mutex_t *mutex,
const struct timespec *abstime) const struct timespec *abstime)
{ {
struct timespec tp; struct timespec tp;
DWORD waitlength; LARGE_INTEGER timeout;
myfault efault; myfault efault;
if (efault.faulted ()) if (efault.faulted ())
@ -2738,17 +2773,27 @@ pthread_cond_timedwait (pthread_cond_t *cond, pthread_mutex_t *mutex,
clock_gettime ((*cond)->clock_id, &tp); clock_gettime ((*cond)->clock_id, &tp);
/* Check for immediate timeout before converting to microseconds, since /* Check for immediate timeout before converting */
the resulting value can easily overflow long. This also allows to
evaluate microseconds directly in DWORD. */
if (tp.tv_sec > abstime->tv_sec if (tp.tv_sec > abstime->tv_sec
|| (tp.tv_sec == abstime->tv_sec || (tp.tv_sec == abstime->tv_sec
&& tp.tv_nsec > abstime->tv_nsec)) && tp.tv_nsec > abstime->tv_nsec))
return ETIMEDOUT; return ETIMEDOUT;
waitlength = (abstime->tv_sec - tp.tv_sec) * 1000; timeout.QuadPart = abstime->tv_sec * NSPERSEC
waitlength += (abstime->tv_nsec - tp.tv_nsec) / 1000000; + (abstime->tv_nsec + 99LL) / 100LL;
return __pthread_cond_dowait (cond, mutex, waitlength);
switch ((*cond)->clock_id)
{
case CLOCK_REALTIME:
timeout.QuadPart += FACTOR;
break;
default:
/* other clocks must be handled as relative timeout */
timeout.QuadPart -= tp.tv_sec * NSPERSEC + tp.tv_nsec / 100LL;
timeout.QuadPart *= -1LL;
break;
}
return __pthread_cond_dowait (cond, mutex, &timeout);
} }
extern "C" int extern "C" int
@ -2756,7 +2801,7 @@ pthread_cond_wait (pthread_cond_t *cond, pthread_mutex_t *mutex)
{ {
pthread_testcancel (); pthread_testcancel ();
return __pthread_cond_dowait (cond, mutex, INFINITE); return __pthread_cond_dowait (cond, mutex, NULL);
} }
extern "C" int extern "C" int
@ -3439,8 +3484,7 @@ semaphore::_trywait ()
int int
semaphore::_timedwait (const struct timespec *abstime) semaphore::_timedwait (const struct timespec *abstime)
{ {
struct timeval tv; LARGE_INTEGER timeout;
long waitlength;
myfault efault; myfault efault;
if (efault.faulted ()) if (efault.faulted ())
@ -3453,12 +3497,10 @@ semaphore::_timedwait (const struct timespec *abstime)
return -1; return -1;
} }
gettimeofday (&tv, NULL); timeout.QuadPart = abstime->tv_sec * NSPERSEC
waitlength = abstime->tv_sec * 1000 + abstime->tv_nsec / (1000 * 1000); + (abstime->tv_nsec + 99) / 100 + FACTOR;
waitlength -= tv.tv_sec * 1000 + tv.tv_usec / 1000;
if (waitlength < 0) switch (cancelable_wait (win32_obj_id, &timeout, cw_cancel_self, cw_sig_eintr))
waitlength = 0;
switch (cancelable_wait (win32_obj_id, waitlength, cw_cancel_self, cw_sig_eintr))
{ {
case WAIT_OBJECT_0: case WAIT_OBJECT_0:
currentvalue--; currentvalue--;
@ -3480,7 +3522,7 @@ semaphore::_timedwait (const struct timespec *abstime)
int int
semaphore::_wait () semaphore::_wait ()
{ {
switch (cancelable_wait (win32_obj_id, INFINITE, cw_cancel_self, cw_sig_eintr)) switch (cancelable_wait (win32_obj_id, NULL, cw_cancel_self, cw_sig_eintr))
{ {
case WAIT_OBJECT_0: case WAIT_OBJECT_0:
currentvalue--; currentvalue--;

View File

@ -37,7 +37,8 @@ enum cw_cancel_action
cw_no_cancel cw_no_cancel
}; };
DWORD cancelable_wait (HANDLE, DWORD, const cw_cancel_action = cw_cancel_self, DWORD cancelable_wait (HANDLE, PLARGE_INTEGER timeout = NULL,
const cw_cancel_action = cw_cancel_self,
const enum cw_sig_wait = cw_sig_nosig) const enum cw_sig_wait = cw_sig_nosig)
__attribute__ ((regparm (3))); __attribute__ ((regparm (3)));
@ -70,7 +71,7 @@ public:
void lock () void lock ()
{ {
if (InterlockedIncrement ((long *) &lock_counter) != 1) if (InterlockedIncrement ((long *) &lock_counter) != 1)
cancelable_wait (win32_obj_id, INFINITE, cw_no_cancel, cw_sig_resume); cancelable_wait (win32_obj_id, NULL, cw_no_cancel, cw_sig_resume);
} }
void unlock () void unlock ()
@ -517,7 +518,7 @@ public:
pthread_mutex_t mtx_cond; pthread_mutex_t mtx_cond;
void unblock (const bool all); void unblock (const bool all);
int wait (pthread_mutex_t mutex, DWORD dwMilliseconds = INFINITE); int wait (pthread_mutex_t mutex, PLARGE_INTEGER timeout = NULL);
pthread_cond (pthread_condattr *); pthread_cond (pthread_condattr *);
~pthread_cond (); ~pthread_cond ();

View File

@ -27,10 +27,6 @@ details. */
#include "cygtls.h" #include "cygtls.h"
#include "ntdll.h" #include "ntdll.h"
/* 100ns difference between WIndows and UNIX timebase. */
#define FACTOR (0x19db1ded53e8000LL)
/* # of 100ns intervals per second. */
#define NSPERSEC 10000000LL
/* Max allowed diversion in 100ns of internal timer from system time. If /* Max allowed diversion in 100ns of internal timer from system time. If
this difference is exceeded, the internal timer gets re-primed. */ this difference is exceeded, the internal timer gets re-primed. */
#define JITTER (40 * 10000LL) #define JITTER (40 * 10000LL)
@ -737,7 +733,7 @@ hires_ms::resolution ()
status = NtQueryTimerResolution (&coarsest, &finest, &actual); status = NtQueryTimerResolution (&coarsest, &finest, &actual);
if (NT_SUCCESS (status)) if (NT_SUCCESS (status))
minperiod = (DWORD) actual / 10000L; minperiod = (DWORD) actual;
else else
{ {
/* Try to empirically determine current timer resolution */ /* Try to empirically determine current timer resolution */
@ -757,13 +753,9 @@ hires_ms::resolution ()
period += now - then; period += now - then;
} }
SetThreadPriority (GetCurrentThread (), priority); SetThreadPriority (GetCurrentThread (), priority);
period /= 40000L; period /= 4L;
minperiod = (DWORD) period; minperiod = (DWORD) period;
} }
/* The resolution can be as low as 5000 100ns intervals on recent OSes.
We have to make sure that the resolution in ms is never 0. */
if (!minperiod)
minperiod = 1L;
} }
return minperiod; return minperiod;
} }
@ -786,8 +778,8 @@ clock_getres (clockid_t clk_id, struct timespec *tp)
case CLOCK_REALTIME: case CLOCK_REALTIME:
{ {
DWORD period = gtod.resolution (); DWORD period = gtod.resolution ();
tp->tv_sec = period / 1000; tp->tv_sec = period / NSPERSEC;
tp->tv_nsec = (period % 1000) * 1000000; tp->tv_nsec = (period % NSPERSEC) * 100;
break; break;
} }
@ -838,7 +830,7 @@ clock_setres (clockid_t clk_id, struct timespec *tp)
} }
if (period_set if (period_set
&& NT_SUCCESS (NtSetTimerResolution (minperiod * 10000L, FALSE, &actual))) && NT_SUCCESS (NtSetTimerResolution (minperiod, FALSE, &actual)))
period_set = false; period_set = false;
status = NtSetTimerResolution (period, TRUE, &actual); status = NtSetTimerResolution (period, TRUE, &actual);
@ -847,11 +839,7 @@ clock_setres (clockid_t clk_id, struct timespec *tp)
__seterrno_from_nt_status (status); __seterrno_from_nt_status (status);
return -1; return -1;
} }
minperiod = actual / 10000L; minperiod = actual;
/* The resolution can be as low as 5000 100ns intervals on recent OSes.
We have to make sure that the resolution in ms is never 0. */
if (!minperiod)
minperiod = 1L;
period_set = true; period_set = true;
return 0; return 0;
} }

View File

@ -1,6 +1,6 @@
//;# autogenerated: Do not edit. //;# autogenerated: Do not edit.
//; $tls::sizeof__cygtls = 4044; //; $tls::sizeof__cygtls = 4048;
//; $tls::func = -12700; //; $tls::func = -12700;
//; $tls::pfunc = 0; //; $tls::pfunc = 0;
//; $tls::saved_errno = -12696; //; $tls::saved_errno = -12696;
@ -37,26 +37,26 @@
//; $tls::p__dontuse = 412; //; $tls::p__dontuse = 412;
//; $tls::locals = -11200; //; $tls::locals = -11200;
//; $tls::plocals = 1500; //; $tls::plocals = 1500;
//; $tls::_ctinfo = -9740; //; $tls::_ctinfo = -9736;
//; $tls::p_ctinfo = 2960; //; $tls::p_ctinfo = 2964;
//; $tls::andreas = -9736; //; $tls::andreas = -9732;
//; $tls::pandreas = 2964; //; $tls::pandreas = 2968;
//; $tls::wq = -9732; //; $tls::wq = -9728;
//; $tls::pwq = 2968; //; $tls::pwq = 2972;
//; $tls::sig = -9704; //; $tls::sig = -9700;
//; $tls::psig = 2996; //; $tls::psig = 3000;
//; $tls::incyg = -9700; //; $tls::incyg = -9696;
//; $tls::pincyg = 3000; //; $tls::pincyg = 3004;
//; $tls::spinning = -9696; //; $tls::spinning = -9692;
//; $tls::pspinning = 3004; //; $tls::pspinning = 3008;
//; $tls::stacklock = -9692; //; $tls::stacklock = -9688;
//; $tls::pstacklock = 3008; //; $tls::pstacklock = 3012;
//; $tls::stackptr = -9688; //; $tls::stackptr = -9684;
//; $tls::pstackptr = 3012; //; $tls::pstackptr = 3016;
//; $tls::stack = -9684; //; $tls::stack = -9680;
//; $tls::pstack = 3016; //; $tls::pstack = 3020;
//; $tls::initialized = -8660; //; $tls::initialized = -8656;
//; $tls::pinitialized = 4040; //; $tls::pinitialized = 4044;
//; __DATA__ //; __DATA__
#define tls_func (-12700) #define tls_func (-12700)
@ -95,23 +95,23 @@
#define tls_p__dontuse (412) #define tls_p__dontuse (412)
#define tls_locals (-11200) #define tls_locals (-11200)
#define tls_plocals (1500) #define tls_plocals (1500)
#define tls__ctinfo (-9740) #define tls__ctinfo (-9736)
#define tls_p_ctinfo (2960) #define tls_p_ctinfo (2964)
#define tls_andreas (-9736) #define tls_andreas (-9732)
#define tls_pandreas (2964) #define tls_pandreas (2968)
#define tls_wq (-9732) #define tls_wq (-9728)
#define tls_pwq (2968) #define tls_pwq (2972)
#define tls_sig (-9704) #define tls_sig (-9700)
#define tls_psig (2996) #define tls_psig (3000)
#define tls_incyg (-9700) #define tls_incyg (-9696)
#define tls_pincyg (3000) #define tls_pincyg (3004)
#define tls_spinning (-9696) #define tls_spinning (-9692)
#define tls_pspinning (3004) #define tls_pspinning (3008)
#define tls_stacklock (-9692) #define tls_stacklock (-9688)
#define tls_pstacklock (3008) #define tls_pstacklock (3012)
#define tls_stackptr (-9688) #define tls_stackptr (-9684)
#define tls_pstackptr (3012) #define tls_pstackptr (3016)
#define tls_stack (-9684) #define tls_stack (-9680)
#define tls_pstack (3016) #define tls_pstack (3020)
#define tls_initialized (-8660) #define tls_initialized (-8656)
#define tls_pinitialized (4040) #define tls_pinitialized (4044)

View File

@ -1,6 +1,7 @@
/* wait.cc: Posix wait routines. /* wait.cc: Posix wait routines.
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 Red Hat, Inc. Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
2005, 2009, 2011 Red Hat, Inc.
This file is part of Cygwin. This file is part of Cygwin.
@ -78,7 +79,7 @@ wait4 (int intpid, int *status, int options, struct rusage *r)
if ((waitfor = w->ev) == NULL) if ((waitfor = w->ev) == NULL)
goto nochildren; goto nochildren;
res = cancelable_wait (waitfor, INFINITE); res = cancelable_wait (waitfor);
sigproc_printf ("%d = WaitForSingleObject (...)", res); sigproc_printf ("%d = WaitForSingleObject (...)", res);