The signal distribution test has a tendency to hang for a long time as the signal delivery is not really evenly distributed. Increasing the timer interval to 10ms makes this less likely. Add a timeout to catch the case where it hangs and terminate the test gracefully. While at it get rid of the pointless atomic operation on a the thread local variable in the signal handler. Signed-off-by: Thomas Gleixner <tglx@xxxxxxxxxxxxx> [edliaw: Rebase and fix checkpatch recommendations] Signed-off-by: Edward Liaw <edliaw@xxxxxxxxxx> --- tools/testing/selftests/timers/posix_timers.c | 43 ++++++++++++------- 1 file changed, 27 insertions(+), 16 deletions(-) diff --git a/tools/testing/selftests/timers/posix_timers.c b/tools/testing/selftests/timers/posix_timers.c index d49dd3ffd0d9..03779b6b3c20 100644 --- a/tools/testing/selftests/timers/posix_timers.c +++ b/tools/testing/selftests/timers/posix_timers.c @@ -24,7 +24,8 @@ static volatile int done; /* Busy loop in userspace to elapse ITIMER_VIRTUAL */ static void user_loop(void) { - while (!done); + while (!done) + continue; } /* @@ -184,18 +185,19 @@ static int check_timer_create(int which) return 0; } -int remain; -__thread int got_signal; +static int remain; +static __thread int got_signal; static void *distribution_thread(void *arg) { - while (__atomic_load_n(&remain, __ATOMIC_RELAXED)); + while (__atomic_load_n(&remain, __ATOMIC_RELAXED) && !done) + continue; return NULL; } static void distribution_handler(int nr) { - if (!__atomic_exchange_n(&got_signal, 1, __ATOMIC_RELAXED)) + if (++got_signal == 1) __atomic_fetch_sub(&remain, 1, __ATOMIC_RELAXED); } @@ -205,17 +207,19 @@ static void distribution_handler(int nr) */ static int check_timer_distribution(void) { - int err, i; - timer_t id; const int nthreads = 10; pthread_t threads[nthreads]; struct itimerspec val = { .it_value.tv_sec = 0, - .it_value.tv_nsec = 1000 * 1000, + .it_value.tv_nsec = 20 * 1000 * 1000, .it_interval.tv_sec = 0, - .it_interval.tv_nsec = 1000 * 1000, + .it_interval.tv_nsec = 20 * 1000 * 1000, }; + time_t start, now; + int err, i; + timer_t id; + done = 0; remain = nthreads + 1; /* worker threads + this thread */ signal(SIGALRM, distribution_handler); err = timer_create(CLOCK_PROCESS_CPUTIME_ID, NULL, &id); @@ -240,7 +244,18 @@ static int check_timer_distribution(void) } /* Wait for all threads to receive the signal. */ - while (__atomic_load_n(&remain, __ATOMIC_RELAXED)); + now = start = time(NULL); + while (__atomic_load_n(&remain, __ATOMIC_RELAXED)) { + now = time(NULL); + if (now - start > 5) + break; + } + done = 1; + + if (timer_delete(id)) { + ksft_perror("Can't delete timer\n"); + return -1; + } for (i = 0; i < nthreads; i++) { err = pthread_join(threads[i], NULL); @@ -251,12 +266,8 @@ static int check_timer_distribution(void) } } - if (timer_delete(id)) { - ksft_perror("Can't delete timer"); - return -1; - } + ksft_test_result((now - start <= 5), "%s\n", __func__); - ksft_test_result_pass("check_timer_distribution\n"); return 0; } @@ -265,7 +276,7 @@ int main(int argc, char **argv) ksft_print_header(); ksft_set_plan(6); - ksft_print_msg("Testing posix timers. False negative may happen on CPU execution \n"); + ksft_print_msg("Testing posix timers. False negative may happen on CPU execution\n"); ksft_print_msg("based timers if other threads run on the CPU...\n"); if (check_itimer(ITIMER_VIRTUAL) < 0) -- 2.44.0.rc1.240.g4c46232300-goog