* [PATCH] clock_nanosleep(2), round two
@ 2011-08-03 18:42 Yaakov (Cygwin/X)
2011-08-03 19:10 ` Corinna Vinschen
0 siblings, 1 reply; 2+ messages in thread
From: Yaakov (Cygwin/X) @ 2011-08-03 18:42 UTC (permalink / raw)
To: cygwin-patches
[-- Attachment #1: Type: text/plain, Size: 361 bytes --]
Here's my second attempt at clock_nanosleep(2). After what we dealt
with in round one, this should be a piece of cake.
http://pubs.opengroup.org/onlinepubs/9699919799/functions/clock_nanosleep.html
http://www.kernel.org/doc/man-pages/online/pages/man2/clock_nanosleep.2.html
Patches for winsup/cygwin and winsup/doc, plus a test program, attached.
Yaakov
[-- Attachment #2: cygwin-clock_nanosleep.patch --]
[-- Type: text/x-patch, Size: 7828 bytes --]
2011-08-03 Yaakov Selkowitz <yselkowitz@...>
* 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.
Index: cygwin.din
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/cygwin.din,v
retrieving revision 1.245
diff -u -p -r1.245 cygwin.din
--- cygwin.din 21 Jul 2011 09:39:21 -0000 1.245
+++ cygwin.din 3 Aug 2011 17:56:20 -0000
@@ -223,6 +223,7 @@ _clock = clock SIGFE
clock_getcpuclockid SIGFE
clock_getres SIGFE
clock_gettime SIGFE
+clock_nanosleep SIGFE
clock_setres SIGFE
clock_settime SIGFE
clog NOSIGFE
Index: posix.sgml
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/posix.sgml,v
retrieving revision 1.69
diff -u -p -r1.69 posix.sgml
--- posix.sgml 21 Jul 2011 09:39:21 -0000 1.69
+++ posix.sgml 3 Aug 2011 17:56:20 -0000
@@ -92,6 +92,7 @@ also IEEE Std 1003.1-2008 (POSIX.1-2008)
clock_getcpuclockid
clock_getres
clock_gettime
+ clock_nanosleep (see chapter "Implementation Notes")
clock_settime (see chapter "Implementation Notes")
clog
clogf
@@ -1299,7 +1300,6 @@ also IEEE Std 1003.1-2008 (POSIX.1-2008)
ceill
cexpl
cimagl
- clock_nanosleep
clogl
conjl
copysignl
@@ -1446,8 +1446,10 @@ by keeping track of the current root and
related function calls. A real chroot functionality is not supported by
Windows however.</para>
-<para><function>clock_setres</function>, <function>clock_settime</function>,
-and <function>timer_create</function> only support CLOCK_REALTIME.</para>
+<para><function>clock_nanosleep</function> currently supports only
+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
propagated to the parent process and sibling processes. The locks are
Index: signal.cc
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/signal.cc,v
retrieving revision 1.99
diff -u -p -r1.99 signal.cc
--- signal.cc 3 Aug 2011 16:40:47 -0000 1.99
+++ signal.cc 3 Aug 2011 17:56:20 -0000
@@ -81,52 +81,104 @@ signal (int sig, _sig_func_ptr func)
}
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;
sig_dispatch_pending ();
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);
- return -1;
+ case CLOCK_REALTIME:
+ case CLOCK_MONOTONIC:
+ break;
+ default:
+ /* unknown or illegal clock ID */
+ return EINVAL;
}
+
LARGE_INTEGER timeout;
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);
+ 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);
if (rc == WAIT_OBJECT_0)
{
_my_tls.call_signal_handler ();
- set_errno (EINTR);
- res = -1;
+ res = EINTR;
}
- if (rmtp)
+ /* according to POSIX, rmtp is used only if !abstime */
+ if (rmtp && !abstime)
{
rmtp->tv_sec = (time_t) (timeout.QuadPart / NSPERSEC);
rmtp->tv_nsec = (long) ((timeout.QuadPart % NSPERSEC) * 100LL);
}
- 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);
+ syscall_printf ("%d = clock_nanosleep (%lu, %d, %ld.%09ld, %ld.%09.ld)",
+ res, clk_id, flags, rqtp->tv_sec, rqtp->tv_nsec,
+ rmtp ? rmtp->tv_sec : 0, rmtp ? rmtp->tv_nsec : 0);
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
sleep (unsigned int seconds)
{
struct timespec req, rem;
req.tv_sec = seconds;
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 0;
}
@@ -137,8 +189,13 @@ usleep (useconds_t useconds)
struct timespec req;
req.tv_sec = useconds / 1000000;
req.tv_nsec = (useconds % 1000000) * 1000;
- int res = nanosleep (&req, NULL);
- return res;
+ int res = clock_nanosleep (CLOCK_REALTIME, 0, &req, NULL);
+ if (res != 0)
+ {
+ set_errno (res);
+ return -1;
+ }
+ return 0;
}
extern "C" int
Index: thread.cc
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/thread.cc,v
retrieving revision 1.245
diff -u -p -r1.245 thread.cc
--- thread.cc 3 Aug 2011 16:40:47 -0000 1.245
+++ thread.cc 3 Aug 2011 17:56:20 -0000
@@ -577,7 +577,7 @@ pthread::cancel ()
* accept ()
o aio_suspend ()
- o clock_nanosleep ()
+ * clock_nanosleep ()
* close ()
* connect ()
* creat ()
Index: include/cygwin/version.h
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/include/cygwin/version.h,v
retrieving revision 1.350
diff -u -p -r1.350 version.h
--- include/cygwin/version.h 21 Jul 2011 09:39:22 -0000 1.350
+++ include/cygwin/version.h 3 Aug 2011 17:56:20 -0000
@@ -418,12 +418,13 @@ details. */
error_print_progname.
248: Export __fpurge.
249: Export pthread_condattr_getclock, pthread_condattr_setclock.
+ 250: Export clock_nanosleep.
*/
/* Note that we forgot to bump the api for ualarm, strtoll, strtoull */
#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
shared memory regions. It is incremented when incompatible
[-- Attachment #3: doc-clock_nanosleep.patch --]
[-- Type: text/x-patch, Size: 909 bytes --]
2011-08-03 Yaakov Selkowitz <yselkowitz@...>
* new-features.sgml (ov-new1.7.10): Document new POSIX Clock Selection
option APIs.
Index: new-features.sgml
===================================================================
RCS file: /cvs/src/src/winsup/doc/new-features.sgml,v
retrieving revision 1.87
diff -u -p -r1.87 new-features.sgml
--- new-features.sgml 20 Jul 2011 01:19:53 -0000 1.87
+++ new-features.sgml 20 Jul 2011 10:41:00 -0000
@@ -41,6 +41,11 @@ pthread_attr_setstackaddr, pthread_attr_
</para></listitem>
<listitem><para>
+POSIX Clock Selection option. New APIs: clock_nanosleep,
+pthread_condattr_getclock, pthread_condattr_setclock.
+</para></listitem>
+
+<listitem><para>
clock_gettime(3) and clock_getres(3) accept per-process and per-thread CPU-time
clocks, including CLOCK_PROCESS_CPUTIME_ID and CLOCK_THREAD_CPUTIME_ID.
New APIs: clock_getcpuclockid, pthread_getcpuclockid.
[-- Attachment #4: nanosleep-test.c --]
[-- Type: text/x-csrc, Size: 2114 bytes --]
#pragma CCOD:script no
#pragma CCOD:options -lrt
#define _XOPEN_SOURCE 600
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#ifdef __CYGWIN__
#include <dlfcn.h>
int (*clock_nanosleep) (clockid_t, int, const struct timespec *, struct timespec *);
#endif
int
mysleep (clockid_t clk_id, int flags, struct timespec *rqtp, struct timespec *rmtp)
{
struct timespec now;
int res;
clock_gettime (CLOCK_REALTIME, &now);
printf ("Start: %s", asctime (localtime (&now.tv_sec)));
res = clock_nanosleep (clk_id, flags, rqtp, rmtp);
clock_gettime (CLOCK_REALTIME, &now);
printf ("End: %s\n", asctime (localtime (&now.tv_sec)));
return res;
}
void
mysleep_err (clockid_t clk_id, int flags, struct timespec *rqtp, struct timespec *rmtp)
{
int res = clock_nanosleep (clk_id, flags, rqtp, rmtp);
printf ("%s\n", strerror (res));
}
int
main (void)
{
struct timespec tp;
int res;
#ifdef __CYGWIN__
clock_nanosleep = dlsym (dlopen ("cygwin1.dll", 0), "clock_nanosleep");
#endif
tp.tv_sec = 2;
tp.tv_nsec = 500000000;
res = mysleep (CLOCK_REALTIME, 0, &tp, NULL);
if (res)
goto done;
clock_gettime (CLOCK_REALTIME, &tp);
tp.tv_sec += 2;
res = mysleep (CLOCK_REALTIME, TIMER_ABSTIME, &tp, NULL);
if (res)
goto done;
clock_gettime (CLOCK_MONOTONIC, &tp);
tp.tv_sec += 2;
res = mysleep (CLOCK_MONOTONIC, TIMER_ABSTIME, &tp, NULL);
if (res)
goto done;
tp.tv_sec = 2;
tp.tv_nsec = 500000000;
res = mysleep (CLOCK_MONOTONIC, 0, &tp, NULL);
if (res)
goto done;
clock_gettime (CLOCK_REALTIME, &tp);
tp.tv_sec--;
mysleep_err (CLOCK_REALTIME, TIMER_ABSTIME, &tp, NULL);
tp.tv_sec = -1;
tp.tv_nsec = 500000000;
mysleep_err (CLOCK_REALTIME, 0, &tp, NULL);
tp.tv_sec = 1;
tp.tv_nsec = -500000000;
mysleep_err (CLOCK_REALTIME, 0, &tp, NULL);
tp.tv_sec = 0;
tp.tv_nsec = 500000000;
#ifdef CLOCK_PROCESS_CPUTIME_ID
mysleep_err (CLOCK_PROCESS_CPUTIME_ID, 0, &tp, NULL);
#endif
#ifdef CLOCK_THREAD_CPUTIME_ID
mysleep_err (CLOCK_THREAD_CPUTIME_ID, 0, &tp, NULL);
#endif
mysleep_err (-1, 0, &tp, NULL);
done:
return res;
}
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [PATCH] clock_nanosleep(2), round two
2011-08-03 18:42 [PATCH] clock_nanosleep(2), round two Yaakov (Cygwin/X)
@ 2011-08-03 19:10 ` Corinna Vinschen
0 siblings, 0 replies; 2+ messages in thread
From: Corinna Vinschen @ 2011-08-03 19:10 UTC (permalink / raw)
To: cygwin-patches
On Aug 3 13:42, Yaakov (Cygwin/X) wrote:
> * 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.
Thumbs up.
Thank you,
Corinna
--
Corinna Vinschen Please, send mails regarding Cygwin to
Cygwin Project Co-Leader cygwin AT cygwin DOT com
Red Hat
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2011-08-03 19:10 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-08-03 18:42 [PATCH] clock_nanosleep(2), round two Yaakov (Cygwin/X)
2011-08-03 19:10 ` Corinna Vinschen
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).