From 028f078c32abfdce18912b7f79212fe0d185663f Mon Sep 17 00:00:00 2001 From: brarcher Date: Mon, 23 Sep 2013 15:17:56 +0000 Subject: [PATCH] Determine at runtime which clockid_t to use for clock_gettime 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 | 28 ++++++++++++++++++++++++++++ src/check_impl.h | 2 ++ src/check_log.c | 4 ++-- src/check_run.c | 29 +++++++---------------------- 4 files changed, 39 insertions(+), 24 deletions(-) diff --git a/src/check.c b/src/check.c index 9e8d7e2..0d84003 100644 --- a/src/check.c +++ b/src/check.c @@ -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; +} diff --git a/src/check_impl.h b/src/check_impl.h index f1f4664..ba58aa4 100644 --- a/src/check_impl.h +++ b/src/check_impl.h @@ -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 */ diff --git a/src/check_log.c b/src/check_log.c index 2bbacdb..6bcf527 100644 --- a/src/check_log.c +++ b/src/check_log.c @@ -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, " %u.%06u\n", duration / 1000000, duration % 1000000); diff --git a/src/check_run.c b/src/check_run.c index d41943e..7882a64 100644 --- a/src/check_run.c +++ b/src/check_run.c @@ -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; -- 2.40.0