Re: [libevl][PATCH 2/2] tests: sched-quota-accuracy: Add preempting FIFO thread

Philippe Gerum <[email protected]> Tue, 16 Jun 2026 08:09:21 +0200
Newsgroups dev.linux.lists.xenomai
Message-ID <[email protected]>
Jan Kiszka <[email protected]> writes:

> 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

Merged, thanks.

-- 
Philippe.