Add CPU oversubscription test
This commit is contained in:
		
							parent
							
								
									a818795d88
								
							
						
					
					
						commit
						0746d2a0ec
					
				| @ -169,7 +169,7 @@ cpu_update(struct cpu *cpu) | ||||
| 
 | ||||
| 	/* Only virtual cpus can be oversubscribed */ | ||||
| 	if (cpu->nth_running > 1 && !cpu->is_virtual) { | ||||
| 		err("physical cpu %s has %d thread running at the same time", | ||||
| 		err("physical cpu %s has %d threads running at the same time", | ||||
| 				cpu->name, cpu->nth_running); | ||||
| 		return -1; | ||||
| 	} | ||||
|  | ||||
| @ -22,3 +22,4 @@ unit_test(stream.c) | ||||
| unit_test(loom.c) | ||||
| unit_test(thread.c) | ||||
| unit_test(proc.c) | ||||
| unit_test(cpu.c) | ||||
|  | ||||
							
								
								
									
										110
									
								
								test/unit/cpu.c
									
									
									
									
									
								
							
							
						
						
									
										110
									
								
								test/unit/cpu.c
									
									
									
									
									
								
							| @ -1,98 +1,74 @@ | ||||
| #include "emu/bay.h" | ||||
| #include "emu/cpu.h" | ||||
| #include "common.h" | ||||
| 
 | ||||
| static void | ||||
| test_remove(struct bay *bay) | ||||
| test_oversubscription(void) | ||||
| { | ||||
| 	struct chan chan; | ||||
| 	chan_init(&chan, CHAN_SINGLE, "removeme"); | ||||
| 	struct cpu cpu; | ||||
| 
 | ||||
| 	if (bay_register(bay, &chan) != 0) | ||||
| 		die("bay_register failed\n"); | ||||
| 	int phyid = 0; | ||||
| 	cpu_init_begin(&cpu, phyid, 0); | ||||
| 	cpu_set_name(&cpu, "cpu0"); | ||||
| 	cpu_set_gindex(&cpu, 0); | ||||
| 	if (cpu_init_end(&cpu) != 0) | ||||
| 		die("cpu_init_end failed"); | ||||
| 
 | ||||
| 	if (bay_find(bay, chan.name) == NULL) | ||||
| 		die("bay_find failed\n"); | ||||
| 	struct proc proc; | ||||
| 
 | ||||
| 	if (bay_remove(bay, &chan) != 0) | ||||
| 		die("bay_remove failed\n"); | ||||
| 	if (proc_init_begin(&proc, "loom.0/proc.0") != 0) | ||||
| 		die("proc_init_begin failed"); | ||||
| 
 | ||||
| 	if (bay_find(bay, chan.name) != NULL) | ||||
| 		die("bay_find didn't fail\n"); | ||||
| } | ||||
| 	proc_set_gindex(&proc, 0); | ||||
| 
 | ||||
| static void | ||||
| test_duplicate(struct bay *bay) | ||||
| { | ||||
| 	struct chan chan; | ||||
| 	chan_init(&chan, CHAN_SINGLE, "dup"); | ||||
| 	/* FIXME: We shouldn't need to recreate a full process to test the CPU
 | ||||
| 	 * affinity rules */ | ||||
| 	proc.metadata_loaded = 1; | ||||
| 
 | ||||
| 	if (bay_register(bay, &chan) != 0) | ||||
| 		die("bay_register failed\n"); | ||||
| 	if (proc_init_end(&proc) != 0) | ||||
| 		die("proc_init_end failed"); | ||||
| 
 | ||||
| 	if (bay_register(bay, &chan) == 0) | ||||
| 		die("bay_register didn't fail\n"); | ||||
| 	struct thread th0, th1; | ||||
| 
 | ||||
| 	if (bay_remove(bay, &chan) != 0) | ||||
| 		die("bay_remove failed\n"); | ||||
| } | ||||
| 	if (thread_init_begin(&th0, &proc, "loom.0/proc.0/thread.0.ovnistream") != 0) | ||||
| 		die("thread_init_begin failed"); | ||||
| 
 | ||||
| static int | ||||
| callback(struct chan *chan, void *ptr) | ||||
| { | ||||
| 	struct value value; | ||||
| 	if (chan_read(chan, &value) != 0) | ||||
| 		die("callback: chan_read failed\n"); | ||||
| 	thread_set_gindex(&th0, 0); | ||||
| 
 | ||||
| 	if (value.type != VALUE_INT64) | ||||
| 		die("callback: unexpected value type\n"); | ||||
| 	if (thread_init_end(&th0) != 0) | ||||
| 		die("thread_init_end failed"); | ||||
| 
 | ||||
| 	int64_t *ival = ptr; | ||||
| 	*ival = value.i; | ||||
| 	if (thread_init_begin(&th1, &proc, "loom.1/proc.1/thread.1.ovnistream") != 0) | ||||
| 		die("thread_init_begin failed"); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 	thread_set_gindex(&th1, 1); | ||||
| 
 | ||||
| static void | ||||
| test_callback(struct bay *bay) | ||||
| { | ||||
| 	struct chan chan; | ||||
| 	chan_init(&chan, CHAN_SINGLE, "testchan"); | ||||
| 	if (thread_init_end(&th1) != 0) | ||||
| 		die("thread_init_end failed"); | ||||
| 
 | ||||
| 	if (bay_register(bay, &chan) != 0) | ||||
| 		die("bay_register failed\n"); | ||||
| 	if (thread_set_cpu(&th0, &cpu) != 0) | ||||
| 		die("thread_set_cpu failed"); | ||||
| 
 | ||||
| 	int64_t data = 0; | ||||
| 	if (bay_add_cb(bay, BAY_CB_DIRTY, &chan, callback, &data) != 0) | ||||
| 		die("bay_add_cb failed\n"); | ||||
| 	if (thread_set_cpu(&th1, &cpu) != 0) | ||||
| 		die("thread_set_cpu failed"); | ||||
| 
 | ||||
| 	if (data != 0) | ||||
| 		die("data changed after bay_chan_append_cb\n"); | ||||
| 	if (thread_set_state(&th0, TH_ST_RUNNING) != 0) | ||||
| 		die("thread_set_state failed"); | ||||
| 
 | ||||
| 	if (chan_set(&chan, value_int64(1)) != 0) | ||||
| 		die("chan_set failed\n"); | ||||
| 	if (thread_set_state(&th1, TH_ST_RUNNING) != 0) | ||||
| 		die("thread_set_state failed"); | ||||
| 
 | ||||
| 	if (data != 0) | ||||
| 		die("data changed after chan_set\n"); | ||||
| 	if (cpu_add_thread(&cpu, &th0) != 0) | ||||
| 		die("cpu_add_thread failed"); | ||||
| 
 | ||||
| 	/* Now the callback should modify 'data' */ | ||||
| 	if (bay_propagate(bay) != 0) | ||||
| 		die("bay_propagate failed\n"); | ||||
| 	if (cpu_add_thread(&cpu, &th1) == 0) | ||||
| 		die("cpu_add_thread didn't fail"); | ||||
| 
 | ||||
| 	if (data != 1) | ||||
| 		die("data didn't change after bay_propagate\n"); | ||||
| 
 | ||||
| 	if (bay_remove(bay, &chan) != 0) | ||||
| 		die("bay_remove failed\n"); | ||||
| 	err("ok"); | ||||
| } | ||||
| 
 | ||||
| int main(void) | ||||
| { | ||||
| 	struct bay bay; | ||||
| 	bay_init(&bay); | ||||
| 
 | ||||
| 	test_remove(&bay); | ||||
| 	test_duplicate(&bay); | ||||
| 	test_callback(&bay); | ||||
| 	test_oversubscription(); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user