[libevl][PATCH 2/2] tests: sched-quota-accuracy: Add preempting FIFO thread
Jan Kiszka <[email protected]> Sun, 14 Jun 2026 21:37:26 +0200
| Newsgroups | dev.linux.lists.xenomai |
|---|---|
| Message-ID | <[email protected]> |
From: Jan Kiszka <[email protected]> Test that higher-prio SCHED_FIFO threads do not run on the bill of SCHED_QUOTA threads and that their accounting is not otherwise disturbed. Signed-off-by: Jan Kiszka <[email protected]> --- tests/sched-quota-accuracy.c | 55 +++++++++++++++++++++++++++++++----- 1 file changed, 48 insertions(+), 7 deletions(-) diff --git a/tests/sched-quota-accuracy.c b/tests/sched-quota-accuracy.c index 278ff1b..f48f034 100644 --- a/tests/sched-quota-accuracy.c +++ b/tests/sched-quota-accuracy.c @@ -34,7 +34,7 @@ static struct quota_thread_desc { pthread_t tid; struct evl_sched_attrs attrs; unsigned long count; -} threads[MAX_THREADS]; +} threads[MAX_THREADS + 1]; static int nrthreads = 3; @@ -165,6 +165,41 @@ static void *quota_thread(void *arg) return NULL; } +static void *disruption_thread(void *arg) +{ + int serial = (int)(long)arg; + struct quota_thread_desc *t = threads + serial; + struct timespec now, to; + unsigned long loops; + int ret; + + set_thread_affinity(); + + loops = crunch_per_sec / 1000; /* yield every 1 ms */ + + __Tcall_assert(t->efd, evl_attach_self("disrupt")); + + evl_put_sem(&ready); + + __Tcall_assert(ret, evl_lock_mutex(&lock)); + for (;;) { + if (started) + break; + __Tcall_assert(ret, evl_wait_event(&barrier, &lock)); + } + __Tcall_assert(ret, evl_unlock_mutex(&lock)); + + while (!done) { + do_work(loops, &t->count); + + __Tcall_assert(ret, evl_read_clock(EVL_CLOCK_MONOTONIC, &now)); + timespec_add_ns(&to, &now, 1000000); + __Tcall_assert(ret, evl_sleep_until(EVL_CLOCK_MONOTONIC, &to)); + } + + return NULL; +} + static void create_quota_thread(int tgid, int serial) { struct quota_thread_desc *t = threads + serial; @@ -175,13 +210,13 @@ static void create_quota_thread(int tgid, int serial) new_thread(&t->tid, SCHED_FIFO, 1, quota_thread, (void *)(long)serial); } -static void create_fifo_thread(int serial) +static void create_fifo_thread(void *(*thread_func)(void *), int serial) { struct quota_thread_desc *t = threads + serial; t->attrs.sched_policy = SCHED_FIFO; - t->attrs.sched_priority = 1; - new_thread(&t->tid, SCHED_FIFO, 1, quota_thread, (void *)(long)serial); + t->attrs.sched_priority = 2; + new_thread(&t->tid, SCHED_FIFO, 2, thread_func, (void *)(long)serial); } static int cleanup_group(void) @@ -235,6 +270,9 @@ static double run_quota(int quota) __Tcall_assert(ret, evl_get_sem(&ready)); } + create_fifo_thread(disruption_thread, n); + __Tcall_assert(ret, evl_get_sem(&ready)); + __Tcall_assert(ret, evl_lock_mutex(&lock)); started = true; __Tcall_assert(ret, evl_broadcast_event(&barrier)); @@ -256,6 +294,8 @@ static double run_quota(int quota) for (n = 0; n < nrthreads; n++) pthread_join(threads[n].tid, NULL); + pthread_join(threads[nrthreads].tid, NULL); + /* * Percentage of completion of the SCHED_QUOTA run for the * given quota value, compared to the calibration run which @@ -301,7 +341,7 @@ static unsigned long long calibrate(void) crunch_per_sec = (((unsigned long long)count) * ONE_BILLION) / ns; for (n = 0; n < nrthreads; n++) { - create_fifo_thread(n); + create_fifo_thread(quota_thread, n); __Tcall_assert(ret, evl_get_sem(&ready)); } @@ -400,12 +440,13 @@ int main(int argc, char *argv[]) effective = run_quota(quota); if (verbose) /* Percentage of quota actually obtained. */ - do_trace("CPU%d: %d thread%s: cap=%d%%, effective=%.1f%%", + do_trace("CPU%d: %d thread%s: cap=%d%%, effective=%.1f%%, disruption=%.1f%%", test_cpu, nrthreads, nrthreads > 1 ? "s": "", quota, - effective); + effective, + threads[nrthreads].count * 100.0 / loops_per_sec); /* * The accuracy value is the alignment of the observed runtime -- 2.47.3