* [libevl][PATCH 1/2] tests: sched-quota-accuracy: Augment workload with busy-spinning
@ 2026-06-14 19:36 Jan Kiszka
2026-06-14 19:37 ` [libevl][PATCH 2/2] tests: sched-quota-accuracy: Add preempting FIFO thread Jan Kiszka
0 siblings, 1 reply; 3+ messages in thread
From: Jan Kiszka @ 2026-06-14 19:36 UTC (permalink / raw)
To: Xenomai, Philippe Gerum
From: Jan Kiszka <jan.kiszka@siemens.com>
This increases calibration accuracy, specifically over virtual
environments.
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
tests/sched-quota-accuracy.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/tests/sched-quota-accuracy.c b/tests/sched-quota-accuracy.c
index 9ca496d..278ff1b 100644
--- a/tests/sched-quota-accuracy.c
+++ b/tests/sched-quota-accuracy.c
@@ -94,6 +94,13 @@ static const struct option options[] = {
static unsigned long __attribute__(( noinline ))
__do_work(unsigned long count)
{
+ struct timespec now, to;
+ int ret;
+
+ __Tcall_assert(ret, evl_read_clock(EVL_CLOCK_MONOTONIC, &now));
+ timespec_add_ns(&to, &now, 100);
+ while (timespec_sub_ns(&to, &now) > 0)
+ __Tcall_assert(ret, evl_read_clock(EVL_CLOCK_MONOTONIC, &now));
return count + 1;
}
--
2.47.3
^ permalink raw reply related [flat|nested] 3+ messages in thread
* [libevl][PATCH 2/2] tests: sched-quota-accuracy: Add preempting FIFO thread
2026-06-14 19:36 [libevl][PATCH 1/2] tests: sched-quota-accuracy: Augment workload with busy-spinning Jan Kiszka
@ 2026-06-14 19:37 ` Jan Kiszka
2026-06-16 6:09 ` Philippe Gerum
0 siblings, 1 reply; 3+ messages in thread
From: Jan Kiszka @ 2026-06-14 19:37 UTC (permalink / raw)
To: Xenomai, Philippe Gerum
From: Jan Kiszka <jan.kiszka@siemens.com>
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 <jan.kiszka@siemens.com>
---
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
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [libevl][PATCH 2/2] tests: sched-quota-accuracy: Add preempting FIFO thread
2026-06-14 19:37 ` [libevl][PATCH 2/2] tests: sched-quota-accuracy: Add preempting FIFO thread Jan Kiszka
@ 2026-06-16 6:09 ` Philippe Gerum
0 siblings, 0 replies; 3+ messages in thread
From: Philippe Gerum @ 2026-06-16 6:09 UTC (permalink / raw)
To: Jan Kiszka; +Cc: Xenomai
Jan Kiszka <jan.kiszka@siemens.com> writes:
> From: Jan Kiszka <jan.kiszka@siemens.com>
>
> 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 <jan.kiszka@siemens.com>
> ---
> 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.
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-06-16 6:09 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-14 19:36 [libevl][PATCH 1/2] tests: sched-quota-accuracy: Augment workload with busy-spinning Jan Kiszka
2026-06-14 19:37 ` [libevl][PATCH 2/2] tests: sched-quota-accuracy: Add preempting FIFO thread Jan Kiszka
2026-06-16 6:09 ` Philippe Gerum
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.