Add Nanos6 spawn task rt tests
This commit is contained in:
		
							parent
							
								
									b5eb652580
								
							
						
					
					
						commit
						9407616c2b
					
				| @ -41,6 +41,10 @@ nanos6_rt_test(several-tasks.c) | ||||
| nanos6_rt_test(sched-add.c) | ||||
| nanos6_rt_test(if0.c) | ||||
| #nanos6_rt_test(taskfor.c) #Taskfor no longer supported | ||||
| nanos6_rt_test(spawn-task.c) | ||||
| nanos6_rt_test(spawn-task-external.c) | ||||
| nanos6_rt_test(spawn-task-external-bad.c SHOULD_FAIL | ||||
|   REGEX "ovni_finish: thread [0-9]* is not dead") | ||||
| 
 | ||||
| # Test multiple instrumentation levels | ||||
| nanos6_rt_test(simple-task.c NAME simple-task-level-1 LEVEL 1) | ||||
|  | ||||
							
								
								
									
										71
									
								
								test/rt/nanos6/spawn-task-external-bad.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								test/rt/nanos6/spawn-task-external-bad.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,71 @@ | ||||
| /* Copyright (c) 2023 Barcelona Supercomputing Center (BSC)
 | ||||
|  * SPDX-License-Identifier: GPL-3.0-or-later */ | ||||
| 
 | ||||
| /* Spawn a task from an external thread that calls some nanos6
 | ||||
|  * functions. The external thread must be paused when the task pauses | ||||
|  * the execution. This emulates the same behavior as TAMPI when using a | ||||
|  * polling task. */ | ||||
| 
 | ||||
| #define _DEFAULT_SOURCE | ||||
| 
 | ||||
| #include <nanos6.h> | ||||
| #include <nanos6/library-mode.h> | ||||
| #include <time.h> | ||||
| #include <pthread.h> | ||||
| 
 | ||||
| #include "common.h" | ||||
| 
 | ||||
| static double | ||||
| get_time_ms(void) | ||||
| { | ||||
| 	struct timespec ts; | ||||
| 	clock_gettime(CLOCK_MONOTONIC, &ts); | ||||
| 	return (double) ts.tv_sec + (double) ts.tv_nsec * 1.0e-9; | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| dummy_work(double ms) | ||||
| { | ||||
| 	double end = get_time_ms() + ms * 1e-3; | ||||
| 	while (get_time_ms() < end); | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| polling_func(void *arg) | ||||
| { | ||||
| 	double ms = *((double *) arg); | ||||
| 	double end = get_time_ms() + ms * 1e-3; | ||||
| 	while (get_time_ms() < end) { | ||||
| 		dummy_work(1.0); /* 1 ms */ | ||||
| 		nanos6_wait_for(1000UL); /* 1 ms */ | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| /* Call the nanos6_spawn_function from an external thread */ | ||||
| static void * | ||||
| spawn(void *arg) | ||||
| { | ||||
| 	double ms = *((double *) arg); | ||||
| 	nanos6_spawn_function(polling_func, &ms, NULL, NULL, "polling_task"); | ||||
| 	return NULL; | ||||
| } | ||||
| 
 | ||||
| int | ||||
| main(void) | ||||
| { | ||||
| 	pthread_t th; | ||||
| 	double T = 100.0; | ||||
| 
 | ||||
| 	if (pthread_create(&th, NULL, spawn, &T) != 0) | ||||
| 		die("pthread_create failed:"); | ||||
| 
 | ||||
| 	if (pthread_join(th, NULL) != 0) | ||||
| 		die("pthread_join failed:"); | ||||
| 
 | ||||
| 	#pragma oss task label("dummy_task") | ||||
| 	dummy_work(T); | ||||
| 
 | ||||
| 	#pragma oss taskwait | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
							
								
								
									
										111
									
								
								test/rt/nanos6/spawn-task-external.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										111
									
								
								test/rt/nanos6/spawn-task-external.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,111 @@ | ||||
| /* Copyright (c) 2023 Barcelona Supercomputing Center (BSC)
 | ||||
|  * SPDX-License-Identifier: GPL-3.0-or-later */ | ||||
| 
 | ||||
| /* Spawn a task from an external thread that calls some nanos6
 | ||||
|  * functions. The external thread must be paused when the task pauses | ||||
|  * the execution. This emulates the same behavior as TAMPI when using a | ||||
|  * polling task. */ | ||||
| 
 | ||||
| #define _GNU_SOURCE | ||||
| 
 | ||||
| #include <nanos6.h> | ||||
| #include <nanos6/library-mode.h> | ||||
| #include <time.h> | ||||
| #include <pthread.h> | ||||
| 
 | ||||
| #include "common.h" | ||||
| #include "compat.h" | ||||
| #include "ovni.h" | ||||
| 
 | ||||
| static double | ||||
| get_time_ms(void) | ||||
| { | ||||
| 	struct timespec ts; | ||||
| 	clock_gettime(CLOCK_MONOTONIC, &ts); | ||||
| 	return (double) ts.tv_sec + (double) ts.tv_nsec * 1.0e-9; | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| dummy_work(double ms) | ||||
| { | ||||
| 	double end = get_time_ms() + ms * 1e-3; | ||||
| 	while (get_time_ms() < end); | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| polling_func(void *arg) | ||||
| { | ||||
| 	double ms = *((double *) arg); | ||||
| 	double end = get_time_ms() + ms * 1e-3; | ||||
| 	while (get_time_ms() < end) { | ||||
| 		dummy_work(1.0); /* 1 ms */ | ||||
| 		nanos6_wait_for(1000UL); /* 1 ms */ | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| static inline void | ||||
| instr_thread_start(int32_t cpu, int32_t creator_tid, uint64_t tag) | ||||
| { | ||||
| 	ovni_thread_init(gettid()); | ||||
| 
 | ||||
| 	struct ovni_ev ev = {0}; | ||||
| 
 | ||||
| 	ovni_ev_set_mcv(&ev, "OHx"); | ||||
| 	ovni_ev_set_clock(&ev, ovni_clock_now()); | ||||
| 	ovni_payload_add(&ev, (uint8_t *) &cpu, sizeof(cpu)); | ||||
| 	ovni_payload_add(&ev, (uint8_t *) &creator_tid, sizeof(creator_tid)); | ||||
| 	ovni_payload_add(&ev, (uint8_t *) &tag, sizeof(tag)); | ||||
| 	ovni_ev_emit(&ev); | ||||
| 
 | ||||
| 	/* Flush the events to disk before killing the thread */ | ||||
| 	ovni_flush(); | ||||
| } | ||||
| 
 | ||||
| static inline void | ||||
| instr_thread_end(void) | ||||
| { | ||||
| 	struct ovni_ev ev = {0}; | ||||
| 
 | ||||
| 	ovni_ev_set_mcv(&ev, "OHe"); | ||||
| 	ovni_ev_set_clock(&ev, ovni_clock_now()); | ||||
| 	ovni_ev_emit(&ev); | ||||
| 
 | ||||
| 	/* Flush the events to disk before killing the thread */ | ||||
| 	ovni_flush(); | ||||
| } | ||||
| 
 | ||||
| /* Call the nanos6_spawn_function from an external thread */ | ||||
| static void * | ||||
| spawn(void *arg) | ||||
| { | ||||
| 	/* Inform ovni of this external thread */ | ||||
| 	instr_thread_start(-1, -1, 0); | ||||
| 
 | ||||
| 	double ms = *((double *) arg); | ||||
| 	nanos6_spawn_function(polling_func, &ms, NULL, NULL, "polling_task"); | ||||
| 
 | ||||
| 	/* Then inform that the thread finishes */ | ||||
| 	instr_thread_end(); | ||||
| 
 | ||||
| 	return NULL; | ||||
| } | ||||
| 
 | ||||
| int | ||||
| main(void) | ||||
| { | ||||
| 	pthread_t th; | ||||
| 	double T = 100.0; | ||||
| 
 | ||||
| 	if (pthread_create(&th, NULL, spawn, &T) != 0) | ||||
| 		die("pthread_create failed:"); | ||||
| 
 | ||||
| 	if (pthread_join(th, NULL) != 0) | ||||
| 		die("pthread_join failed:"); | ||||
| 
 | ||||
| 	#pragma oss task label("dummy_task") | ||||
| 	dummy_work(T); | ||||
| 
 | ||||
| 	#pragma oss taskwait | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
							
								
								
									
										54
									
								
								test/rt/nanos6/spawn-task.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								test/rt/nanos6/spawn-task.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,54 @@ | ||||
| /* Copyright (c) 2023 Barcelona Supercomputing Center (BSC)
 | ||||
|  * SPDX-License-Identifier: GPL-3.0-or-later */ | ||||
| 
 | ||||
| /* Spawn a task from the main thread that calls some nanos6
 | ||||
|  * functions. */ | ||||
| 
 | ||||
| #define _DEFAULT_SOURCE | ||||
| 
 | ||||
| #include <nanos6.h> | ||||
| #include <nanos6/library-mode.h> | ||||
| #include <time.h> | ||||
| 
 | ||||
| #include "common.h" | ||||
| 
 | ||||
| static double | ||||
| get_time_ms(void) | ||||
| { | ||||
| 	struct timespec ts; | ||||
| 	clock_gettime(CLOCK_MONOTONIC, &ts); | ||||
| 	return (double) ts.tv_sec + (double) ts.tv_nsec * 1.0e-9; | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| dummy_work(double ms) | ||||
| { | ||||
| 	double end = get_time_ms() + ms * 1e-3; | ||||
| 	while (get_time_ms() < end); | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| polling_func(void *arg) | ||||
| { | ||||
| 	double ms = *((double *) arg); | ||||
| 	double end = get_time_ms() + ms * 1e-3; | ||||
| 	while (get_time_ms() < end) { | ||||
| 		dummy_work(1.0); /* 1 ms */ | ||||
| 		nanos6_wait_for(1000UL); /* 1 ms */ | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| int | ||||
| main(void) | ||||
| { | ||||
| 	double T = 100.0; | ||||
| 
 | ||||
| 	nanos6_spawn_function(polling_func, &T, NULL, NULL, "polling_task"); | ||||
| 
 | ||||
| 	#pragma oss task label("dummy_task") | ||||
| 	dummy_work(T); | ||||
| 
 | ||||
| 	#pragma oss taskwait | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user