Add noisy yield test in nOS-V
Ensure we can call nosv_yield in a loop without generating a lot of events when using the level 3 instrumentation level. Noisy events are now moved to level 4, so they shouldn't appear on the trace. Additionally, make sure that the noisy events appear on level 4.
This commit is contained in:
parent
a8a8a0e763
commit
c847ec19ad
@ -1,4 +1,4 @@
|
||||
# Copyright (c) 2021-2024 Barcelona Supercomputing Center (BSC)
|
||||
# Copyright (c) 2021-2025 Barcelona Supercomputing Center (BSC)
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
find_package(Nosv)
|
||||
@ -45,6 +45,8 @@ nosv_test(inline.c SORT)
|
||||
nosv_test(mutex.c SORT LEVEL 3)
|
||||
nosv_test(barrier.c SORT LEVEL 3)
|
||||
nosv_test(cond.c SORT LEVEL 3)
|
||||
nosv_test(yield-noisy.c NAME "yield-noisy-l3" DRIVER "yield-noisy-l3.driver.sh")
|
||||
nosv_test(yield-noisy.c NAME "yield-noisy-l4" DRIVER "yield-noisy-l4.driver.sh")
|
||||
|
||||
# Test multiple instrumentation levels
|
||||
nosv_test(several-tasks.c SORT NAME several-tasks-level-0 LEVEL 0)
|
||||
|
||||
30
test/rt/nosv/yield-noisy-l3.driver.sh
Normal file
30
test/rt/nosv/yield-noisy-l3.driver.sh
Normal file
@ -0,0 +1,30 @@
|
||||
target=$OVNI_TEST_BIN
|
||||
|
||||
# We will set our own
|
||||
unset NOSV_CONFIG
|
||||
unset NOSV_CONFIG_OVERRIDE
|
||||
|
||||
export NOSV_APPID=1
|
||||
|
||||
cat > nosv.toml << EOF
|
||||
instrumentation.version = "ovni"
|
||||
ovni.level = 3
|
||||
EOF
|
||||
|
||||
$target
|
||||
|
||||
. ./vars.sh
|
||||
|
||||
# We need to sort the trace as it has unsorted regions
|
||||
ovnisort ovni
|
||||
|
||||
# Ensure that we don't find any noisy events by using the limit of 5% of
|
||||
# nosv_yield calls. It is fine if some events don't appear.
|
||||
ovnitop ovni | awk -v n=$nyields \
|
||||
'/^V(AY|Ay|Sh|Sf|S\[|S\]|SN|Sn|Pr|Pp)/ { \
|
||||
if ($2 < 0.05 * n) { print $0, "OK" }
|
||||
else { print $0, "BAD"; bad++ }
|
||||
} END { if (bad != 0) { exit 1 } }'
|
||||
|
||||
# Perform the emulation with breakdown enabled
|
||||
ovniemu -b ovni
|
||||
38
test/rt/nosv/yield-noisy-l4.driver.sh
Normal file
38
test/rt/nosv/yield-noisy-l4.driver.sh
Normal file
@ -0,0 +1,38 @@
|
||||
target=$OVNI_TEST_BIN
|
||||
|
||||
# We will set our own
|
||||
unset NOSV_CONFIG
|
||||
unset NOSV_CONFIG_OVERRIDE
|
||||
|
||||
export NOSV_APPID=1
|
||||
|
||||
cat > nosv.toml << EOF
|
||||
instrumentation.version = "ovni"
|
||||
ovni.level = 4
|
||||
EOF
|
||||
|
||||
$target
|
||||
|
||||
. ./vars.sh
|
||||
|
||||
# We need to sort the trace as it has unsorted regions
|
||||
ovnisort ovni
|
||||
|
||||
# Ensure we get a lot of VA[yY] and VS[nN] events. We need to make sure that all
|
||||
# events are matched.
|
||||
ovnitop ovni | awk -v n=$nyields \
|
||||
'/^VA[Yy]/ { \
|
||||
/* Match the number or nosv_yield calls exactly */
|
||||
if ($2 == n) { print $0, "OK"; ok++ }
|
||||
else { print $0, "BAD" }
|
||||
} \
|
||||
/^VS[Nn]/ { \
|
||||
/* Use 2% for the non-blocking scheduler events */
|
||||
if ($2 > 0.02 * n) { print $0, "OK"; ok++ }
|
||||
else { print $0, "BAD" }
|
||||
} END {
|
||||
/* Be sure we matched the 4 rules */
|
||||
if (ok != 4) { exit 1 }
|
||||
}'
|
||||
|
||||
# Avoid emulation as may be huge
|
||||
89
test/rt/nosv/yield-noisy.c
Normal file
89
test/rt/nosv/yield-noisy.c
Normal file
@ -0,0 +1,89 @@
|
||||
/* Copyright (c) 2025 Barcelona Supercomputing Center (BSC)
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later */
|
||||
|
||||
#include <nosv.h>
|
||||
#include <nosv/alpi.h>
|
||||
#include <stdatomic.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "compat.h"
|
||||
|
||||
#define NITERS 1000L
|
||||
|
||||
atomic_int ncompleted = 0;
|
||||
|
||||
static void
|
||||
busywait(long iter)
|
||||
{
|
||||
for (volatile long i = 0; i < iter; i++)
|
||||
;
|
||||
}
|
||||
|
||||
static void
|
||||
task_body(nosv_task_t task)
|
||||
{
|
||||
UNUSED(task);
|
||||
|
||||
/* Yield a lot of times to try to generate several events */
|
||||
for (long i = 0; i < NITERS; i++) {
|
||||
nosv_yield(0);
|
||||
busywait(10000L);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
task_done(nosv_task_t task)
|
||||
{
|
||||
UNUSED(task);
|
||||
atomic_fetch_add(&ncompleted, 1);
|
||||
}
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
nosv_init();
|
||||
|
||||
uint64_t ncpus;
|
||||
|
||||
if (alpi_cpu_count(&ncpus))
|
||||
die("alpi_cpu_count failed");
|
||||
|
||||
nosv_task_t *tasks = calloc((size_t) ncpus, sizeof(nosv_task_t));
|
||||
if (tasks == NULL)
|
||||
die("calloc failed:");
|
||||
|
||||
int ntasks = (int) ncpus;
|
||||
info("ntasks = %d", ntasks);
|
||||
|
||||
FILE *f = fopen("vars.sh", "w");
|
||||
if (f == NULL)
|
||||
die("fopen failed:");
|
||||
|
||||
fprintf(f, "nyields=%ld\n", (long) ntasks * NITERS);
|
||||
fclose(f);
|
||||
|
||||
nosv_task_type_t task_type;
|
||||
nosv_type_init(&task_type, task_body, NULL, task_done, "task", NULL, NULL, 0);
|
||||
|
||||
for (int i = 0; i < ntasks; i++)
|
||||
nosv_create(&tasks[i], task_type, 0, 0);
|
||||
|
||||
for (int i = 0; i < ntasks; i++)
|
||||
nosv_submit(tasks[i], 0);
|
||||
|
||||
while (atomic_load(&ncompleted) != ntasks)
|
||||
sleep_us(1000);
|
||||
|
||||
for (int i = 0; i < ntasks; i++)
|
||||
nosv_destroy(tasks[i], 0);
|
||||
|
||||
nosv_type_destroy(task_type, 0);
|
||||
|
||||
free(tasks);
|
||||
|
||||
nosv_shutdown();
|
||||
|
||||
return 0;
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user