]> granicus.if.org Git - check/commitdiff
Use setitimer in timer_* fallbacks
authorbrarcher <brarcher@64e312b2-a51f-0410-8e61-82d0ca0eb02a>
Sat, 21 Sep 2013 16:33:08 +0000 (16:33 +0000)
committerbrarcher <brarcher@64e312b2-a51f-0410-8e61-82d0ca0eb02a>
Sat, 21 Sep 2013 16:33:08 +0000 (16:33 +0000)
CCurrently on GNU/Hurd the timer_* functions are not implemented;
check's configure detects that and switches to the replacements
functions in lib/, which use alarm for the timer. However, using
alarm does not allow a timeout precision more than 1 second (as also
written in the comments in lib/timer_settime.c), causing the failure
of the two tests check_check_export and check_check.

As a workaround, it is possible to get a better precision using the
POSIX function setitimer [1] (declared obsolescent, but still usable)
instead of alarm.

This change checks for the existence of setitimer, and in case it
exists uses it (with its ITIMER_REAL timer) in the replacement
timer_settime and timer_delete. Given they are implemented in the
Hurd, all the tests of check passes.

[1] http://pubs.opengroup.org/onlinepubs/9699919799/functions/getitimer.html

Patch submitted by Pino Toscano, patch#49

git-svn-id: svn+ssh://svn.code.sf.net/p/check/code/trunk@759 64e312b2-a51f-0410-8e61-82d0ca0eb02a

AUTHORS
NEWS
configure.ac
lib/timer_delete.c
lib/timer_settime.c

diff --git a/AUTHORS b/AUTHORS
index 30027798e24bc350312155901f0e1718480f4b40..ff78f540d05e2ea54936e537ab23ddbee5dd9cd5 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -41,6 +41,7 @@ Contributors:
     Sebastian Rasmussen   (duration bug fix, 64-bit API fix)
     Martin Willers        (rename check's internal list API to start with check_)
     bross                 (patches for msys/mingw32 support)
+    Pino Toscano          (GNU/Hurd support for subsecond timeouts)
 
 Anybody who has contributed code to Check or Check's build system is
 considered an author.  Send patches to this file to 
diff --git a/NEWS b/NEWS
index bbec28446064841e0196543c0ee908296c999ce9..43ae88ef25372e84d36a684575e2797b35d23b03 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,10 @@ In development:
 
 * Check compiles for the Windows using x86_64-w64-mingw32.
 
+* On systems without timer_settimer, use setitimer (if available) to get
+  subsecond unit test timeouts. If setitimer is unavailable, fallback
+  on alarm.
+
 Thu, Apr 18, 2013: Released Check 0.9.10
   based on r743 (2013-04-18 11:27:03 +0200)
 
index 0d8c80d25f73430ac12a2be5ea1366c74dfa1cc3..9f710982c15169502bd7bfa9b5409b0be17d67cc 100644 (file)
@@ -184,6 +184,8 @@ AC_FUNC_REALLOC
 AC_REPLACE_FUNCS([alarm clock_gettime timer_create timer_settime timer_delete fileno localtime_r pipe putenv setenv sleep strdup strsignal unsetenv])
 AC_CHECK_DECLS([alarm, clock_gettime, timer_create, timer_settime, timer_delete, fileno, localtime_r, pipe, putenv, setenv, sleep, strdup, strsignal, unsetenv])
 
+AC_CHECK_FUNCS([setitimer])
+
 # Check if the system's snprintf (and its variations) are C99 compliant.
 # If they are not, use the version in libcompat.
 HW_FUNC_VSNPRINTF
index 4228b371d3db744e55b51f1edefe181d00f35bcb..02cf16b6d4f97148abe3e7d7bf4290c8fed34e3d 100644 (file)
@@ -2,6 +2,23 @@
 
 int timer_delete(timer_t timerid CK_ATTRIBUTE_UNUSED)
 {
+#ifdef HAVE_SETITIMER
+    /*
+     * If the system does not have timer_settime() but does have
+     * setitimer() use that instead of alarm().
+     */
+    struct itimerval new;
+
+    /*
+     * Setting values to '0' results in disabling the running timer.
+     */
+    new.it_value.tv_sec     = 0;
+    new.it_value.tv_usec    = 0;
+    new.it_interval.tv_sec  = 0;
+    new.it_interval.tv_usec = 0;
+
+    return setitimer(ITIMER_REAL, &new, NULL);
+#else
     /*
      * There is only one timer, that used by alarm.
      * Setting alarm(0) will not set a new alarm, and
@@ -11,4 +28,5 @@ int timer_delete(timer_t timerid CK_ATTRIBUTE_UNUSED)
     alarm(0);
     
     return 0;
+#endif
 }
index 39ec613fc8a1f0627162bc39b65b8c590ac444ea..963830a32af610934b53fdee54b6ac72388edf99 100644 (file)
@@ -5,6 +5,20 @@ int timer_settime(timer_t timerid               CK_ATTRIBUTE_UNUSED,
                   const struct itimerspec *new_value, 
                   struct itimerspec * old_value CK_ATTRIBUTE_UNUSED)
 {
+#ifdef HAVE_SETITIMER
+    /*
+     * If the system does not have timer_settime() but does have
+     * setitimer() use that instead of alarm().
+     */
+    struct itimerval new;
+
+    new.it_value.tv_sec     = new_value->it_value.tv_sec;
+    new.it_value.tv_usec    = new_value->it_value.tv_nsec / 1000;
+    new.it_interval.tv_sec  = new_value->it_interval.tv_sec;
+    new.it_interval.tv_usec = new_value->it_interval.tv_nsec / 1000;
+
+    return setitimer(ITIMER_REAL, &new, NULL);
+#else
     int seconds = new_value->it_value.tv_sec;
     
     /* 
@@ -19,4 +33,5 @@ int timer_settime(timer_t timerid               CK_ATTRIBUTE_UNUSED,
     alarm(seconds);
     
     return 0;
+#endif
 }