]> granicus.if.org Git - check/commitdiff
Determine at runtime which clockid_t to use for clock_gettime
authorbrarcher <brarcher@64e312b2-a51f-0410-8e61-82d0ca0eb02a>
Mon, 23 Sep 2013 15:17:56 +0000 (15:17 +0000)
committerbrarcher <brarcher@64e312b2-a51f-0410-8e61-82d0ca0eb02a>
Mon, 23 Sep 2013 15:17:56 +0000 (15:17 +0000)
The cygwin platform (perhaps others) does not support
CLOCK_MONOTONIC in clock_gettime. However, it does support
CLOCK_REALTIME. Instead of having every call to clock_gettime
check which clock to use, check once and cache the result.

The only two clock options which seemed useful are CLOCK_MONOTONIC
and CLOCK_REALTIME. If others are available in the future
(or another clock type seems a good alternative if these two are
missing on a system) it can be added later.

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

src/check.c
src/check_impl.h
src/check_log.c
src/check_run.c

index 9e8d7e23a19727fa9c11cb784daf8eb9d4553271..0d84003390ca35a1b8a8a47f0f4c7e26df799c3a 100644 (file)
@@ -445,3 +445,31 @@ enum fork_status cur_fork_status (void)
 {
   return _fstat;
 }
+
+/**
+ * Not all systems support the same clockid_t's. This call checks
+ * if the CLOCK_MONOTONIC clockid_t is valid. If so, that is returned,
+ * otherwise, CLOCK_REALTIME is returned.
+ *
+ * The clockid_t that was found to work on the first call is
+ * cached for subsequent calls.
+ */
+clockid_t check_get_clockid()
+{
+       static clockid_t clockid = -1;
+
+       if(clockid == -1)
+       {
+               struct timespec ts;
+               if(clock_gettime(CLOCK_MONOTONIC, &ts) == 0)
+               {
+                       clockid = CLOCK_MONOTONIC;
+               }
+               else
+               {
+                       clockid = CLOCK_REALTIME;
+               }
+       }
+
+       return clockid;
+}
index f1f4664f7296bfa09cb579e141b8a147ec38a471..ba58aa47113d156c2560123c3d1b62afee28c16b 100644 (file)
@@ -119,4 +119,6 @@ struct SRunner {
 void set_fork_status(enum fork_status fstat);
 enum fork_status cur_fork_status (void);
 
+clockid_t check_get_clockid();
+
 #endif /* CHECK_IMPL_H */
index 2bbacdb3ff3faff04b4748a9f85efec358115c84..6bcf527f384b586839dd93ebdc1577ae6a2aa09f 100644 (file)
@@ -239,7 +239,7 @@ void xml_lfun (SRunner *sr CK_ATTRIBUTE_UNUSED, FILE *file, enum print_output pr
     struct timeval inittv;
     struct tm now;
     gettimeofday(&inittv, NULL);
-    clock_gettime(CLOCK_MONOTONIC, &ts_start);
+    clock_gettime(check_get_clockid(), &ts_start);
     localtime_r(&(inittv.tv_sec), &now);
     strftime(t, sizeof("yyyy-mm-dd hh:mm:ss"), "%Y-%m-%d %H:%M:%S", &now);
   }
@@ -257,7 +257,7 @@ void xml_lfun (SRunner *sr CK_ATTRIBUTE_UNUSED, FILE *file, enum print_output pr
       unsigned int duration;
 
       /* calculate time the test were running */
-      clock_gettime(CLOCK_MONOTONIC, &ts_end);
+      clock_gettime(check_get_clockid(), &ts_end);
       duration = DIFF_IN_USEC(ts_start, ts_end);
       fprintf(file, "  <duration>%u.%06u</duration>\n",
           duration / 1000000, duration % 1000000);
index d41943e7b6b5f2ab5c0dbdd3c957018a0112abdf..7882a648523ebd99c46615f57793b3e0ef6694f4 100644 (file)
@@ -323,9 +323,9 @@ static TestResult *tcase_run_tfun_nofork (SRunner *sr, TCase *tc, TF *tfun, int
   tr = tcase_run_checked_setup(sr, tc);
   if (tr == NULL) {
     if ( 0 == setjmp(error_jmp_buffer) ) {
-      clock_gettime(CLOCK_MONOTONIC, &ts_start);
+      clock_gettime(check_get_clockid(), &ts_start);
       tfun->fn(i);
-      clock_gettime(CLOCK_MONOTONIC, &ts_end);
+      clock_gettime(check_get_clockid(), &ts_end);
     }
     tcase_run_checked_teardown(tc);
     return receive_result_info_nofork(tc->name, tfun->name, i,
@@ -379,7 +379,6 @@ static TestResult *tcase_run_tfun_fork (SRunner *sr, TCase *tc, TF *tfun, int i)
   int status = 0;
   struct timespec ts_start = {0}, ts_end = {0};
 
-  int timer_create_result;
   timer_t timerid;
   struct itimerspec timer_spec; 
   TestResult * tr;
@@ -393,9 +392,9 @@ static TestResult *tcase_run_tfun_fork (SRunner *sr, TCase *tc, TF *tfun, int i)
     group_pid = getpgrp();
     tr = tcase_run_checked_setup(sr, tc);
     free(tr);
-    clock_gettime(CLOCK_MONOTONIC, &ts_start);
+    clock_gettime(check_get_clockid(), &ts_start);
     tfun->fn(i);
-    clock_gettime(CLOCK_MONOTONIC, &ts_end);
+    clock_gettime(check_get_clockid(), &ts_end);
     tcase_run_checked_teardown(tc);
     send_duration_info(DIFF_IN_USEC(ts_start, ts_end));
     exit(EXIT_SUCCESS);
@@ -405,23 +404,9 @@ static TestResult *tcase_run_tfun_fork (SRunner *sr, TCase *tc, TF *tfun, int i)
 
   alarm_received = 0;
 
-  timer_create_result = timer_create(CLOCK_MONOTONIC,
-                           NULL /* fire SIGALRM if timer expires */,
-                           &timerid);
-
-  /*
-   * CLOCK_MONOTONIC is not supported on the Cygwin platform
-   * (maybe others as well). If the timer creation fails, attempt with
-   * CLOCK_REALTIME before bailing out.
-   */
-  if(timer_create_result != 0)
-  {
-         timer_create_result = timer_create(CLOCK_REALTIME,
-                           NULL /* fire SIGALRM if timer expires */,
-                           &timerid);
-  }
-
-  if(timer_create_result == 0)
+  if(timer_create(check_get_clockid(),
+                  NULL /* fire SIGALRM if timer expires */,
+                  &timerid) == 0)
   {
     /* Set the timer to fire once */
     timer_spec.it_value            = tc->timeout;