mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-15 13:15:57 +00:00
selftests/timers/posix-timers: Validate overrun after unblock
When a timer signal is blocked and later unblocked then one signal should be delivered with the correct number of overruns since the timer was queued. Validate that behaviour. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Frederic Weisbecker <frederic@kernel.org>
This commit is contained in:
parent
f924f868ed
commit
73339b82f8
@ -540,10 +540,66 @@ static void check_gettime(int which, const char *name)
|
||||
ksft_test_result(wraps > 1, "check_gettime %s\n", name);
|
||||
}
|
||||
|
||||
static void check_overrun(int which, const char *name)
|
||||
{
|
||||
struct timespec start, now;
|
||||
struct tmrsig tsig = { };
|
||||
struct itimerspec its;
|
||||
struct sigaction sa;
|
||||
struct sigevent sev;
|
||||
timer_t timerid;
|
||||
sigset_t set;
|
||||
|
||||
sa.sa_flags = SA_SIGINFO;
|
||||
sa.sa_sigaction = siginfo_handler;
|
||||
sigemptyset(&sa.sa_mask);
|
||||
if (sigaction(SIGUSR1, &sa, NULL))
|
||||
fatal_error(name, "sigaction()");
|
||||
|
||||
/* Block the signal */
|
||||
sigemptyset(&set);
|
||||
sigaddset(&set, SIGUSR1);
|
||||
if (sigprocmask(SIG_BLOCK, &set, NULL))
|
||||
fatal_error(name, "sigprocmask(SIG_BLOCK)");
|
||||
|
||||
memset(&sev, 0, sizeof(sev));
|
||||
sev.sigev_notify = SIGEV_SIGNAL;
|
||||
sev.sigev_signo = SIGUSR1;
|
||||
sev.sigev_value.sival_ptr = &tsig;
|
||||
if (timer_create(which, &sev, &timerid))
|
||||
fatal_error(name, "timer_create()");
|
||||
|
||||
/* Start the timer to expire in 100ms and 100ms intervals */
|
||||
its.it_value.tv_sec = 0;
|
||||
its.it_value.tv_nsec = 100000000;
|
||||
its.it_interval.tv_sec = 0;
|
||||
its.it_interval.tv_nsec = 100000000;
|
||||
if (timer_settime(timerid, 0, &its, NULL))
|
||||
fatal_error(name, "timer_settime()");
|
||||
|
||||
if (clock_gettime(which, &start))
|
||||
fatal_error(name, "clock_gettime()");
|
||||
|
||||
do {
|
||||
if (clock_gettime(which, &now))
|
||||
fatal_error(name, "clock_gettime()");
|
||||
} while (calcdiff_ns(now, start) < NSECS_PER_SEC);
|
||||
|
||||
/* Unblock it, which should deliver a signal */
|
||||
if (sigprocmask(SIG_UNBLOCK, &set, NULL))
|
||||
fatal_error(name, "sigprocmask(SIG_UNBLOCK)");
|
||||
|
||||
if (timer_delete(timerid))
|
||||
fatal_error(name, "timer_delete()");
|
||||
|
||||
ksft_test_result(tsig.signals == 1 && tsig.overruns == 9,
|
||||
"check_overrun %s\n", name);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
ksft_print_header();
|
||||
ksft_set_plan(15);
|
||||
ksft_set_plan(18);
|
||||
|
||||
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");
|
||||
@ -574,6 +630,9 @@ int main(int argc, char **argv)
|
||||
check_gettime(CLOCK_MONOTONIC, "CLOCK_MONOTONIC");
|
||||
check_gettime(CLOCK_PROCESS_CPUTIME_ID, "CLOCK_PROCESS_CPUTIME_ID");
|
||||
check_gettime(CLOCK_THREAD_CPUTIME_ID, "CLOCK_THREAD_CPUTIME_ID");
|
||||
check_overrun(CLOCK_MONOTONIC, "CLOCK_MONOTONIC");
|
||||
check_overrun(CLOCK_PROCESS_CPUTIME_ID, "CLOCK_PROCESS_CPUTIME_ID");
|
||||
check_overrun(CLOCK_THREAD_CPUTIME_ID, "CLOCK_THREAD_CPUTIME_ID");
|
||||
|
||||
ksft_finished();
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user