Add nosv task support
This commit is contained in:
		
							parent
							
								
									49198afbca
								
							
						
					
					
						commit
						56c86718fd
					
				
							
								
								
									
										10
									
								
								emu.c
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								emu.c
									
									
									
									
									
								
							| @ -92,6 +92,7 @@ hook_pre(struct ovni_emu *emu) | ||||
| 	switch(emu->cur_ev->model) | ||||
| 	{ | ||||
| 		case 'O': hook_pre_ovni(emu); break; | ||||
| 		case 'V': hook_pre_nosv(emu); break; | ||||
| 		default: | ||||
| 			  //dbg("unknown model %c\n", emu->cur_ev->model);
 | ||||
| 			  break; | ||||
| @ -106,6 +107,7 @@ hook_view(struct ovni_emu *emu) | ||||
| 	switch(emu->cur_ev->model) | ||||
| 	{ | ||||
| 		case 'O': hook_view_ovni(emu); break; | ||||
| 		case 'V': hook_view_nosv(emu); break; | ||||
| 		default: | ||||
| 			  //dbg("unknown model %c\n", emu->cur_ev->model);
 | ||||
| 			  break; | ||||
| @ -144,6 +146,7 @@ next_event(struct ovni_emu *emu) | ||||
| 	struct ovni_ev *ev; | ||||
| 	struct ovni_stream *stream; | ||||
| 	struct ovni_trace *trace; | ||||
| 	static int64_t t0 = -1; | ||||
| 
 | ||||
| 	trace = &emu->trace; | ||||
| 
 | ||||
| @ -184,6 +187,11 @@ next_event(struct ovni_emu *emu) | ||||
| 
 | ||||
| 	emu->lastclock = ovni_ev_get_clock(&stream->last); | ||||
| 
 | ||||
| 	if(t0 < 0) | ||||
| 		t0 = emu->lastclock; | ||||
| 
 | ||||
| 	emu->delta_time = emu->lastclock - t0; | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| @ -272,6 +280,8 @@ main(int argc, char *argv[]) | ||||
| 	if(ovni_load_streams(&emu.trace)) | ||||
| 		return 1; | ||||
| 
 | ||||
| 	printf("#Paraver (19/01/38 at 03:14):00000000000000000000_ns:0:1:1(%d:1)\n", 10); | ||||
| 
 | ||||
| 	emulate(&emu); | ||||
| 
 | ||||
| 	ovni_free_streams(&emu.trace); | ||||
|  | ||||
							
								
								
									
										31
									
								
								emu.h
									
									
									
									
									
								
							
							
						
						
									
										31
									
								
								emu.h
									
									
									
									
									
								
							| @ -2,6 +2,7 @@ | ||||
| #define OVNI_EMU_H | ||||
| 
 | ||||
| #include "ovni.h" | ||||
| #include "uthash.h" | ||||
| #include <stdio.h> | ||||
| 
 | ||||
| /* Debug macros */ | ||||
| @ -24,6 +25,23 @@ enum ethread_state { | ||||
| 	TH_ST_DEAD, | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| enum nosv_task_state { | ||||
| 	TASK_ST_CREATED, | ||||
| 	TASK_ST_RUNNING, | ||||
| 	TASK_ST_PAUSED, | ||||
| 	TASK_ST_DEAD, | ||||
| }; | ||||
| 
 | ||||
| struct ovni_ethread; | ||||
| 
 | ||||
| struct nosv_task { | ||||
| 	int id; | ||||
| 	struct ovni_ethread *thread; | ||||
| 	enum nosv_task_state state; | ||||
| 	UT_hash_handle hh; | ||||
| }; | ||||
| 
 | ||||
| /* State of each emulated thread */ | ||||
| struct ovni_ethread { | ||||
| 	/* Emulated thread tid */ | ||||
| @ -39,6 +57,12 @@ struct ovni_ethread { | ||||
| 
 | ||||
| 	/* Current cpu */ | ||||
| 	struct ovni_cpu *cpu; | ||||
| 
 | ||||
| 	/* FIXME: Use a table with registrable pointers to custom data
 | ||||
| 	 * structures */ | ||||
| 
 | ||||
| 	/* nosv task */ | ||||
| 	struct nosv_task *task; | ||||
| }; | ||||
| 
 | ||||
| /* State of each emulated process */ | ||||
| @ -132,6 +156,9 @@ struct ovni_emu { | ||||
| 	struct ovni_ethread *cur_thread; | ||||
| 
 | ||||
| 	uint64_t lastclock; | ||||
| 	int64_t delta_time; | ||||
| 
 | ||||
| 	struct nosv_task *cur_task; | ||||
| }; | ||||
| 
 | ||||
| /* Emulator function declaration */ | ||||
| @ -142,6 +169,10 @@ void hook_pre_ovni(struct ovni_emu *emu); | ||||
| void hook_view_ovni(struct ovni_emu *emu); | ||||
| void hook_post_ovni(struct ovni_emu *emu); | ||||
| 
 | ||||
| void hook_pre_nosv(struct ovni_emu *emu); | ||||
| void hook_view_nosv(struct ovni_emu *emu); | ||||
| void hook_post_nosv(struct ovni_emu *emu); | ||||
| 
 | ||||
| struct ovni_cpu *emu_get_cpu(struct ovni_emu *emu, int cpuid); | ||||
| 
 | ||||
| struct ovni_ethread *emu_get_thread(struct ovni_emu *emu, int tid); | ||||
|  | ||||
							
								
								
									
										239
									
								
								emu_nosv.c
									
									
									
									
									
								
							
							
						
						
									
										239
									
								
								emu_nosv.c
									
									
									
									
									
								
							| @ -1,13 +1,244 @@ | ||||
| #include "ovni.h" | ||||
| #include "ovni_trace.h" | ||||
| #include "emu.h" | ||||
| #include "uthash.h" | ||||
| #include <assert.h> | ||||
| 
 | ||||
| int | ||||
| emu_nosv_thread_init(struct ovni_emu *emu, struct ovni_ethread *thread) | ||||
| struct nosv_task *tasks = NULL; | ||||
| 
 | ||||
| struct hook_entry { | ||||
| 	char id[4]; | ||||
| 	void (*hook)(struct ovni_emu *); | ||||
| }; | ||||
| 
 | ||||
| static void | ||||
| pre_task_create(struct ovni_emu *emu) | ||||
| { | ||||
| 	struct nosv_task *task, *p = NULL; | ||||
| 	 | ||||
| 	task = malloc(sizeof(*task)); | ||||
| 
 | ||||
| 	if(task == NULL) | ||||
| 	{ | ||||
| 		perror("malloc"); | ||||
| 		abort(); | ||||
| 	} | ||||
| 
 | ||||
| int | ||||
| emu_nosv_process_ev(struct ovni_emu *emu) | ||||
| 	task->id = emu->cur_ev->payload.i32[0]; | ||||
| 	task->state = TASK_ST_CREATED; | ||||
| 
 | ||||
| 	/* Ensure the task id is new */ | ||||
| 	HASH_FIND_INT(tasks, &task->id, p); | ||||
| 
 | ||||
| 	if(p != NULL) | ||||
| 	{ | ||||
| 		err("A task with id %d already exists\n", task->id); | ||||
| 		abort(); | ||||
| 	} | ||||
| 
 | ||||
| 	/* Add the new task to the hash table */ | ||||
| 	HASH_ADD_INT(tasks, id, task); | ||||
| 
 | ||||
| 	emu->cur_task = task; | ||||
| 
 | ||||
| 	dbg("new task created id=%d\n", task->id); | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| pre_task_execute(struct ovni_emu *emu) | ||||
| { | ||||
| 	struct nosv_task *task; | ||||
| 	int taskid; | ||||
| 
 | ||||
| 	taskid = emu->cur_ev->payload.i32[0]; | ||||
| 
 | ||||
| 	HASH_FIND_INT(tasks, &taskid, task); | ||||
| 
 | ||||
| 	assert(task != NULL); | ||||
| 	assert(emu->cur_thread->state == TH_ST_RUNNING); | ||||
| 	assert(emu->cur_thread->task == NULL); | ||||
| 
 | ||||
| 	task->state = TASK_ST_RUNNING; | ||||
| 	task->thread = emu->cur_thread; | ||||
| 	emu->cur_thread->task = task; | ||||
| 
 | ||||
| 	emu->cur_task = task; | ||||
| 
 | ||||
| 	dbg("task id=%d runs now\n", task->id); | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| pre_task_pause(struct ovni_emu *emu) | ||||
| { | ||||
| 	struct nosv_task *task; | ||||
| 	int taskid; | ||||
| 
 | ||||
| 	taskid = emu->cur_ev->payload.i32[0]; | ||||
| 
 | ||||
| 	HASH_FIND_INT(tasks, &taskid, task); | ||||
| 
 | ||||
| 	assert(task != NULL); | ||||
| 	assert(task->state == TASK_ST_RUNNING); | ||||
| 	assert(emu->cur_thread->state == TH_ST_RUNNING); | ||||
| 	assert(emu->cur_thread->task == task); | ||||
| 	assert(emu->cur_thread == task->thread); | ||||
| 
 | ||||
| 	task->state = TASK_ST_PAUSED; | ||||
| 
 | ||||
| 	emu->cur_task = task; | ||||
| 
 | ||||
| 	dbg("task id=%d pauses\n", task->id); | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| pre_task_resume(struct ovni_emu *emu) | ||||
| { | ||||
| 	struct nosv_task *task; | ||||
| 	int taskid; | ||||
| 
 | ||||
| 	taskid = emu->cur_ev->payload.i32[0]; | ||||
| 
 | ||||
| 	HASH_FIND_INT(tasks, &taskid, task); | ||||
| 
 | ||||
| 	assert(task != NULL); | ||||
| 	assert(task->state == TASK_ST_PAUSED); | ||||
| 	assert(emu->cur_thread->state == TH_ST_RUNNING); | ||||
| 	assert(emu->cur_thread->task == task); | ||||
| 	assert(emu->cur_thread == task->thread); | ||||
| 
 | ||||
| 	task->state = TASK_ST_RUNNING; | ||||
| 
 | ||||
| 	emu->cur_task = task; | ||||
| 
 | ||||
| 	dbg("task id=%d resumes\n", task->id); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| static void | ||||
| pre_task_end(struct ovni_emu *emu) | ||||
| { | ||||
| 	struct nosv_task *task; | ||||
| 	int taskid; | ||||
| 
 | ||||
| 	taskid = emu->cur_ev->payload.i32[0]; | ||||
| 
 | ||||
| 	/* Ensure the task id is new */ | ||||
| 	HASH_FIND_INT(tasks, &taskid, task); | ||||
| 
 | ||||
| 	assert(task != NULL); | ||||
| 	assert(task->state == TASK_ST_RUNNING); | ||||
| 	assert(emu->cur_thread->state == TH_ST_RUNNING); | ||||
| 	assert(emu->cur_thread->task == task); | ||||
| 	assert(emu->cur_thread == task->thread); | ||||
| 
 | ||||
| 	task->state = TASK_ST_DEAD; | ||||
| 	task->thread = NULL; | ||||
| 	emu->cur_thread->task = NULL; | ||||
| 
 | ||||
| 	emu->cur_task = task; | ||||
| 
 | ||||
| 	dbg("task id=%d ends\n", task->id); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| static void | ||||
| pre_task(struct ovni_emu *emu) | ||||
| { | ||||
| 	emu_emit(emu); | ||||
| 	switch(emu->cur_ev->value) | ||||
| 	{ | ||||
| 		case 'c': pre_task_create(emu); break; | ||||
| 		case 'x': pre_task_execute(emu); break; | ||||
| 		case 'e': pre_task_end(emu); break; | ||||
| 		case 'p': pre_task_pause(emu); break; | ||||
| 		case 'r': pre_task_resume(emu); break; | ||||
| 		default: | ||||
| 			  emu->cur_task = NULL; | ||||
| 			  break; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void | ||||
| hook_pre_nosv(struct ovni_emu *emu) | ||||
| { | ||||
| 	dbg("pre nosv\n"); | ||||
| 	switch(emu->cur_ev->class) | ||||
| 	{ | ||||
| 		case 'T': pre_task(emu); break; | ||||
| 		default: | ||||
| 			  break; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| /* --------------------------- views ------------------------------- */ | ||||
| 
 | ||||
| static void | ||||
| emit_prv(struct ovni_emu *emu, int type, int val) | ||||
| { | ||||
| 	printf("2:0:1:1:%d:%ld:%d:%d\n", | ||||
| 			emu->cur_thread->cpu->cpu_id + 2, | ||||
| 			emu->delta_time, | ||||
| 			type, val); | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| emit_task_create(struct ovni_emu *emu) | ||||
| { | ||||
| 	//emit_prv(emu, 200, emu->cur_task->id);
 | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| emit_task_execute(struct ovni_emu *emu) | ||||
| { | ||||
| 	emit_prv(emu, 200, emu->cur_task->id + 1); | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| emit_task_pause(struct ovni_emu *emu) | ||||
| { | ||||
| 	emit_prv(emu, 200, 0); | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| emit_task_resume(struct ovni_emu *emu) | ||||
| { | ||||
| 	emit_prv(emu, 200, emu->cur_task->id + 1); | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| emit_task_end(struct ovni_emu *emu) | ||||
| { | ||||
| 	emit_prv(emu, 200, 0); | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| emit_task(struct ovni_emu *emu) | ||||
| { | ||||
| 	switch(emu->cur_ev->value) | ||||
| 	{ | ||||
| 		case 'c': emit_task_create(emu); break; | ||||
| 		case 'x': emit_task_execute(emu); break; | ||||
| 		case 'p': emit_task_pause(emu); break; | ||||
| 		case 'r': emit_task_resume(emu); break; | ||||
| 		case 'e': emit_task_end(emu); break; | ||||
| 		default: | ||||
| 			break; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void | ||||
| hook_view_nosv(struct ovni_emu *emu) | ||||
| { | ||||
| 	dbg("pre nosv\n"); | ||||
| 	switch(emu->cur_ev->class) | ||||
| 	{ | ||||
| 		case 'T': emit_task(emu); break; | ||||
| 		default: | ||||
| 			break; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| struct hook_entry pre_hooks[] = { | ||||
| 	{ "VTc", pre_task_create }, | ||||
| 	{ "VTx", pre_task_create }, | ||||
| }; | ||||
|  | ||||
							
								
								
									
										49
									
								
								emu_ovni.c
									
									
									
									
									
								
							
							
						
						
									
										49
									
								
								emu_ovni.c
									
									
									
									
									
								
							| @ -100,8 +100,8 @@ ev_thread_execute(struct ovni_emu *emu) | ||||
| 	assert(emu->cur_thread->state != TH_ST_RUNNING); | ||||
| 
 | ||||
| 	cpuid = emu->cur_ev->payload.i32[0]; | ||||
| 	dbg("thread %d runs in cpuid %d\n", emu->cur_thread->tid, | ||||
| 			cpuid); | ||||
| 	//dbg("thread %d runs in cpuid %d\n", emu->cur_thread->tid,
 | ||||
| 	//		cpuid);
 | ||||
| 	cpu = emu_get_cpu(emu, cpuid); | ||||
| 
 | ||||
| 	emu->cur_thread->state = TH_ST_RUNNING; | ||||
| @ -152,7 +152,7 @@ ev_thread(struct ovni_emu *emu) | ||||
| 	struct ovni_ethread *thread, *remote_thread; | ||||
| 	int i; | ||||
| 
 | ||||
| 	emu_emit(emu); | ||||
| 	//emu_emit(emu);
 | ||||
| 
 | ||||
| 	thread = emu->cur_thread; | ||||
| 	cpu = thread->cpu; | ||||
| @ -196,7 +196,7 @@ ev_affinity_set(struct ovni_emu *emu) | ||||
| 
 | ||||
| 	emu->cur_thread->cpu = newcpu; | ||||
| 
 | ||||
| 	dbg("cpu %d now runs %d\n", cpuid, emu->cur_thread->tid); | ||||
| 	//dbg("cpu %d now runs %d\n", cpuid, emu->cur_thread->tid);
 | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| @ -223,14 +223,14 @@ ev_affinity_remote(struct ovni_emu *emu) | ||||
| 
 | ||||
| 	thread->cpu = newcpu; | ||||
| 
 | ||||
| 	dbg("thread %d switches to cpu %d by remote petition\n", tid, | ||||
| 			cpuid); | ||||
| 	//dbg("thread %d switches to cpu %d by remote petition\n", tid,
 | ||||
| 	//		cpuid);
 | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| ev_affinity(struct ovni_emu *emu) | ||||
| { | ||||
| 	emu_emit(emu); | ||||
| 	//emu_emit(emu);
 | ||||
| 	switch(emu->cur_ev->value) | ||||
| 	{ | ||||
| 		case 's': ev_affinity_set(emu); break; | ||||
| @ -322,27 +322,46 @@ hook_pre_ovni(struct ovni_emu *emu) | ||||
| 			break; | ||||
| 	} | ||||
| 
 | ||||
| 	print_threads_state(emu); | ||||
| 	//print_threads_state(emu);
 | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| view_thread_count(struct ovni_emu *emu) | ||||
| { | ||||
| 	int i; | ||||
| 	int i, n, cpu = -1; | ||||
| 	int64_t delta_time; | ||||
| 	static int64_t t0 = -1; | ||||
| 
 | ||||
| 	if(t0 < 0) | ||||
| 		t0 = ovni_ev_get_clock(emu->cur_ev); | ||||
| 
 | ||||
| 	delta_time = ovni_ev_get_clock(emu->cur_ev) - t0; | ||||
| 
 | ||||
| 	/* Check every CPU looking for a change in nthreads */ | ||||
| 	for(i=0; i<emu->ncpus; i++) | ||||
| 	{ | ||||
| 		if(emu->cpu[i].last_nthreads == emu->cpu[i].nthreads) | ||||
| 			continue; | ||||
| 
 | ||||
| 		/* Emit the number of threads in the cpu */ | ||||
| 		dbg("cpu %d runs %d threads\n", i, emu->cpu[i].nthreads); | ||||
| 		if(emu->cpu[i].last_nthreads != emu->cpu[i].nthreads) | ||||
| 		{ | ||||
| 			cpu = i + 1; | ||||
| 			n = emu->cpu[i].nthreads; | ||||
| 			goto emit; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	/* Same with the virtual CPU */ | ||||
| 	if(emu->vcpu.last_nthreads != emu->vcpu.nthreads) | ||||
| 		dbg("vpu runs %d threads\n", emu->vcpu.nthreads); | ||||
| 	{ | ||||
| 		cpu = 0; | ||||
| 		n = emu->vcpu.nthreads; | ||||
| 		goto emit; | ||||
| 	} | ||||
| 
 | ||||
| 	return; | ||||
| 
 | ||||
| emit: | ||||
| 
 | ||||
| 	printf("2:0:1:1:%d:%ld:100:%d\n", | ||||
| 			cpu+1, delta_time, n); | ||||
| } | ||||
| 
 | ||||
| void | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user