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 a2a97c382..9564d7e66 100644 --- a/src/unit-tests/ostimer-test/ut_ostimer_test.c +++ b/src/unit-tests/ostimer-test/ut_ostimer_test.c @@ -74,10 +74,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; @@ -88,18 +86,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); } } }