From 52bf89327ae34f67b204091456dd30726ab42b4d Mon Sep 17 00:00:00 2001 From: Joseph Hickey Date: Tue, 31 Dec 2019 14:25:31 -0500 Subject: [PATCH] Fix #335: Clear pending signal when configuring timer On POSIX, call sigtimedwait() on the selected RT signal as part of the set up for the timebase. This ensures that if the signal is already pending, it will be cleared. This also simplifies the timer callback routine in the UT code, cleaning up some unncessary extra logic. --- src/os/posix/ostimer.c | 29 +++++++++++++++++++ src/unit-tests/ostimer-test/ut_ostimer_test.c | 18 ++++-------- 2 files changed, 34 insertions(+), 13 deletions(-) diff --git a/src/os/posix/ostimer.c b/src/os/posix/ostimer.c index 69dd8bfc7..54ad418fc 100644 --- a/src/os/posix/ostimer.c +++ b/src/os/posix/ostimer.c @@ -325,6 +325,7 @@ int32 OS_TimeBaseCreate_Impl(uint32 timer_id) int status; int i; struct sigevent evp; + struct timespec ts; OS_impl_timebase_internal_record_t *local; OS_common_record_t *global; OS_U32ValueWrapper_t arg; @@ -403,6 +404,34 @@ int32 OS_TimeBaseCreate_Impl(uint32 timer_id) sigemptyset(&local->sigset); sigaddset(&local->sigset, local->assigned_signal); + /* + * Ensure that the chosen signal is NOT already pending. + * + * Perform a "sigtimedwait" with a zero timeout to poll the + * status of the selected signal. RT signals are also queued, + * so this needs to be called in a loop to until sigtimedwait() + * returns an error. + * + * The max number of signals that can be queued is available + * via sysconf() as the _SC_SIGQUEUE_MAX value. + * + * The output is irrelevant here; the objective is to just ensure + * that the signal is not already pending. + */ + i = sysconf( _SC_SIGQUEUE_MAX); + do + { + ts.tv_sec = 0; + ts.tv_nsec = 0; + if (sigtimedwait(&local->sigset, NULL, &ts) < 0) + { + /* signal is NOT pending */ + break; + } + --i; + } + while(i > 0); + /* ** Initialize the sigevent structures for the handler. */ diff --git a/src/unit-tests/ostimer-test/ut_ostimer_test.c b/src/unit-tests/ostimer-test/ut_ostimer_test.c index 709f56c9b..395c13587 100644 --- a/src/unit-tests/ostimer-test/ut_ostimer_test.c +++ b/src/unit-tests/ostimer-test/ut_ostimer_test.c @@ -79,10 +79,8 @@ void UT_os_timercallback(uint32 timerId) OS_GetLocalTime(&endTime); - if (endTime.seconds == currTime.seconds) - currIntervalTime = endTime.microsecs - currTime.microsecs; - else - currIntervalTime = endTime.microsecs + (1000000 - currTime.microsecs); + currIntervalTime = 1000000 * (endTime.seconds - currTime.seconds) + + endTime.microsecs - currTime.microsecs; if (currIntervalTime >= prevIntervalTime) deltaTime = currIntervalTime - prevIntervalTime; @@ -102,18 +100,12 @@ void UT_os_timercallback(uint32 timerId) res = -1; loopCnt++; + currTime = endTime; + prevIntervalTime = currIntervalTime; - if (loopCnt < g_cbLoopCntMax) - { - currTime = endTime; - prevIntervalTime = currIntervalTime; - } - else + if (loopCnt == g_cbLoopCntMax) { g_status = (res == 0) ? 1 : -1; - - /* slow the timer down so the main test thread can continue */ - res = OS_TimerSet(g_timerId, 1000, 500000); } } }