* 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:
		| @@ -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> | ||||
|  | ||||
| 	* syscalls.cc (faccessat): Fix parens in flag expression when calling | ||||
|   | ||||
| @@ -98,6 +98,7 @@ _cygtls::init_thread (void *x, DWORD (*func) (void *, void *)) | ||||
|   thread_id = GetCurrentThreadId (); | ||||
|   initialized = CYGTLS_INITIALIZED; | ||||
|   errno_addr = &(local_clib._errno); | ||||
|   locals.cw_timer = NULL; | ||||
|  | ||||
|   if ((void *) func == (void *) cygthread::stub | ||||
|       || (void *) func == (void *) cygthread::simplestub) | ||||
| @@ -127,6 +128,7 @@ _cygtls::fixup_after_fork () | ||||
|     } | ||||
|   stacklock = spinning = 0; | ||||
|   locals.select.sockevt = NULL; | ||||
|   locals.cw_timer = NULL; | ||||
|   wq.thread_ev = NULL; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -131,6 +131,9 @@ struct _local_storage | ||||
|   int setmode_file; | ||||
|   int setmode_mode; | ||||
|  | ||||
|   /* thread.cc */ | ||||
|   HANDLE cw_timer; | ||||
|  | ||||
|   /* All functions requiring temporary path buffers. */ | ||||
|   tls_pathbuf pathbufs; | ||||
|   char ttybuf[32]; | ||||
|   | ||||
| @@ -719,7 +719,7 @@ handle_sigsuspend (sigset_t tempmask) | ||||
|   sigproc_printf ("oldmask %p, newmask %p", oldmask, tempmask); | ||||
|  | ||||
|   pthread_testcancel (); | ||||
|   cancelable_wait (signal_arrived, INFINITE); | ||||
|   cancelable_wait (signal_arrived); | ||||
|  | ||||
|   set_sig_errno (EINTR);	// Per POSIX | ||||
|  | ||||
|   | ||||
| @@ -29,6 +29,11 @@ details. */ | ||||
|    and rounding won't exceed HIRES_DELAY_MAX */ | ||||
| #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 | ||||
| { | ||||
|  protected: | ||||
|   | ||||
| @@ -986,6 +986,15 @@ typedef struct _THREAD_BASIC_INFORMATION { | ||||
|     KPRIORITY  BasePriority; | ||||
| } 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_TOPKEY 0x02 | ||||
| #define RTL_QUERY_REGISTRY_REQUIRED 0x04 | ||||
| @@ -1155,6 +1164,8 @@ extern "C" | ||||
|   NTSTATUS NTAPI NtQuerySecurityObject (HANDLE, SECURITY_INFORMATION, | ||||
| 					PSECURITY_DESCRIPTOR, ULONG, 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 NtQueryValueKey (HANDLE, PUNICODE_STRING, | ||||
| 				  KEY_VALUE_INFORMATION_CLASS, PVOID, ULONG, | ||||
|   | ||||
| @@ -92,61 +92,31 @@ nanosleep (const struct timespec *rqtp, struct timespec *rmtp) | ||||
|       set_errno (EINVAL); | ||||
|       return -1; | ||||
|     } | ||||
|   unsigned int sec = rqtp->tv_sec; | ||||
|   DWORD resolution = gtod.resolution (); | ||||
|   bool done = false; | ||||
|   DWORD req; | ||||
|   DWORD rem; | ||||
|   LARGE_INTEGER timeout; | ||||
|  | ||||
|   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 | ||||
| 	 days at a time.  */ | ||||
|       if (sec > HIRES_DELAY_MAX / 1000) | ||||
| 	{ | ||||
| 	  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; | ||||
| 	} | ||||
|       _my_tls.call_signal_handler (); | ||||
|       set_errno (EINTR); | ||||
|       res = -1; | ||||
|     } | ||||
|  | ||||
|   if (rmtp) | ||||
|     { | ||||
|       rmtp->tv_sec = sec + rem / 1000; | ||||
|       rmtp->tv_nsec = (rem % 1000) * 1000000; | ||||
|       if (sec) | ||||
| 	{ | ||||
| 	  rmtp->tv_nsec += rqtp->tv_nsec; | ||||
| 	  if (rmtp->tv_nsec >= 1000000000) | ||||
| 	    { | ||||
| 	      rmtp->tv_nsec -= 1000000000; | ||||
| 	      rmtp->tv_sec++; | ||||
| 	    } | ||||
| 	} | ||||
|       rmtp->tv_sec = (time_t) (timeout.QuadPart / NSPERSEC); | ||||
|       rmtp->tv_nsec = (long) ((timeout.QuadPart % NSPERSEC) * 100LL); | ||||
|     } | ||||
|  | ||||
|   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; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -906,13 +906,13 @@ pthread::static_cancel_self () | ||||
| } | ||||
|  | ||||
| DWORD | ||||
| cancelable_wait (HANDLE object, DWORD timeout, | ||||
| cancelable_wait (HANDLE object, PLARGE_INTEGER timeout, | ||||
| 		 const cw_cancel_action cancel_action, | ||||
| 		 const enum cw_sig_wait sig_wait) | ||||
| { | ||||
|   DWORD res; | ||||
|   DWORD num = 0; | ||||
|   HANDLE wait_objects[3]; | ||||
|   HANDLE wait_objects[4]; | ||||
|   pthread_t thread = pthread::self (); | ||||
|  | ||||
|   /* Do not change the wait order. | ||||
| @@ -939,15 +939,30 @@ cancelable_wait (HANDLE object, DWORD timeout, | ||||
|       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) | ||||
|     { | ||||
|       res = WaitForMultipleObjects (num, wait_objects, FALSE, timeout); | ||||
|       res = WaitForMultipleObjects (num, wait_objects, FALSE, INFINITE); | ||||
|       if (res == cancel_n) | ||||
| 	{ | ||||
| 	  if (cancel_action == cw_cancel_self) | ||||
| 	    pthread::static_cancel_self (); | ||||
| 	  res = WAIT_CANCELED; | ||||
| 	} | ||||
|       else if (res == timeout_n) | ||||
| 	res = WAIT_TIMEOUT; | ||||
|       else if (res != sig_n) | ||||
| 	/* all set */; | ||||
|       else if (sig_wait == cw_sig_eintr) | ||||
| @@ -959,6 +974,21 @@ cancelable_wait (HANDLE object, DWORD timeout, | ||||
| 	} | ||||
|       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; | ||||
| } | ||||
|  | ||||
| @@ -1228,7 +1258,7 @@ pthread_cond::unblock (const bool all) | ||||
| } | ||||
|  | ||||
| int | ||||
| pthread_cond::wait (pthread_mutex_t mutex, DWORD dwMilliseconds) | ||||
| pthread_cond::wait (pthread_mutex_t mutex, PLARGE_INTEGER timeout) | ||||
| { | ||||
|   DWORD rv; | ||||
|  | ||||
| @@ -1249,7 +1279,7 @@ pthread_cond::wait (pthread_mutex_t mutex, DWORD dwMilliseconds) | ||||
|   ++mutex->condwaits; | ||||
|   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 (); | ||||
|  | ||||
| @@ -1764,7 +1794,7 @@ pthread_mutex::lock () | ||||
|   else if (type == PTHREAD_MUTEX_NORMAL /* potentially causes deadlock */ | ||||
| 	   || !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); | ||||
|     } | ||||
|   else | ||||
| @@ -1899,8 +1929,13 @@ pthread_spinlock::lock () | ||||
| 	} | ||||
|       else if (pthread::equal (owner, self)) | ||||
| 	result = EDEADLK; | ||||
|       else /* Minimal timeout to minimize CPU usage while still spinning. */ | ||||
| 	cancelable_wait (win32_obj_id, 1L, cw_no_cancel, cw_sig_resume); | ||||
|       else | ||||
| 	{ | ||||
| 	  /* 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); | ||||
|   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)->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: | ||||
| 	  if (return_val) | ||||
| @@ -2702,7 +2737,7 @@ pthread_cond_signal (pthread_cond_t *cond) | ||||
|  | ||||
| static int | ||||
| __pthread_cond_dowait (pthread_cond_t *cond, pthread_mutex_t *mutex, | ||||
| 		       DWORD waitlength) | ||||
| 		       PLARGE_INTEGER waitlength) | ||||
| { | ||||
|   if (!pthread_mutex::is_good_object (mutex)) | ||||
|     return EINVAL; | ||||
| @@ -2722,7 +2757,7 @@ pthread_cond_timedwait (pthread_cond_t *cond, pthread_mutex_t *mutex, | ||||
| 			const struct timespec *abstime) | ||||
| { | ||||
|   struct timespec tp; | ||||
|   DWORD waitlength; | ||||
|   LARGE_INTEGER timeout; | ||||
|  | ||||
|   myfault efault; | ||||
|   if (efault.faulted ()) | ||||
| @@ -2738,17 +2773,27 @@ pthread_cond_timedwait (pthread_cond_t *cond, pthread_mutex_t *mutex, | ||||
|  | ||||
|   clock_gettime ((*cond)->clock_id, &tp); | ||||
|  | ||||
|   /* Check for immediate timeout before converting to microseconds, since | ||||
|      the resulting value can easily overflow long.  This also allows to | ||||
|      evaluate microseconds directly in DWORD. */ | ||||
|   /* Check for immediate timeout before converting */ | ||||
|   if (tp.tv_sec > abstime->tv_sec | ||||
|       || (tp.tv_sec == abstime->tv_sec | ||||
| 	  && tp.tv_nsec > abstime->tv_nsec)) | ||||
|     return ETIMEDOUT; | ||||
|  | ||||
|   waitlength = (abstime->tv_sec - tp.tv_sec) * 1000; | ||||
|   waitlength += (abstime->tv_nsec - tp.tv_nsec) / 1000000; | ||||
|   return __pthread_cond_dowait (cond, mutex, waitlength); | ||||
|   timeout.QuadPart = abstime->tv_sec * NSPERSEC | ||||
| 		      + (abstime->tv_nsec + 99LL) / 100LL; | ||||
|  | ||||
|   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 | ||||
| @@ -2756,7 +2801,7 @@ pthread_cond_wait (pthread_cond_t *cond, pthread_mutex_t *mutex) | ||||
| { | ||||
|   pthread_testcancel (); | ||||
|  | ||||
|   return __pthread_cond_dowait (cond, mutex, INFINITE); | ||||
|   return __pthread_cond_dowait (cond, mutex, NULL); | ||||
| } | ||||
|  | ||||
| extern "C" int | ||||
| @@ -3439,8 +3484,7 @@ semaphore::_trywait () | ||||
| int | ||||
| semaphore::_timedwait (const struct timespec *abstime) | ||||
| { | ||||
|   struct timeval tv; | ||||
|   long waitlength; | ||||
|   LARGE_INTEGER timeout; | ||||
|  | ||||
|   myfault efault; | ||||
|   if (efault.faulted ()) | ||||
| @@ -3453,12 +3497,10 @@ semaphore::_timedwait (const struct timespec *abstime) | ||||
|       return -1; | ||||
|     } | ||||
|  | ||||
|   gettimeofday (&tv, NULL); | ||||
|   waitlength = abstime->tv_sec * 1000 + abstime->tv_nsec / (1000 * 1000); | ||||
|   waitlength -= tv.tv_sec * 1000 + tv.tv_usec / 1000; | ||||
|   if (waitlength < 0) | ||||
|     waitlength = 0; | ||||
|   switch (cancelable_wait (win32_obj_id, waitlength, cw_cancel_self, cw_sig_eintr)) | ||||
|   timeout.QuadPart = abstime->tv_sec * NSPERSEC | ||||
| 		     + (abstime->tv_nsec + 99) / 100 + FACTOR; | ||||
|  | ||||
|   switch (cancelable_wait (win32_obj_id, &timeout, cw_cancel_self, cw_sig_eintr)) | ||||
|     { | ||||
|     case WAIT_OBJECT_0: | ||||
|       currentvalue--; | ||||
| @@ -3480,7 +3522,7 @@ semaphore::_timedwait (const struct timespec *abstime) | ||||
| int | ||||
| 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: | ||||
|       currentvalue--; | ||||
|   | ||||
| @@ -37,7 +37,8 @@ enum cw_cancel_action | ||||
|   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) | ||||
|   __attribute__ ((regparm (3))); | ||||
|  | ||||
| @@ -70,7 +71,7 @@ public: | ||||
|   void lock () | ||||
|   { | ||||
|     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 () | ||||
| @@ -517,7 +518,7 @@ public: | ||||
|   pthread_mutex_t mtx_cond; | ||||
|  | ||||
|   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 (); | ||||
|   | ||||
| @@ -27,10 +27,6 @@ details. */ | ||||
| #include "cygtls.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 | ||||
|    this difference is exceeded, the internal timer gets re-primed. */ | ||||
| #define JITTER (40 * 10000LL) | ||||
| @@ -737,7 +733,7 @@ hires_ms::resolution () | ||||
|  | ||||
|       status = NtQueryTimerResolution (&coarsest, &finest, &actual); | ||||
|       if (NT_SUCCESS (status)) | ||||
| 	minperiod = (DWORD) actual / 10000L; | ||||
| 	minperiod = (DWORD) actual; | ||||
|       else | ||||
| 	{ | ||||
| 	  /* Try to empirically determine current timer resolution */ | ||||
| @@ -757,13 +753,9 @@ hires_ms::resolution () | ||||
| 	      period += now - then; | ||||
| 	    } | ||||
| 	  SetThreadPriority (GetCurrentThread (), priority); | ||||
| 	  period /= 40000L; | ||||
| 	  period /= 4L; | ||||
| 	  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; | ||||
| } | ||||
| @@ -786,8 +778,8 @@ clock_getres (clockid_t clk_id, struct timespec *tp) | ||||
|       case CLOCK_REALTIME: | ||||
| 	{ | ||||
| 	  DWORD period = gtod.resolution (); | ||||
| 	  tp->tv_sec = period / 1000; | ||||
| 	  tp->tv_nsec = (period % 1000) * 1000000; | ||||
| 	  tp->tv_sec = period / NSPERSEC; | ||||
| 	  tp->tv_nsec = (period % NSPERSEC) * 100; | ||||
| 	  break; | ||||
| 	} | ||||
|  | ||||
| @@ -838,7 +830,7 @@ clock_setres (clockid_t clk_id, struct timespec *tp) | ||||
|     } | ||||
|  | ||||
|   if (period_set | ||||
|       && NT_SUCCESS (NtSetTimerResolution (minperiod * 10000L, FALSE, &actual))) | ||||
|       && NT_SUCCESS (NtSetTimerResolution (minperiod, FALSE, &actual))) | ||||
|     period_set = false; | ||||
|  | ||||
|   status = NtSetTimerResolution (period, TRUE, &actual); | ||||
| @@ -847,11 +839,7 @@ clock_setres (clockid_t clk_id, struct timespec *tp) | ||||
|       __seterrno_from_nt_status (status); | ||||
|       return -1; | ||||
|     } | ||||
|   minperiod = actual / 10000L; | ||||
|   /* 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; | ||||
|   minperiod = actual; | ||||
|   period_set = true; | ||||
|   return 0; | ||||
| } | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| //;# autogenerated:  Do not edit. | ||||
|  | ||||
| //; $tls::sizeof__cygtls = 4044; | ||||
| //; $tls::sizeof__cygtls = 4048; | ||||
| //; $tls::func = -12700; | ||||
| //; $tls::pfunc = 0; | ||||
| //; $tls::saved_errno = -12696; | ||||
| @@ -37,26 +37,26 @@ | ||||
| //; $tls::p__dontuse = 412; | ||||
| //; $tls::locals = -11200; | ||||
| //; $tls::plocals = 1500; | ||||
| //; $tls::_ctinfo = -9740; | ||||
| //; $tls::p_ctinfo = 2960; | ||||
| //; $tls::andreas = -9736; | ||||
| //; $tls::pandreas = 2964; | ||||
| //; $tls::wq = -9732; | ||||
| //; $tls::pwq = 2968; | ||||
| //; $tls::sig = -9704; | ||||
| //; $tls::psig = 2996; | ||||
| //; $tls::incyg = -9700; | ||||
| //; $tls::pincyg = 3000; | ||||
| //; $tls::spinning = -9696; | ||||
| //; $tls::pspinning = 3004; | ||||
| //; $tls::stacklock = -9692; | ||||
| //; $tls::pstacklock = 3008; | ||||
| //; $tls::stackptr = -9688; | ||||
| //; $tls::pstackptr = 3012; | ||||
| //; $tls::stack = -9684; | ||||
| //; $tls::pstack = 3016; | ||||
| //; $tls::initialized = -8660; | ||||
| //; $tls::pinitialized = 4040; | ||||
| //; $tls::_ctinfo = -9736; | ||||
| //; $tls::p_ctinfo = 2964; | ||||
| //; $tls::andreas = -9732; | ||||
| //; $tls::pandreas = 2968; | ||||
| //; $tls::wq = -9728; | ||||
| //; $tls::pwq = 2972; | ||||
| //; $tls::sig = -9700; | ||||
| //; $tls::psig = 3000; | ||||
| //; $tls::incyg = -9696; | ||||
| //; $tls::pincyg = 3004; | ||||
| //; $tls::spinning = -9692; | ||||
| //; $tls::pspinning = 3008; | ||||
| //; $tls::stacklock = -9688; | ||||
| //; $tls::pstacklock = 3012; | ||||
| //; $tls::stackptr = -9684; | ||||
| //; $tls::pstackptr = 3016; | ||||
| //; $tls::stack = -9680; | ||||
| //; $tls::pstack = 3020; | ||||
| //; $tls::initialized = -8656; | ||||
| //; $tls::pinitialized = 4044; | ||||
| //; __DATA__ | ||||
|  | ||||
| #define tls_func (-12700) | ||||
| @@ -95,23 +95,23 @@ | ||||
| #define tls_p__dontuse (412) | ||||
| #define tls_locals (-11200) | ||||
| #define tls_plocals (1500) | ||||
| #define tls__ctinfo (-9740) | ||||
| #define tls_p_ctinfo (2960) | ||||
| #define tls_andreas (-9736) | ||||
| #define tls_pandreas (2964) | ||||
| #define tls_wq (-9732) | ||||
| #define tls_pwq (2968) | ||||
| #define tls_sig (-9704) | ||||
| #define tls_psig (2996) | ||||
| #define tls_incyg (-9700) | ||||
| #define tls_pincyg (3000) | ||||
| #define tls_spinning (-9696) | ||||
| #define tls_pspinning (3004) | ||||
| #define tls_stacklock (-9692) | ||||
| #define tls_pstacklock (3008) | ||||
| #define tls_stackptr (-9688) | ||||
| #define tls_pstackptr (3012) | ||||
| #define tls_stack (-9684) | ||||
| #define tls_pstack (3016) | ||||
| #define tls_initialized (-8660) | ||||
| #define tls_pinitialized (4040) | ||||
| #define tls__ctinfo (-9736) | ||||
| #define tls_p_ctinfo (2964) | ||||
| #define tls_andreas (-9732) | ||||
| #define tls_pandreas (2968) | ||||
| #define tls_wq (-9728) | ||||
| #define tls_pwq (2972) | ||||
| #define tls_sig (-9700) | ||||
| #define tls_psig (3000) | ||||
| #define tls_incyg (-9696) | ||||
| #define tls_pincyg (3004) | ||||
| #define tls_spinning (-9692) | ||||
| #define tls_pspinning (3008) | ||||
| #define tls_stacklock (-9688) | ||||
| #define tls_pstacklock (3012) | ||||
| #define tls_stackptr (-9684) | ||||
| #define tls_pstackptr (3016) | ||||
| #define tls_stack (-9680) | ||||
| #define tls_pstack (3020) | ||||
| #define tls_initialized (-8656) | ||||
| #define tls_pinitialized (4044) | ||||
|   | ||||
| @@ -1,6 +1,7 @@ | ||||
| /* 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. | ||||
|  | ||||
| @@ -78,7 +79,7 @@ wait4 (int intpid, int *status, int options, struct rusage *r) | ||||
|       if ((waitfor = w->ev) == NULL) | ||||
| 	goto nochildren; | ||||
|  | ||||
|       res = cancelable_wait (waitfor, INFINITE); | ||||
|       res = cancelable_wait (waitfor); | ||||
|  | ||||
|       sigproc_printf ("%d = WaitForSingleObject (...)", res); | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user