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