Add virtual events
This commit is contained in:
		
							parent
							
								
									af22678b07
								
							
						
					
					
						commit
						abdbd8d64c
					
				
							
								
								
									
										97
									
								
								emu.c
									
									
									
									
									
								
							
							
						
						
									
										97
									
								
								emu.c
									
									
									
									
									
								
							| @ -82,11 +82,14 @@ hook_pre(struct ovni_emu *emu) | ||||
| 
 | ||||
| 	switch(emu->cur_ev->header.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);
 | ||||
| 		case 'O': hook_pre_ovni(emu); | ||||
| 			  break; | ||||
| 		case 'V': hook_pre_nosv(emu); | ||||
| 			  break; | ||||
| 		case '*': hook_pre_nosv(emu); | ||||
| 			  break; | ||||
| 		default: | ||||
| 			break; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| @ -97,8 +100,12 @@ hook_emit(struct ovni_emu *emu) | ||||
| 
 | ||||
| 	switch(emu->cur_ev->header.model) | ||||
| 	{ | ||||
| 		case 'O': hook_emit_ovni(emu); break; | ||||
| 		case 'V': hook_emit_nosv(emu); break; | ||||
| 		case 'O': hook_emit_ovni(emu); | ||||
| 			  break; | ||||
| 		case 'V': hook_emit_nosv(emu); | ||||
| 			  break; | ||||
| 		case '*': hook_emit_nosv(emu); | ||||
| 			  break; | ||||
| 		default: | ||||
| 			  //dbg("unknown model %c\n", emu->cur_ev->model);
 | ||||
| 			  break; | ||||
| @ -112,8 +119,12 @@ hook_post(struct ovni_emu *emu) | ||||
| 
 | ||||
| 	switch(emu->cur_ev->header.model) | ||||
| 	{ | ||||
| 		case 'O': hook_post_ovni(emu); break; | ||||
| 		case 'V': hook_post_nosv(emu); break; | ||||
| 		case 'O': hook_post_ovni(emu); | ||||
| 			  break; | ||||
| 		case 'V': hook_post_nosv(emu); | ||||
| 			  break; | ||||
| 		case '*': hook_post_nosv(emu); | ||||
| 			  break; | ||||
| 		default: | ||||
| 			  //dbg("unknown model %c\n", emu->cur_ev->model);
 | ||||
| 			  break; | ||||
| @ -143,6 +154,21 @@ next_event(struct ovni_emu *emu) | ||||
| 
 | ||||
| 	trace = &emu->trace; | ||||
| 
 | ||||
| 	/* Look for virtual events first */ | ||||
| 
 | ||||
| 	if(trace->ivirtual < trace->nvirtual) | ||||
| 	{ | ||||
| 		emu->cur_ev = &trace->virtual_events[trace->ivirtual]; | ||||
| 		trace->ivirtual++; | ||||
| 		return 0; | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		/* Reset virtual events to 0 */ | ||||
| 		trace->ivirtual = 0; | ||||
| 		trace->nvirtual = 0; | ||||
| 	} | ||||
| 
 | ||||
| 	f = -1; | ||||
| 	minclock = 0; | ||||
| 
 | ||||
| @ -218,8 +244,9 @@ emulate(struct ovni_emu *emu) | ||||
| 		hook_emit(emu); | ||||
| 		hook_post(emu); | ||||
| 
 | ||||
| 		/* Read the next event */ | ||||
| 		ovni_load_next_event(emu->cur_stream); | ||||
| 		/* Read the next event if no virtual events exist */ | ||||
| 		if(emu->trace.ivirtual == emu->trace.nvirtual) | ||||
| 			ovni_load_next_event(emu->cur_stream); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| @ -587,6 +614,53 @@ write_row_cpu(struct ovni_emu *emu) | ||||
| 	fclose(f); | ||||
| } | ||||
| 
 | ||||
| static int | ||||
| emu_virtual_init(struct ovni_emu *emu) | ||||
| { | ||||
| 	struct ovni_trace *trace; | ||||
| 
 | ||||
| 	trace = &emu->trace; | ||||
| 
 | ||||
| 	trace->ivirtual = 0; | ||||
| 	trace->nvirtual = 0; | ||||
| 
 | ||||
| 	trace->virtual_events = calloc(MAX_VIRTUAL_EVENTS, | ||||
| 			sizeof(struct ovni_ev)); | ||||
| 
 | ||||
| 	if(trace->virtual_events == NULL) | ||||
| 	{ | ||||
| 		perror("calloc"); | ||||
| 		exit(EXIT_FAILURE); | ||||
| 	} | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| void | ||||
| emu_virtual_ev(struct ovni_emu *emu, char *mcv) | ||||
| { | ||||
| 	struct ovni_trace *trace; | ||||
| 	struct ovni_ev *ev; | ||||
| 
 | ||||
| 	trace = &emu->trace; | ||||
| 
 | ||||
| 	if(trace->nvirtual >= MAX_VIRTUAL_EVENTS) | ||||
| 	{ | ||||
| 		err("too many virtual events\n"); | ||||
| 		exit(EXIT_FAILURE); | ||||
| 	} | ||||
| 
 | ||||
| 	ev = &trace->virtual_events[trace->nvirtual]; | ||||
| 
 | ||||
| 	ev->header.flags = 0; | ||||
| 	ev->header.model = mcv[0]; | ||||
| 	ev->header.class = mcv[1]; | ||||
| 	ev->header.value = mcv[2]; | ||||
| 	ev->header.clock = emu->cur_ev->header.clock; | ||||
| 
 | ||||
| 	trace->nvirtual++; | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| emu_init(struct ovni_emu *emu, int argc, char *argv[]) | ||||
| { | ||||
| @ -597,6 +671,9 @@ emu_init(struct ovni_emu *emu, int argc, char *argv[]) | ||||
| 	if(ovni_load_trace(&emu->trace, emu->tracedir)) | ||||
| 		abort(); | ||||
| 
 | ||||
| 	if(emu_virtual_init(emu)) | ||||
| 		abort(); | ||||
| 
 | ||||
| 	if(ovni_load_streams(&emu->trace)) | ||||
| 		abort(); | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										18
									
								
								emu.h
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								emu.h
									
									
									
									
									
								
							| @ -100,6 +100,9 @@ struct ovni_ethread { | ||||
| 
 | ||||
| 	/* nosv task */ | ||||
| 	struct nosv_task *task; | ||||
| 
 | ||||
| 	/* Should we print the subsystem? */ | ||||
| 	int show_ss; | ||||
| }; | ||||
| 
 | ||||
| /* State of each emulated process */ | ||||
| @ -179,9 +182,21 @@ struct ovni_loom { | ||||
| 	struct ovni_eproc proc[OVNI_MAX_PROC]; | ||||
| }; | ||||
| 
 | ||||
| #define MAX_VIRTUAL_EVENTS 16 | ||||
| 
 | ||||
| struct ovni_trace { | ||||
| 	int nlooms; | ||||
| 	struct ovni_loom loom[OVNI_MAX_LOOM]; | ||||
| 
 | ||||
| 	/* Index of next virtual event */ | ||||
| 	int ivirtual; | ||||
| 
 | ||||
| 	/* Number of virtual events stored */ | ||||
| 	int nvirtual; | ||||
| 
 | ||||
| 	/* The virtual events are generated by the emulator */ | ||||
| 	struct ovni_ev *virtual_events; | ||||
| 
 | ||||
| 	int nstreams; | ||||
| 	struct ovni_stream *stream; | ||||
| }; | ||||
| @ -254,4 +269,7 @@ struct ovni_ethread *emu_get_thread(struct ovni_eproc *proc, int tid); | ||||
| 
 | ||||
| void emu_emit_prv(struct ovni_emu *emu, int type, int val); | ||||
| 
 | ||||
| void | ||||
| emu_virtual_ev(struct ovni_emu *emu, char *mcv); | ||||
| 
 | ||||
| #endif /* OVNI_EMU_H */ | ||||
|  | ||||
							
								
								
									
										18
									
								
								emu_nosv.c
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								emu_nosv.c
									
									
									
									
									
								
							| @ -146,7 +146,6 @@ pre_task_end(struct ovni_emu *emu) | ||||
| 	dbg("task id=%d ends\n", task->id); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| static void | ||||
| pre_task(struct ovni_emu *emu) | ||||
| { | ||||
| @ -221,16 +220,23 @@ pre_type(struct ovni_emu *emu) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| void | ||||
| hook_pre_nosv(struct ovni_emu *emu) | ||||
| { | ||||
| 	switch(emu->cur_ev->header.class) | ||||
| 	switch(emu->cur_ev->header.model) | ||||
| 	{ | ||||
| 		case 'T': pre_task(emu); break; | ||||
| 		case 'Y': pre_type(emu); break; | ||||
| 		/* Only listen for nosv events */ | ||||
| 		case 'V': | ||||
| 			switch(emu->cur_ev->header.class) | ||||
| 			{ | ||||
| 				case 'T': pre_task(emu); break; | ||||
| 				case 'Y': pre_type(emu); break; | ||||
| 				default: | ||||
| 					break; | ||||
| 			} | ||||
| 			break; | ||||
| 		default: | ||||
| 			  break; | ||||
| 			break; | ||||
| 	} | ||||
| 
 | ||||
| 	hook_pre_nosv_ss(emu); | ||||
|  | ||||
| @ -19,6 +19,7 @@ static void | ||||
| ss_init(struct ovni_ethread *t) | ||||
| { | ||||
| 	t->nss = 0; | ||||
| 	t->show_ss = 0; | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| @ -134,16 +135,58 @@ pre_memory(struct ovni_emu *emu) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| /* Hook for the virtual "thread changed" event */ | ||||
| static void | ||||
| pre_thread_change(struct ovni_emu *emu) | ||||
| { | ||||
| 	struct ovni_ethread *th; | ||||
| 
 | ||||
| 	th = emu->cur_thread; | ||||
| 
 | ||||
| 	/* Only print the subsystem if the thread is running */ | ||||
| 	if(th->state == TH_ST_RUNNING) | ||||
| 		th->show_ss = 1; | ||||
| 	else | ||||
| 		th->show_ss = 0; | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| pre_thread(struct ovni_emu *emu) | ||||
| { | ||||
| 	switch(emu->cur_ev->header.value) | ||||
| 	{ | ||||
| 		case 'c': pre_thread_change(emu); break; | ||||
| 		default: | ||||
| 			break; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void | ||||
| hook_pre_nosv_ss(struct ovni_emu *emu) | ||||
| { | ||||
| 	switch(emu->cur_ev->header.class) | ||||
| 	switch(emu->cur_ev->header.model) | ||||
| 	{ | ||||
| 		case 'S': pre_sched(emu); break; | ||||
| 		case 'U': pre_submit(emu); break; | ||||
| 		case 'M': pre_memory(emu); break; | ||||
| 		/* Listen for virtual events as well */ | ||||
| 		case '*': | ||||
| 			switch(emu->cur_ev->header.class) | ||||
| 			{ | ||||
| 				case 'H': pre_thread(emu); break; | ||||
| 				default: | ||||
| 					break; | ||||
| 			} | ||||
| 			break; | ||||
| 		case 'V': | ||||
| 			switch(emu->cur_ev->header.class) | ||||
| 			{ | ||||
| 				case 'S': pre_sched(emu); break; | ||||
| 				case 'U': pre_submit(emu); break; | ||||
| 				case 'M': pre_memory(emu); break; | ||||
| 				default: | ||||
| 					break; | ||||
| 			} | ||||
| 			break; | ||||
| 		default: | ||||
| 			  break; | ||||
| 			break; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| @ -187,6 +230,12 @@ hook_emit_nosv_ss(struct ovni_emu *emu) | ||||
| 
 | ||||
| 	th = emu->cur_thread; | ||||
| 
 | ||||
| 	if(th->show_ss == 0) | ||||
| 	{ | ||||
| 		emit_thread_state(emu, th, PTT_SUBSYSTEM, ST_NULL); | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	/* Only emit a state if needed */ | ||||
| 	if(th->ss_event != EV_NULL) | ||||
| 	{ | ||||
|  | ||||
| @ -174,8 +174,14 @@ ev_thread(struct ovni_emu *emu) | ||||
| 		case 'p': ev_thread_pause(emu); break; | ||||
| 		case 'r': ev_thread_resume(emu); break; | ||||
| 		default: | ||||
| 			break; | ||||
| 			  err("unknown thread event value %c\n", | ||||
| 					  ev->header.value); | ||||
| 			  exit(EXIT_FAILURE); | ||||
| 	} | ||||
| 
 | ||||
| 	/* All events change the thread state: inject a virtual event to
 | ||||
| 	 * notify other modules */ | ||||
| 	emu_virtual_ev(emu, "*Hc"); | ||||
| } | ||||
| 
 | ||||
| static void | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user