* cygwin.din (clock_nanosleep): Export.
* posix.sgml (std-notimpl): Move clock_nanosleep from here... (std-susv4): ... to here. (std-notes): Note limitations of clock_nanosleep. * signal.cc (clock_nanosleep): Renamed from nanosleep, adding clock_id and flags arguments and changing return values throughout. Improve checks for illegal rqtp values. Add support for CLOCK_MONOTONIC and TIMER_ABSTIME. (nanosleep): Rewrite in terms of clock_nanosleep. (sleep): Ditto. (usleep): Ditto. * thread.cc: Mark clock_nanosleep in list of cancellation points. * include/cygwin/version.h (CYGWIN_VERSION_API_MINOR): Bump.
This commit is contained in:
		| @@ -1,3 +1,19 @@ | |||||||
|  | 2011-08-03  Yaakov Selkowitz  <yselkowitz@users.sourceforge.net> | ||||||
|  |  | ||||||
|  | 	* cygwin.din (clock_nanosleep): Export. | ||||||
|  | 	* posix.sgml (std-notimpl): Move clock_nanosleep from here... | ||||||
|  | 	(std-susv4): ... to here. | ||||||
|  | 	(std-notes): Note limitations of clock_nanosleep. | ||||||
|  | 	* signal.cc (clock_nanosleep): Renamed from nanosleep, adding clock_id | ||||||
|  | 	and flags arguments and changing return values throughout. | ||||||
|  | 	Improve checks for illegal rqtp values.  Add support for | ||||||
|  | 	CLOCK_MONOTONIC and TIMER_ABSTIME. | ||||||
|  | 	(nanosleep): Rewrite in terms of clock_nanosleep. | ||||||
|  | 	(sleep): Ditto. | ||||||
|  | 	(usleep): Ditto. | ||||||
|  | 	* thread.cc: Mark clock_nanosleep in list of cancellation points. | ||||||
|  | 	* include/cygwin/version.h (CYGWIN_VERSION_API_MINOR): Bump. | ||||||
|  |  | ||||||
| 2011-08-03  Christopher Faylor  <me.cygwin2011@cgf.cx> | 2011-08-03  Christopher Faylor  <me.cygwin2011@cgf.cx> | ||||||
|  |  | ||||||
| 	* dll_init.cc: Use fabort in favor of api_fatal and fork_info->abort | 	* dll_init.cc: Use fabort in favor of api_fatal and fork_info->abort | ||||||
|   | |||||||
| @@ -223,6 +223,7 @@ _clock = clock SIGFE | |||||||
| clock_getcpuclockid SIGFE | clock_getcpuclockid SIGFE | ||||||
| clock_getres SIGFE | clock_getres SIGFE | ||||||
| clock_gettime SIGFE | clock_gettime SIGFE | ||||||
|  | clock_nanosleep SIGFE | ||||||
| clock_setres SIGFE | clock_setres SIGFE | ||||||
| clock_settime SIGFE | clock_settime SIGFE | ||||||
| clog NOSIGFE | clog NOSIGFE | ||||||
|   | |||||||
| @@ -418,12 +418,13 @@ details. */ | |||||||
| 	   error_print_progname. | 	   error_print_progname. | ||||||
|       248: Export __fpurge. |       248: Export __fpurge. | ||||||
|       249: Export pthread_condattr_getclock, pthread_condattr_setclock. |       249: Export pthread_condattr_getclock, pthread_condattr_setclock. | ||||||
|  |       250: Export clock_nanosleep. | ||||||
|      */ |      */ | ||||||
|  |  | ||||||
|      /* Note that we forgot to bump the api for ualarm, strtoll, strtoull */ |      /* Note that we forgot to bump the api for ualarm, strtoll, strtoull */ | ||||||
|  |  | ||||||
| #define CYGWIN_VERSION_API_MAJOR 0 | #define CYGWIN_VERSION_API_MAJOR 0 | ||||||
| #define CYGWIN_VERSION_API_MINOR 249 | #define CYGWIN_VERSION_API_MINOR 250 | ||||||
|  |  | ||||||
|      /* There is also a compatibity version number associated with the |      /* There is also a compatibity version number associated with the | ||||||
| 	shared memory regions.  It is incremented when incompatible | 	shared memory regions.  It is incremented when incompatible | ||||||
|   | |||||||
| @@ -92,6 +92,7 @@ also IEEE Std 1003.1-2008 (POSIX.1-2008).</para> | |||||||
|     clock_getcpuclockid |     clock_getcpuclockid | ||||||
|     clock_getres |     clock_getres | ||||||
|     clock_gettime |     clock_gettime | ||||||
|  |     clock_nanosleep		(see chapter "Implementation Notes") | ||||||
|     clock_settime		(see chapter "Implementation Notes") |     clock_settime		(see chapter "Implementation Notes") | ||||||
|     clog |     clog | ||||||
|     clogf |     clogf | ||||||
| @@ -1299,7 +1300,6 @@ also IEEE Std 1003.1-2008 (POSIX.1-2008).</para> | |||||||
|     ceill |     ceill | ||||||
|     cexpl |     cexpl | ||||||
|     cimagl |     cimagl | ||||||
|     clock_nanosleep |  | ||||||
|     clogl |     clogl | ||||||
|     conjl |     conjl | ||||||
|     copysignl |     copysignl | ||||||
| @@ -1446,8 +1446,10 @@ by keeping track of the current root and accomodating this in the file | |||||||
| related function calls.  A real chroot functionality is not supported by | related function calls.  A real chroot functionality is not supported by | ||||||
| Windows however.</para> | Windows however.</para> | ||||||
|  |  | ||||||
| <para><function>clock_setres</function>, <function>clock_settime</function>, | <para><function>clock_nanosleep</function> currently supports only | ||||||
| and <function>timer_create</function> only support CLOCK_REALTIME.</para> | CLOCK_REALTIME and CLOCK_MONOTONIC.  <function>clock_setres</function>, | ||||||
|  | <function>clock_settime</function>, and <function>timer_create</function> | ||||||
|  | currently support only CLOCK_REALTIME.</para> | ||||||
|  |  | ||||||
| <para>BSD file locks created via <function>flock</function> are not | <para>BSD file locks created via <function>flock</function> are not | ||||||
| propagated to the parent process and sibling processes.  The locks are | propagated to the parent process and sibling processes.  The locks are | ||||||
|   | |||||||
| @@ -81,52 +81,104 @@ signal (int sig, _sig_func_ptr func) | |||||||
| } | } | ||||||
|  |  | ||||||
| extern "C" int | extern "C" int | ||||||
| nanosleep (const struct timespec *rqtp, struct timespec *rmtp) | clock_nanosleep (clockid_t clk_id, int flags, const struct timespec *rqtp, | ||||||
|  | 		 struct timespec *rmtp) | ||||||
| { | { | ||||||
|  |   const bool abstime = (flags & TIMER_ABSTIME) ? true : false; | ||||||
|   int res = 0; |   int res = 0; | ||||||
|   sig_dispatch_pending (); |   sig_dispatch_pending (); | ||||||
|   pthread_testcancel (); |   pthread_testcancel (); | ||||||
|  |  | ||||||
|   if ((unsigned int) rqtp->tv_nsec > 999999999) |   if (rqtp->tv_sec < 0 || rqtp->tv_nsec < 0 || rqtp->tv_nsec > 999999999L) | ||||||
|  |     return EINVAL; | ||||||
|  |  | ||||||
|  |   /* Explicitly disallowed by POSIX. Needs to be checked first to avoid | ||||||
|  |      being caught by the following test. */ | ||||||
|  |   if (clk_id == CLOCK_THREAD_CPUTIME_ID) | ||||||
|  |     return EINVAL; | ||||||
|  |  | ||||||
|  |   /* support for CPU-time clocks is optional */ | ||||||
|  |   if (CLOCKID_IS_PROCESS (clk_id) || CLOCKID_IS_THREAD (clk_id)) | ||||||
|  |     return ENOTSUP; | ||||||
|  |  | ||||||
|  |   switch (clk_id) | ||||||
|     { |     { | ||||||
|       set_errno (EINVAL); |     case CLOCK_REALTIME: | ||||||
|       return -1; |     case CLOCK_MONOTONIC: | ||||||
|  |       break; | ||||||
|  |     default: | ||||||
|  |       /* unknown or illegal clock ID */ | ||||||
|  |       return EINVAL; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   LARGE_INTEGER timeout; |   LARGE_INTEGER timeout; | ||||||
|  |  | ||||||
|   timeout.QuadPart = (LONGLONG) rqtp->tv_sec * NSPERSEC |   timeout.QuadPart = (LONGLONG) rqtp->tv_sec * NSPERSEC | ||||||
| 		     + ((LONGLONG) rqtp->tv_nsec + 99LL) / 100LL; | 		     + ((LONGLONG) rqtp->tv_nsec + 99LL) / 100LL; | ||||||
|   timeout.QuadPart *= -1LL; |  | ||||||
|  |  | ||||||
|   syscall_printf ("nanosleep (%ld.%09ld)", rqtp->tv_sec, rqtp->tv_nsec); |   if (abstime) | ||||||
|  |     { | ||||||
|  |       struct timespec tp; | ||||||
|  |  | ||||||
|  |       clock_gettime (clk_id, &tp); | ||||||
|  |       /* Check for immediate timeout */ | ||||||
|  |       if (tp.tv_sec > rqtp->tv_sec | ||||||
|  |           || (tp.tv_sec == rqtp->tv_sec && tp.tv_nsec > rqtp->tv_nsec)) | ||||||
|  | 	return 0; | ||||||
|  |  | ||||||
|  |       if (clk_id == CLOCK_REALTIME) | ||||||
|  | 	timeout.QuadPart += FACTOR; | ||||||
|  |       else | ||||||
|  | 	{ | ||||||
|  | 	  /* other clocks need to be handled with a relative timeout */ | ||||||
|  | 	  timeout.QuadPart -= tp.tv_sec * NSPERSEC + tp.tv_nsec / 100LL; | ||||||
|  | 	  timeout.QuadPart *= -1LL; | ||||||
|  | 	} | ||||||
|  |     } | ||||||
|  |   else /* !abstime */ | ||||||
|  |     timeout.QuadPart *= -1LL; | ||||||
|  |  | ||||||
|  |   syscall_printf ("clock_nanosleep (%ld.%09ld)", rqtp->tv_sec, rqtp->tv_nsec); | ||||||
|  |  | ||||||
|   int rc = cancelable_wait (signal_arrived, &timeout); |   int rc = cancelable_wait (signal_arrived, &timeout); | ||||||
|   if (rc == WAIT_OBJECT_0) |   if (rc == WAIT_OBJECT_0) | ||||||
|     { |     { | ||||||
|       _my_tls.call_signal_handler (); |       _my_tls.call_signal_handler (); | ||||||
|       set_errno (EINTR); |       res = EINTR; | ||||||
|       res = -1; |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   if (rmtp) |   /* according to POSIX, rmtp is used only if !abstime */ | ||||||
|  |   if (rmtp && !abstime) | ||||||
|     { |     { | ||||||
|       rmtp->tv_sec = (time_t) (timeout.QuadPart / NSPERSEC); |       rmtp->tv_sec = (time_t) (timeout.QuadPart / NSPERSEC); | ||||||
|       rmtp->tv_nsec = (long) ((timeout.QuadPart % NSPERSEC) * 100LL); |       rmtp->tv_nsec = (long) ((timeout.QuadPart % NSPERSEC) * 100LL); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   syscall_printf ("%d = nanosleep (%ld.%09ld, %ld.%09.ld)", res, rqtp->tv_sec, |   syscall_printf ("%d = clock_nanosleep (%lu, %d, %ld.%09ld, %ld.%09.ld)", | ||||||
| 		  rqtp->tv_nsec, rmtp ? rmtp->tv_sec : 0, | 		  res, clk_id, flags, rqtp->tv_sec, rqtp->tv_nsec, | ||||||
| 		  rmtp ? rmtp->tv_nsec : 0); | 		  rmtp ? rmtp->tv_sec : 0, rmtp ? rmtp->tv_nsec : 0); | ||||||
|   return res; |   return res; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | extern "C" int | ||||||
|  | nanosleep (const struct timespec *rqtp, struct timespec *rmtp) | ||||||
|  | { | ||||||
|  |   int res = clock_nanosleep (CLOCK_REALTIME, 0, rqtp, rmtp); | ||||||
|  |   if (res != 0) | ||||||
|  |     { | ||||||
|  |       set_errno (res); | ||||||
|  |       return -1; | ||||||
|  |     } | ||||||
|  |   return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
| extern "C" unsigned int | extern "C" unsigned int | ||||||
| sleep (unsigned int seconds) | sleep (unsigned int seconds) | ||||||
| { | { | ||||||
|   struct timespec req, rem; |   struct timespec req, rem; | ||||||
|   req.tv_sec = seconds; |   req.tv_sec = seconds; | ||||||
|   req.tv_nsec = 0; |   req.tv_nsec = 0; | ||||||
|   if (nanosleep (&req, &rem)) |   if (clock_nanosleep (CLOCK_REALTIME, 0, &req, &rem)) | ||||||
|     return rem.tv_sec + (rem.tv_nsec > 0); |     return rem.tv_sec + (rem.tv_nsec > 0); | ||||||
|   return 0; |   return 0; | ||||||
| } | } | ||||||
| @@ -137,8 +189,13 @@ usleep (useconds_t useconds) | |||||||
|   struct timespec req; |   struct timespec req; | ||||||
|   req.tv_sec = useconds / 1000000; |   req.tv_sec = useconds / 1000000; | ||||||
|   req.tv_nsec = (useconds % 1000000) * 1000; |   req.tv_nsec = (useconds % 1000000) * 1000; | ||||||
|   int res = nanosleep (&req, NULL); |   int res = clock_nanosleep (CLOCK_REALTIME, 0, &req, NULL); | ||||||
|   return res; |   if (res != 0) | ||||||
|  |     { | ||||||
|  |       set_errno (res); | ||||||
|  |       return -1; | ||||||
|  |     } | ||||||
|  |   return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
| extern "C" int | extern "C" int | ||||||
|   | |||||||
| @@ -577,7 +577,7 @@ pthread::cancel () | |||||||
|  |  | ||||||
|     * accept () |     * accept () | ||||||
|     o aio_suspend () |     o aio_suspend () | ||||||
|     o clock_nanosleep () |     * clock_nanosleep () | ||||||
|     * close () |     * close () | ||||||
|     * connect () |     * connect () | ||||||
|     * creat () |     * creat () | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user