Distribute emulator into modules
This commit is contained in:
		
							parent
							
								
									cfc4eb7527
								
							
						
					
					
						commit
						d25bbed350
					
				
							
								
								
									
										13
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								Makefile
									
									
									
									
									
								
							| @ -3,15 +3,14 @@ CFLAGS=-fPIC | |||||||
| # Debug CFLAGS
 | # Debug CFLAGS
 | ||||||
| #CFLAGS+=-fsanitize=address
 | #CFLAGS+=-fsanitize=address
 | ||||||
| #LDFLAGS+=-fsanitize=address
 | #LDFLAGS+=-fsanitize=address
 | ||||||
| #CFLAGS+=-g -O0
 | CFLAGS+=-g -O0 | ||||||
| 
 | 
 | ||||||
| # Performance CFLAGS
 | # Performance CFLAGS
 | ||||||
| CFLAGS+=-O3 | #CFLAGS+=-O3
 | ||||||
| CFLAGS+=-fstack-protector-explicit | #CFLAGS+=-fstack-protector-explicit
 | ||||||
| CFLAGS+=-flto | #CFLAGS+=-flto
 | ||||||
| 
 | 
 | ||||||
| BIN=dump libovni.a test_speed ovni2prv | BIN=dump libovni.a test_speed ovni2prv emu | ||||||
| #BIN=dump libovni.a prvth test_speed emu
 |  | ||||||
| 
 | 
 | ||||||
| all: $(BIN) | all: $(BIN) | ||||||
| 
 | 
 | ||||||
| @ -22,7 +21,7 @@ dump: ovni.o dump.o | |||||||
| 
 | 
 | ||||||
| test_speed: test_speed.c ovni.o | test_speed: test_speed.c ovni.o | ||||||
| 
 | 
 | ||||||
| emu: emu.c ovni.o | emu: emu.o emu_ovni.o emu_nosv.o ovni.o | ||||||
| 
 | 
 | ||||||
| ovni2prv: ovni2prv.c ovni.o | ovni2prv: ovni2prv.c ovni.o | ||||||
| 
 | 
 | ||||||
|  | |||||||
							
								
								
									
										4
									
								
								dump.c
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								dump.c
									
									
									
									
									
								
							| @ -9,6 +9,8 @@ | |||||||
| #include <dirent.h>  | #include <dirent.h>  | ||||||
| 
 | 
 | ||||||
| #include "ovni.h" | #include "ovni.h" | ||||||
|  | #include "ovni_trace.h" | ||||||
|  | #include "emu.h" | ||||||
| 
 | 
 | ||||||
| #define ENABLE_DEBUG | #define ENABLE_DEBUG | ||||||
| 
 | 
 | ||||||
| @ -58,7 +60,7 @@ void emit(struct ovni_stream *stream, struct ovni_ev *ev) | |||||||
| 	payloadsize = ovni_payload_size(ev); | 	payloadsize = ovni_payload_size(ev); | ||||||
| 	for(i=0; i<payloadsize; i++) | 	for(i=0; i<payloadsize; i++) | ||||||
| 	{ | 	{ | ||||||
| 		printf("%d ", ev->payload.payload_u8[i]); | 		printf("%02x ", ev->payload.u8[i]); | ||||||
| 	} | 	} | ||||||
| 	printf("\n"); | 	printf("\n"); | ||||||
| 
 | 
 | ||||||
|  | |||||||
							
								
								
									
										312
									
								
								emu.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										312
									
								
								emu.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,312 @@ | |||||||
|  | #include <stdio.h> | ||||||
|  | #include <stdint.h> | ||||||
|  | #include <stdlib.h> | ||||||
|  | #include <string.h> | ||||||
|  | #include <linux/limits.h> | ||||||
|  | #include <errno.h> | ||||||
|  | #include <sys/stat.h> | ||||||
|  | #include <stdatomic.h> | ||||||
|  | #include <dirent.h>  | ||||||
|  | #include <assert.h>  | ||||||
|  | 
 | ||||||
|  | #include "ovni.h" | ||||||
|  | #include "ovni_trace.h" | ||||||
|  | #include "emu.h" | ||||||
|  | 
 | ||||||
|  | static void | ||||||
|  | emit_ev(struct ovni_stream *stream, struct ovni_ev *ev) | ||||||
|  | { | ||||||
|  | 	int64_t delta; | ||||||
|  | 	uint64_t clock; | ||||||
|  | 	int i, payloadsize; | ||||||
|  | 
 | ||||||
|  | 	//dbg("sizeof(*ev) = %d\n", sizeof(*ev));
 | ||||||
|  | 	//hexdump((uint8_t *) ev, sizeof(*ev));
 | ||||||
|  | 
 | ||||||
|  | 	clock = ovni_ev_get_clock(ev); | ||||||
|  | 
 | ||||||
|  | 	delta = clock - stream->lastclock; | ||||||
|  | 
 | ||||||
|  | 	dbg("%d.%d.%d %c %c %c % 20lu % 15ld ", | ||||||
|  | 			stream->loom, stream->proc, stream->tid, | ||||||
|  | 			ev->model, ev->class, ev->value, clock, delta); | ||||||
|  | 
 | ||||||
|  | 	payloadsize = ovni_payload_size(ev); | ||||||
|  | 	for(i=0; i<payloadsize; i++) | ||||||
|  | 	{ | ||||||
|  | 		dbg("%d ", ev->payload.u8[i]); | ||||||
|  | 	} | ||||||
|  | 	dbg("\n"); | ||||||
|  | 
 | ||||||
|  | 	stream->lastclock = clock; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void | ||||||
|  | emu_emit(struct ovni_emu *emu) | ||||||
|  | { | ||||||
|  | 	emit_ev(emu->cur_stream, emu->cur_ev); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void | ||||||
|  | load_first_event(struct ovni_stream *stream) | ||||||
|  | { | ||||||
|  | 	int i; | ||||||
|  | 	size_t n; | ||||||
|  | 	struct ovni_ev *ev; | ||||||
|  | 
 | ||||||
|  | 	if(!stream->active) | ||||||
|  | 		return; | ||||||
|  | 
 | ||||||
|  | 	ev = &stream->last; | ||||||
|  | 	if((n = fread(ev, sizeof(*ev), 1, stream->f)) != 1) | ||||||
|  | 	{ | ||||||
|  | 		//fprintf(stderr, "failed to read an event, n=%ld\n", n);
 | ||||||
|  | 		stream->active = 0; | ||||||
|  | 		return; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	stream->active = 1; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | struct ovni_ethread * | ||||||
|  | find_thread(struct ovni_eproc *proc, pid_t tid) | ||||||
|  | { | ||||||
|  | 	int i; | ||||||
|  | 	struct ovni_ethread *thread; | ||||||
|  | 
 | ||||||
|  | 	for(i=0; i<proc->nthreads; i++) | ||||||
|  | 	{ | ||||||
|  | 		thread = &proc->thread[i]; | ||||||
|  | 		if(thread->tid == tid) | ||||||
|  | 			return thread; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return NULL; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void | ||||||
|  | step_emulator(struct ovni_emu *emu) | ||||||
|  | { | ||||||
|  | 	//emu_emit(emu);
 | ||||||
|  | 
 | ||||||
|  | 	switch(emu->cur_ev->model) | ||||||
|  | 	{ | ||||||
|  | 		case 'O': emu_process_ovni_ev(emu); break; | ||||||
|  | 		//case 'V': emu_process_nosv_ev(emu); break;
 | ||||||
|  | 		//case 'M': emu_process_tampi_ev(emu); break;
 | ||||||
|  | 		default: | ||||||
|  | 			  //dbg("unknown model %c\n", emu->cur_ev->model);
 | ||||||
|  | 			  break; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void | ||||||
|  | set_current(struct ovni_emu *emu, struct ovni_stream *stream) | ||||||
|  | { | ||||||
|  | 	emu->cur_stream = stream; | ||||||
|  | 	emu->cur_ev = &stream->last; | ||||||
|  | 	emu->cur_loom = &emu->trace.loom[stream->loom]; | ||||||
|  | 	emu->cur_proc = &emu->cur_loom->proc[stream->proc]; | ||||||
|  | 	emu->cur_thread = &emu->cur_proc->thread[stream->thread]; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static int | ||||||
|  | next_event(struct ovni_emu *emu) | ||||||
|  | { | ||||||
|  | 	int i, f; | ||||||
|  | 	uint64_t minclock; | ||||||
|  | 	struct ovni_ev *ev; | ||||||
|  | 	struct ovni_stream *stream; | ||||||
|  | 	struct ovni_trace *trace; | ||||||
|  | 
 | ||||||
|  | 	trace = &emu->trace; | ||||||
|  | 
 | ||||||
|  | 	f = -1; | ||||||
|  | 	minclock = 0; | ||||||
|  | 
 | ||||||
|  | 	/* TODO: use a heap */ | ||||||
|  | 
 | ||||||
|  | 	/* Select next event based on the clock */ | ||||||
|  | 	for(i=0; i<trace->nstreams; i++) | ||||||
|  | 	{ | ||||||
|  | 		stream = &trace->stream[i]; | ||||||
|  | 
 | ||||||
|  | 		if(!stream->active) | ||||||
|  | 			continue; | ||||||
|  | 
 | ||||||
|  | 		ev = &stream->last; | ||||||
|  | 		if(f < 0 || ovni_ev_get_clock(ev) < minclock) | ||||||
|  | 		{ | ||||||
|  | 			f = i; | ||||||
|  | 			minclock = ovni_ev_get_clock(ev); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if(f < 0) | ||||||
|  | 		return -1; | ||||||
|  | 
 | ||||||
|  | 	/* We have a valid stream with a new event */ | ||||||
|  | 	stream = &trace->stream[f]; | ||||||
|  | 
 | ||||||
|  | 	set_current(emu, stream); | ||||||
|  | 
 | ||||||
|  | 	if(emu->lastclock > ovni_ev_get_clock(&stream->last)) | ||||||
|  | 	{ | ||||||
|  | 		fprintf(stdout, "warning: backwards jump in time %lu -> %lu\n", | ||||||
|  | 				emu->lastclock, ovni_ev_get_clock(&stream->last)); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	emu->lastclock = ovni_ev_get_clock(&stream->last); | ||||||
|  | 
 | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void | ||||||
|  | emulate(struct ovni_emu *emu) | ||||||
|  | { | ||||||
|  | 	int i; | ||||||
|  | 	struct ovni_ev ev; | ||||||
|  | 	struct ovni_stream *stream; | ||||||
|  | 	struct ovni_trace *trace; | ||||||
|  | 
 | ||||||
|  | 	/* Load events */ | ||||||
|  | 	trace = &emu->trace; | ||||||
|  | 	for(i=0; i<trace->nstreams; i++) | ||||||
|  | 	{ | ||||||
|  | 		stream = &trace->stream[i]; | ||||||
|  | 		ovni_load_next_event(stream); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	emu->lastclock = 0; | ||||||
|  | 
 | ||||||
|  | 	/* Then process all events */ | ||||||
|  | 	while(next_event(emu) == 0) | ||||||
|  | 	{ | ||||||
|  | 		//fprintf(stdout, "step %i\n", i);
 | ||||||
|  | 		step_emulator(emu); | ||||||
|  | 
 | ||||||
|  | 		/* Read the next event */ | ||||||
|  | 		ovni_load_next_event(emu->cur_stream); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | int | ||||||
|  | emu_cpu_find_thread(struct ovni_cpu *cpu, struct ovni_ethread *thread) | ||||||
|  | { | ||||||
|  | 	int i; | ||||||
|  | 
 | ||||||
|  | 	for(i=0; i<cpu->nthreads; i++) | ||||||
|  | 		if(cpu->thread[i] == thread) | ||||||
|  | 			break; | ||||||
|  | 
 | ||||||
|  | 	/* Not found */ | ||||||
|  | 	if(i >= cpu->nthreads) | ||||||
|  | 		return -1; | ||||||
|  | 
 | ||||||
|  | 	return i; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void | ||||||
|  | emu_cpu_remove_thread(struct ovni_cpu *cpu, struct ovni_ethread *thread) | ||||||
|  | { | ||||||
|  | 	int i, j; | ||||||
|  | 
 | ||||||
|  | 	i = emu_cpu_find_thread(cpu, thread); | ||||||
|  | 
 | ||||||
|  | 	/* Not found, abort */ | ||||||
|  | 	if(i < 0) | ||||||
|  | 		abort(); | ||||||
|  | 
 | ||||||
|  | 	for(j=i; j+1 < cpu->nthreads; j++) | ||||||
|  | 	{ | ||||||
|  | 		cpu->thread[i] = cpu->thread[j+1]; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	cpu->nthreads--; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void | ||||||
|  | emu_cpu_add_thread(struct ovni_cpu *cpu, struct ovni_ethread *thread) | ||||||
|  | { | ||||||
|  | 	/* Found, abort */ | ||||||
|  | 	if(emu_cpu_find_thread(cpu, thread) >= 0) | ||||||
|  | 		abort(); | ||||||
|  | 
 | ||||||
|  | 	assert(cpu->nthreads < OVNI_MAX_THR); | ||||||
|  | 
 | ||||||
|  | 	cpu->thread[cpu->nthreads++] = thread; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | struct ovni_cpu * | ||||||
|  | emu_get_cpu(struct ovni_emu *emu, int cpuid) | ||||||
|  | { | ||||||
|  | 	assert(cpuid < OVNI_MAX_CPU); | ||||||
|  | 
 | ||||||
|  | 	if(cpuid < 0) | ||||||
|  | 	{ | ||||||
|  | 		return &emu->vcpu; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return &emu->cpu[emu->cpuind[cpuid]]; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | struct ovni_ethread * | ||||||
|  | emu_get_thread(struct ovni_emu *emu, int tid) | ||||||
|  | { | ||||||
|  | 	int i, j, k; | ||||||
|  | 	struct ovni_loom *loom; | ||||||
|  | 	struct ovni_eproc *proc; | ||||||
|  | 	struct ovni_ethread *thread; | ||||||
|  | 
 | ||||||
|  | 	for(i=0; i<emu->trace.nlooms; i++) | ||||||
|  | 	{ | ||||||
|  | 		loom = &emu->trace.loom[i]; | ||||||
|  | 		for(j=0; j<loom->nprocs; j++) | ||||||
|  | 		{ | ||||||
|  | 			proc = &loom->proc[j]; | ||||||
|  | 			for(k=0; k<proc->nthreads; k++) | ||||||
|  | 			{ | ||||||
|  | 				thread = &proc->thread[k]; | ||||||
|  | 				if(thread->tid == tid) | ||||||
|  | 				{ | ||||||
|  | 					/* Only same process threads can
 | ||||||
|  | 					 * change the affinity to each | ||||||
|  | 					 * others */ | ||||||
|  | 					assert(emu->cur_proc == proc); | ||||||
|  | 					return thread; | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return thread; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | int | ||||||
|  | main(int argc, char *argv[]) | ||||||
|  | { | ||||||
|  | 	char *tracedir; | ||||||
|  | 	struct ovni_emu emu; | ||||||
|  | 
 | ||||||
|  | 	if(argc != 2) | ||||||
|  | 	{ | ||||||
|  | 		fprintf(stderr, "missing tracedir\n"); | ||||||
|  | 		exit(EXIT_FAILURE); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	tracedir = argv[1]; | ||||||
|  | 
 | ||||||
|  | 	memset(&emu, 0, sizeof(emu)); | ||||||
|  | 
 | ||||||
|  | 	if(ovni_load_trace(&emu.trace, tracedir)) | ||||||
|  | 		return 1; | ||||||
|  | 
 | ||||||
|  | 	if(ovni_load_streams(&emu.trace)) | ||||||
|  | 		return 1; | ||||||
|  | 
 | ||||||
|  | 	emulate(&emu); | ||||||
|  | 
 | ||||||
|  | 	ovni_free_streams(&emu.trace); | ||||||
|  | 
 | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
							
								
								
									
										151
									
								
								emu.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										151
									
								
								emu.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,151 @@ | |||||||
|  | #ifndef OVNI_EMU_H | ||||||
|  | #define OVNI_EMU_H | ||||||
|  | 
 | ||||||
|  | #include "ovni.h" | ||||||
|  | #include <stdio.h> | ||||||
|  | 
 | ||||||
|  | /* Debug macros */ | ||||||
|  | 
 | ||||||
|  | #define ENABLE_DEBUG | ||||||
|  | 
 | ||||||
|  | #ifdef ENABLE_DEBUG | ||||||
|  | # define dbg(...) fprintf(stderr, __VA_ARGS__); | ||||||
|  | #else | ||||||
|  | # define dbg(...) | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #define err(...) fprintf(stderr, __VA_ARGS__); | ||||||
|  | 
 | ||||||
|  | /* Emulated thread runtime status */ | ||||||
|  | enum ethread_state { | ||||||
|  | 	TH_ST_UNKNOWN, | ||||||
|  | 	TH_ST_RUNNING, | ||||||
|  | 	TH_ST_PAUSED, | ||||||
|  | 	TH_ST_DEAD, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /* State of each emulated thread */ | ||||||
|  | struct ovni_ethread { | ||||||
|  | 	/* Emulated thread tid */ | ||||||
|  | 	pid_t tid; | ||||||
|  | 
 | ||||||
|  | 	/* Stream file */ | ||||||
|  | 	FILE *f; | ||||||
|  | 
 | ||||||
|  | 	enum ethread_state state; | ||||||
|  | 
 | ||||||
|  | 	/* Thread stream */ | ||||||
|  | 	struct ovni_stream *stream; | ||||||
|  | 
 | ||||||
|  | 	/* Current cpu */ | ||||||
|  | 	struct ovni_cpu *cpu; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /* State of each emulated process */ | ||||||
|  | struct ovni_eproc { | ||||||
|  | 	/* Monotonic counter for process index */ | ||||||
|  | 	/* TODO: Use pid? */ | ||||||
|  | 	int proc; | ||||||
|  | 
 | ||||||
|  | 	/* Path of the process tracedir */ | ||||||
|  | 	char dir[PATH_MAX]; | ||||||
|  | 
 | ||||||
|  | 	/* Threads */ | ||||||
|  | 	size_t nthreads; | ||||||
|  | 	struct ovni_ethread thread[OVNI_MAX_THR]; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /* ----------------------- trace ------------------------ */ | ||||||
|  | 
 | ||||||
|  | /* State of each loom on post-process */ | ||||||
|  | struct ovni_loom { | ||||||
|  | 	size_t nprocs; | ||||||
|  | 	struct ovni_eproc proc[OVNI_MAX_PROC]; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | struct ovni_stream { | ||||||
|  | 	FILE *f; | ||||||
|  | 	int tid; | ||||||
|  | 	int thread; | ||||||
|  | 	int proc; | ||||||
|  | 	int loom; | ||||||
|  | 	int loaded; | ||||||
|  | 	int active; | ||||||
|  | 	struct ovni_ev last; | ||||||
|  | 	uint64_t lastclock; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | struct ovni_trace { | ||||||
|  | 	int nlooms; | ||||||
|  | 	struct ovni_loom loom[OVNI_MAX_LOOM]; | ||||||
|  | 	int nstreams; | ||||||
|  | 	struct ovni_stream *stream; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /* ------------------ emulation ---------------- */ | ||||||
|  | 
 | ||||||
|  | enum ovni_cpu_type { | ||||||
|  | 	CPU_REAL, | ||||||
|  | 	CPU_VIRTUAL, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | enum ovni_cpu_state { | ||||||
|  | 	CPU_ST_UNKNOWN, | ||||||
|  | 	CPU_ST_READY, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | struct ovni_cpu { | ||||||
|  | 	/* Physical id */ | ||||||
|  | 	int cpu_id; | ||||||
|  | 
 | ||||||
|  | 	/* Position in emu->cpu */ | ||||||
|  | 	int index; | ||||||
|  | 
 | ||||||
|  | 	enum ovni_cpu_state state; | ||||||
|  | 	enum ovni_cpu_type type; | ||||||
|  | 
 | ||||||
|  | 	/* The threads the cpu is currently running */ | ||||||
|  | 	size_t nthreads; | ||||||
|  | 	struct ovni_ethread *thread[OVNI_MAX_THR]; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | struct ovni_emu { | ||||||
|  | 	struct ovni_trace trace; | ||||||
|  | 
 | ||||||
|  | 	/* Physical CPUs */ | ||||||
|  | 	int max_ncpus; | ||||||
|  | 	int ncpus; | ||||||
|  | 	struct ovni_cpu cpu[OVNI_MAX_CPU]; | ||||||
|  | 	int cpuind[OVNI_MAX_CPU]; | ||||||
|  | 
 | ||||||
|  | 	/* Virtual CPU */ | ||||||
|  | 	struct ovni_cpu vcpu; | ||||||
|  | 
 | ||||||
|  | 	struct ovni_stream *cur_stream; | ||||||
|  | 	struct ovni_ev *cur_ev; | ||||||
|  | 
 | ||||||
|  | 	struct ovni_loom *cur_loom; | ||||||
|  | 	struct ovni_eproc *cur_proc; | ||||||
|  | 	struct ovni_ethread *cur_thread; | ||||||
|  | 
 | ||||||
|  | 	uint64_t lastclock; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /* Emulator function declaration */ | ||||||
|  | 
 | ||||||
|  | void emu_emit(struct ovni_emu *emu); | ||||||
|  | void emu_process_ovni_ev(struct ovni_emu *emu); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | int emu_cpu_find_thread(struct ovni_cpu *cpu, struct ovni_ethread *thread); | ||||||
|  | 
 | ||||||
|  | void emu_cpu_remove_thread(struct ovni_cpu *cpu, struct ovni_ethread *thread); | ||||||
|  | 
 | ||||||
|  | void emu_cpu_add_thread(struct ovni_cpu *cpu, struct ovni_ethread *thread); | ||||||
|  | 
 | ||||||
|  | struct ovni_cpu *emu_get_cpu(struct ovni_emu *emu, int cpuid); | ||||||
|  | 
 | ||||||
|  | struct ovni_ethread *emu_get_thread(struct ovni_emu *emu, int tid); | ||||||
|  | 
 | ||||||
|  | #endif /* OVNI_EMU_H */ | ||||||
							
								
								
									
										13
									
								
								emu_nosv.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								emu_nosv.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,13 @@ | |||||||
|  | #include "ovni.h" | ||||||
|  | #include "ovni_trace.h" | ||||||
|  | #include "emu.h" | ||||||
|  | 
 | ||||||
|  | int | ||||||
|  | emu_nosv_thread_init(struct ovni_emu *emu, struct ovni_ethread *thread) | ||||||
|  | { | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | int | ||||||
|  | emu_nosv_process_ev(struct ovni_emu *emu) | ||||||
|  | { | ||||||
|  | } | ||||||
							
								
								
									
										265
									
								
								emu_ovni.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										265
									
								
								emu_ovni.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,265 @@ | |||||||
|  | #include "ovni.h" | ||||||
|  | #include "emu.h" | ||||||
|  | 
 | ||||||
|  | #include <assert.h> | ||||||
|  | 
 | ||||||
|  | static void | ||||||
|  | print_threads_state(struct ovni_emu *emu) | ||||||
|  | { | ||||||
|  | 	struct ovni_cpu *cpu; | ||||||
|  | 	int i, j; | ||||||
|  | 
 | ||||||
|  | 	for(i=0; i<emu->ncpus; i++) | ||||||
|  | 	{ | ||||||
|  | 		cpu = &emu->cpu[i]; | ||||||
|  | 
 | ||||||
|  | 		dbg("-- cpu %d runs %d threads:", i, cpu->nthreads); | ||||||
|  | 		for(j=0; j<cpu->nthreads; j++) | ||||||
|  | 		{ | ||||||
|  | 			dbg(" %d", cpu->thread[j]->tid); | ||||||
|  | 		} | ||||||
|  | 		dbg("\n"); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	dbg("-- vcpu runs %d threads:", emu->vcpu.nthreads); | ||||||
|  | 	for(j=0; j<emu->vcpu.nthreads; j++) | ||||||
|  | 	{ | ||||||
|  | 		dbg(" %d", emu->vcpu.thread[j]->tid); | ||||||
|  | 	} | ||||||
|  | 	dbg("\n"); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void | ||||||
|  | ev_thread_execute(struct ovni_emu *emu) | ||||||
|  | { | ||||||
|  | 	struct ovni_cpu *cpu; | ||||||
|  | 	int cpuid; | ||||||
|  | 
 | ||||||
|  | 	/* The thread cannot be already running */ | ||||||
|  | 	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); | ||||||
|  | 	cpu = emu_get_cpu(emu, cpuid); | ||||||
|  | 
 | ||||||
|  | 	emu->cur_thread->state = TH_ST_RUNNING; | ||||||
|  | 	emu->cur_thread->cpu = cpu; | ||||||
|  | 
 | ||||||
|  | 	emu_cpu_add_thread(cpu, emu->cur_thread); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void | ||||||
|  | ev_thread_end(struct ovni_emu *emu) | ||||||
|  | { | ||||||
|  | 	assert(emu->cur_thread->state == TH_ST_RUNNING); | ||||||
|  | 	assert(emu->cur_thread->cpu); | ||||||
|  | 
 | ||||||
|  | 	emu_cpu_remove_thread(emu->cur_thread->cpu, emu->cur_thread); | ||||||
|  | 
 | ||||||
|  | 	emu->cur_thread->state = TH_ST_DEAD; | ||||||
|  | 	emu->cur_thread->cpu = NULL; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void | ||||||
|  | ev_thread_pause(struct ovni_emu *emu) | ||||||
|  | { | ||||||
|  | 	assert(emu->cur_thread->state == TH_ST_RUNNING); | ||||||
|  | 	assert(emu->cur_thread->cpu); | ||||||
|  | 
 | ||||||
|  | 	emu_cpu_remove_thread(emu->cur_thread->cpu, emu->cur_thread); | ||||||
|  | 
 | ||||||
|  | 	emu->cur_thread->state = TH_ST_PAUSED; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void | ||||||
|  | ev_thread_resume(struct ovni_emu *emu) | ||||||
|  | { | ||||||
|  | 	assert(emu->cur_thread->state == TH_ST_PAUSED); | ||||||
|  | 	assert(emu->cur_thread->cpu); | ||||||
|  | 
 | ||||||
|  | 	emu_cpu_add_thread(emu->cur_thread->cpu, emu->cur_thread); | ||||||
|  | 
 | ||||||
|  | 	emu->cur_thread->state = TH_ST_RUNNING; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void | ||||||
|  | ev_thread(struct ovni_emu *emu) | ||||||
|  | { | ||||||
|  | 	struct ovni_ev *ev; | ||||||
|  | 	struct ovni_cpu *cpu; | ||||||
|  | 	struct ovni_ethread *thread, *remote_thread; | ||||||
|  | 	int i; | ||||||
|  | 
 | ||||||
|  | 	emu_emit(emu); | ||||||
|  | 
 | ||||||
|  | 	thread = emu->cur_thread; | ||||||
|  | 	cpu = thread->cpu; | ||||||
|  | 	ev = emu->cur_ev; | ||||||
|  | 
 | ||||||
|  | 	switch(ev->value) | ||||||
|  | 	{ | ||||||
|  | 		case 'c': /* create */ | ||||||
|  | 			dbg("thread %d creates a new thread at cpu=%d with args=%x %x\n", | ||||||
|  | 					thread->tid, | ||||||
|  | 					ev->payload.u32[0], | ||||||
|  | 					ev->payload.u32[1], | ||||||
|  | 					ev->payload.u32[2]); | ||||||
|  | 
 | ||||||
|  | 			break; | ||||||
|  | 		case 'x': ev_thread_execute(emu); break; | ||||||
|  | 		case 'e': ev_thread_end(emu); break; | ||||||
|  | 		case 'p': ev_thread_pause(emu); break; | ||||||
|  | 		case 'r': ev_thread_resume(emu); break; | ||||||
|  | 		default: | ||||||
|  | 			break; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void | ||||||
|  | ev_affinity_set(struct ovni_emu *emu) | ||||||
|  | { | ||||||
|  | 	int cpuid; | ||||||
|  | 	struct ovni_cpu *newcpu; | ||||||
|  | 
 | ||||||
|  | 	cpuid = emu->cur_ev->payload.i32[0]; | ||||||
|  | 
 | ||||||
|  | 	assert(emu->cur_thread->state == TH_ST_RUNNING); | ||||||
|  | 	assert(emu->cur_thread->cpu); | ||||||
|  | 
 | ||||||
|  | 	/* Migrate current cpu to the one at cpuid */ | ||||||
|  | 	newcpu = emu_get_cpu(emu, cpuid); | ||||||
|  | 
 | ||||||
|  | 	emu_cpu_remove_thread(emu->cur_thread->cpu, emu->cur_thread); | ||||||
|  | 	emu_cpu_add_thread(newcpu, emu->cur_thread); | ||||||
|  | 
 | ||||||
|  | 	emu->cur_thread->cpu = newcpu; | ||||||
|  | 
 | ||||||
|  | 	dbg("cpu %d now runs %d\n", cpuid, emu->cur_thread->tid); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void | ||||||
|  | ev_affinity_remote(struct ovni_emu *emu) | ||||||
|  | { | ||||||
|  | 	int cpuid, tid; | ||||||
|  | 	struct ovni_cpu *newcpu; | ||||||
|  | 	struct ovni_ethread *thread; | ||||||
|  | 
 | ||||||
|  | 	cpuid = emu->cur_ev->payload.i32[0]; | ||||||
|  | 	tid = emu->cur_ev->payload.i32[1]; | ||||||
|  | 
 | ||||||
|  | 	thread = emu_get_thread(emu, tid); | ||||||
|  | 
 | ||||||
|  | 	assert(thread); | ||||||
|  | 	assert(thread->state == TH_ST_PAUSED); | ||||||
|  | 	assert(thread->cpu); | ||||||
|  | 
 | ||||||
|  | 	newcpu = emu_get_cpu(emu, cpuid); | ||||||
|  | 
 | ||||||
|  | 	/* It must not be running in any of the cpus */ | ||||||
|  | 	assert(emu_cpu_find_thread(thread->cpu, thread) == -1); | ||||||
|  | 	assert(emu_cpu_find_thread(newcpu, thread) == -1); | ||||||
|  | 
 | ||||||
|  | 	thread->cpu = newcpu; | ||||||
|  | 
 | ||||||
|  | 	dbg("thread %d switches to cpu %d by remote petition\n", tid, | ||||||
|  | 			cpuid); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void | ||||||
|  | ev_affinity(struct ovni_emu *emu) | ||||||
|  | { | ||||||
|  | 	emu_emit(emu); | ||||||
|  | 	switch(emu->cur_ev->value) | ||||||
|  | 	{ | ||||||
|  | 		case 's': ev_affinity_set(emu); break; | ||||||
|  | 		case 'r': ev_affinity_remote(emu); break; | ||||||
|  | 		default: | ||||||
|  | 			dbg("unknown affinity event value %c\n", | ||||||
|  | 					emu->cur_ev->value); | ||||||
|  | 			break; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void | ||||||
|  | ev_cpu_count(struct ovni_emu *emu) | ||||||
|  | { | ||||||
|  | 	int i, ncpus, maxcpu; | ||||||
|  | 
 | ||||||
|  | 	ncpus = emu->cur_ev->payload.i32[0]; | ||||||
|  | 	maxcpu = emu->cur_ev->payload.i32[1]; | ||||||
|  | 
 | ||||||
|  | 	assert(ncpus < OVNI_MAX_CPU); | ||||||
|  | 	assert(maxcpu < OVNI_MAX_CPU); | ||||||
|  | 
 | ||||||
|  | 	for(i=0; i<OVNI_MAX_CPU; i++) | ||||||
|  | 	{ | ||||||
|  | 		emu->cpu[i].state = CPU_ST_UNKNOWN; | ||||||
|  | 		emu->cpu[i].cpu_id = -1; | ||||||
|  | 		emu->cpuind[i] = -1; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	emu->ncpus = 0; | ||||||
|  | 	emu->max_ncpus = ncpus; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void | ||||||
|  | ev_cpu_id(struct ovni_emu *emu) | ||||||
|  | { | ||||||
|  | 	int cpuid; | ||||||
|  | 
 | ||||||
|  | 	cpuid = emu->cur_ev->payload.i32[0]; | ||||||
|  | 
 | ||||||
|  | 	assert(cpuid < emu->max_ncpus); | ||||||
|  | 	assert(emu->ncpus < emu->max_ncpus); | ||||||
|  | 	assert(emu->ncpus < OVNI_MAX_CPU); | ||||||
|  | 
 | ||||||
|  | 	assert(emu->cpu[emu->ncpus].state == CPU_ST_UNKNOWN); | ||||||
|  | 
 | ||||||
|  | 	emu->cpu[emu->ncpus].state = CPU_ST_READY; | ||||||
|  | 	emu->cpu[emu->ncpus].cpu_id = cpuid; | ||||||
|  | 	emu->cpu[emu->ncpus].index = emu->ncpus; | ||||||
|  | 
 | ||||||
|  | 	/* Fill the translation to cpu index too */ | ||||||
|  | 	assert(emu->cpuind[cpuid] == -1); | ||||||
|  | 	emu->cpuind[cpuid] = emu->ncpus; | ||||||
|  | 
 | ||||||
|  | 	dbg("new cpu id=%d at %d\n", cpuid, emu->ncpus); | ||||||
|  | 
 | ||||||
|  | 	emu->ncpus++; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | static void | ||||||
|  | ev_cpu(struct ovni_emu *emu) | ||||||
|  | { | ||||||
|  | 	switch(emu->cur_ev->value) | ||||||
|  | 	{ | ||||||
|  | 		case 'n': ev_cpu_count(emu); break; | ||||||
|  | 		case 'i': ev_cpu_id(emu); break; | ||||||
|  | 		default: | ||||||
|  | 			dbg("unknown cpu event value %c\n", | ||||||
|  | 					emu->cur_ev->value); | ||||||
|  | 			break; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void | ||||||
|  | emu_process_ovni_ev(struct ovni_emu *emu) | ||||||
|  | { | ||||||
|  | 	//emu_emit(emu);
 | ||||||
|  | 
 | ||||||
|  | 	switch(emu->cur_ev->class) | ||||||
|  | 	{ | ||||||
|  | 		case 'H': ev_thread(emu); break; | ||||||
|  | 		case 'A': ev_affinity(emu); break; | ||||||
|  | 		case 'C': ev_cpu(emu); break; | ||||||
|  | 		case 'B': dbg("burst %c\n", emu->cur_ev->value); break; | ||||||
|  | 		default: | ||||||
|  | 			dbg("unknown ovni event class %c\n", | ||||||
|  | 					emu->cur_ev->class); | ||||||
|  | 			break; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	print_threads_state(emu); | ||||||
|  | } | ||||||
							
								
								
									
										32
									
								
								ovni.c
									
									
									
									
									
								
							
							
						
						
									
										32
									
								
								ovni.c
									
									
									
									
									
								
							| @ -17,6 +17,7 @@ | |||||||
| #include <dirent.h> | #include <dirent.h> | ||||||
| 
 | 
 | ||||||
| #include "ovni.h" | #include "ovni.h" | ||||||
|  | #include "ovni_trace.h" | ||||||
| 
 | 
 | ||||||
| #define ENABLE_DEBUG | #define ENABLE_DEBUG | ||||||
| 
 | 
 | ||||||
| @ -237,9 +238,9 @@ hexdump(uint8_t *buf, size_t size) | |||||||
| 	{ | 	{ | ||||||
| 		for(j=0; j<16 && i+j < size; j++) | 		for(j=0; j<16 && i+j < size; j++) | ||||||
| 		{ | 		{ | ||||||
| 			printf("%02x ", buf[i+j]); | 			dbg("%02x ", buf[i+j]); | ||||||
| 		} | 		} | ||||||
| 		printf("\n"); | 		dbg("\n"); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -307,16 +308,34 @@ ovni_ev_set_mcv(struct ovni_ev *ev, char *mcv) | |||||||
| int | int | ||||||
| ovni_payload_size(struct ovni_ev *ev) | ovni_payload_size(struct ovni_ev *ev) | ||||||
| { | { | ||||||
| 	return ev->flags & 0x0f; | 	int size; | ||||||
|  | 
 | ||||||
|  | 	size = ev->flags & 0x0f; | ||||||
|  | 
 | ||||||
|  | 	if(size == 0) | ||||||
|  | 		return 0; | ||||||
|  | 
 | ||||||
|  | 	/* The minimum size is 2 bytes, so we can encode a length of 16
 | ||||||
|  | 	 * bytes using 4 bits (0x0f) */ | ||||||
|  | 	size++; | ||||||
|  | 
 | ||||||
|  | 	return size; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void | void | ||||||
| ovni_payload_add(struct ovni_ev *ev, uint8_t *buf, int size) | ovni_payload_add(struct ovni_ev *ev, uint8_t *buf, int size) | ||||||
| { | { | ||||||
| 	/* Ensure we have room */ | 	int payload_size; | ||||||
| 	assert(ovni_payload_size(ev) + size < 16); |  | ||||||
| 
 | 
 | ||||||
| 	ev->flags = ev->flags & 0xf0 | size & 0x0f; | 	payload_size = ovni_payload_size(ev); | ||||||
|  | 
 | ||||||
|  | 	/* Ensure we have room */ | ||||||
|  | 	assert(payload_size + size <= sizeof(ev->payload)); | ||||||
|  | 
 | ||||||
|  | 	memcpy(&ev->payload.u8[payload_size], buf, size); | ||||||
|  | 	payload_size += size; | ||||||
|  | 
 | ||||||
|  | 	ev->flags = ev->flags & 0xf0 | (payload_size-1) & 0x0f; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int | int | ||||||
| @ -412,6 +431,7 @@ load_proc(struct ovni_eproc *proc, char *procdir) | |||||||
| 
 | 
 | ||||||
| 		sprintf(path, "%s/%s", procdir, dirent->d_name); | 		sprintf(path, "%s/%s", procdir, dirent->d_name); | ||||||
| 		thread->f = fopen(path, "r"); | 		thread->f = fopen(path, "r"); | ||||||
|  | 		thread->state = TH_ST_UNKNOWN; | ||||||
| 
 | 
 | ||||||
| 		if(thread->f == NULL) | 		if(thread->f == NULL) | ||||||
| 		{ | 		{ | ||||||
|  | |||||||
							
								
								
									
										115
									
								
								ovni.h
									
									
									
									
									
								
							
							
						
						
									
										115
									
								
								ovni.h
									
									
									
									
									
								
							| @ -1,13 +1,12 @@ | |||||||
| #ifndef OVNI_H | #ifndef OVNI_H | ||||||
| #define OVNI_H | #define OVNI_H | ||||||
| 
 | 
 | ||||||
|  | #include <stdio.h> | ||||||
| #include <stdint.h> | #include <stdint.h> | ||||||
| #include <stdlib.h> | #include <stdlib.h> | ||||||
| #include <string.h> | #include <string.h> | ||||||
| #include <linux/limits.h> | #include <linux/limits.h> | ||||||
| 
 | 
 | ||||||
| #include "ovni.h" |  | ||||||
| 
 |  | ||||||
| #define OVNI_MAX_CPU 256 | #define OVNI_MAX_CPU 256 | ||||||
| #define OVNI_MAX_PROC 32 | #define OVNI_MAX_PROC 32 | ||||||
| #define OVNI_MAX_THR 32 | #define OVNI_MAX_THR 32 | ||||||
| @ -19,6 +18,17 @@ | |||||||
| 
 | 
 | ||||||
| /* ----------------------- common ------------------------ */ | /* ----------------------- common ------------------------ */ | ||||||
| 
 | 
 | ||||||
|  | union __attribute__((__packed__)) ovni_ev_payload { | ||||||
|  | 	uint8_t u8[16]; | ||||||
|  | 	int8_t i8[16]; | ||||||
|  | 	uint16_t u16[8]; | ||||||
|  | 	int16_t i16[8]; | ||||||
|  | 	uint32_t u32[4]; | ||||||
|  | 	int32_t i32[4]; | ||||||
|  | 	uint64_t u64[2]; | ||||||
|  | 	int64_t i64[2]; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
| struct __attribute__((__packed__)) ovni_ev { | struct __attribute__((__packed__)) ovni_ev { | ||||||
| 	/* first 4 bits reserved, last 4 for payload size */ | 	/* first 4 bits reserved, last 4 for payload size */ | ||||||
| 	uint8_t flags; | 	uint8_t flags; | ||||||
| @ -27,12 +37,7 @@ struct __attribute__((__packed__)) ovni_ev { | |||||||
| 	uint8_t value; | 	uint8_t value; | ||||||
| 	uint16_t clock_hi; | 	uint16_t clock_hi; | ||||||
| 	uint32_t clock_lo; | 	uint32_t clock_lo; | ||||||
| 	union { | 	union ovni_ev_payload payload; | ||||||
| 		uint8_t payload_u8[16]; |  | ||||||
| 		uint16_t payload_u16[8]; |  | ||||||
| 		uint32_t payload_u32[4]; |  | ||||||
| 		uint64_t payload_u64[2]; |  | ||||||
| 	} payload; |  | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| /* ----------------------- runtime ------------------------ */ | /* ----------------------- runtime ------------------------ */ | ||||||
| @ -75,93 +80,6 @@ struct ovni_rproc { | |||||||
| 	int ready; | 	int ready; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| /* ----------------------- emulated ------------------------ */ |  | ||||||
| 
 |  | ||||||
| struct ovni_cpu; |  | ||||||
| 
 |  | ||||||
| /* State of each thread on post-process */ |  | ||||||
| struct ovni_ethread { |  | ||||||
| 	/* Emulated thread tid */ |  | ||||||
| 	pid_t tid; |  | ||||||
| 
 |  | ||||||
| 	/* Stream file */ |  | ||||||
| 	FILE *f; |  | ||||||
| 
 |  | ||||||
| 	/* Thread stream */ |  | ||||||
| 	struct ovni_stream *stream; |  | ||||||
| 
 |  | ||||||
| 	/* Current cpu */ |  | ||||||
| 	struct ovni_cpu *cpu; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| /* State of each process on post-process */ |  | ||||||
| struct ovni_eproc { |  | ||||||
| 	/* Monotonic counter for process index */ |  | ||||||
| 	/* TODO: Use pid? */ |  | ||||||
| 	int proc; |  | ||||||
| 
 |  | ||||||
| 	/* Path of the process tracedir */ |  | ||||||
| 	char dir[PATH_MAX]; |  | ||||||
| 
 |  | ||||||
| 	/* Threads */ |  | ||||||
| 	size_t nthreads; |  | ||||||
| 	struct ovni_ethread thread[OVNI_MAX_THR]; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| /* ----------------------- trace ------------------------ */ |  | ||||||
| 
 |  | ||||||
| /* State of each loom on post-process */ |  | ||||||
| struct ovni_loom { |  | ||||||
| 	size_t nprocs; |  | ||||||
| 	struct ovni_eproc proc[OVNI_MAX_PROC]; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| struct ovni_stream { |  | ||||||
| 	FILE *f; |  | ||||||
| 	int tid; |  | ||||||
| 	int thread; |  | ||||||
| 	int proc; |  | ||||||
| 	int loom; |  | ||||||
| 	int loaded; |  | ||||||
| 	int active; |  | ||||||
| 	struct ovni_ev last; |  | ||||||
| 	uint64_t lastclock; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| struct ovni_trace { |  | ||||||
| 	int nlooms; |  | ||||||
| 	struct ovni_loom loom[OVNI_MAX_LOOM]; |  | ||||||
| 	int nstreams; |  | ||||||
| 	struct ovni_stream *stream; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| struct ovni_cpu { |  | ||||||
| 	/* The thread the cpu is currently running */ |  | ||||||
| 	struct ovni_ethread *thread; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| struct ovni_evhead { |  | ||||||
| 	struct ovni_stream *stream; |  | ||||||
| 
 |  | ||||||
| 	struct ovni_loom *loom; |  | ||||||
| 	struct ovni_eproc *proc; |  | ||||||
| 	struct ovni_ethread *thread; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| struct ovni_emulator { |  | ||||||
| 	struct ovni_trace trace; |  | ||||||
| 	struct ovni_cpu cpu[OVNI_MAX_CPU]; |  | ||||||
| 
 |  | ||||||
| 	struct ovni_evhead head; |  | ||||||
| 	uint64_t lastclock; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| int ovni_proc_init(int loom, int proc); | int ovni_proc_init(int loom, int proc); | ||||||
| 
 | 
 | ||||||
| int ovni_thread_init(pid_t tid); | int ovni_thread_init(pid_t tid); | ||||||
| @ -185,12 +103,5 @@ void ovni_ev(struct ovni_ev *ev); | |||||||
| 
 | 
 | ||||||
| int ovni_flush(); | int ovni_flush(); | ||||||
| 
 | 
 | ||||||
| int ovni_load_trace(struct ovni_trace *trace, char *tracedir); |  | ||||||
| 
 |  | ||||||
| int ovni_load_streams(struct ovni_trace *trace); |  | ||||||
| 
 |  | ||||||
| void ovni_free_streams(struct ovni_trace *trace); |  | ||||||
| 
 |  | ||||||
| void ovni_load_next_event(struct ovni_stream *stream); |  | ||||||
| 
 | 
 | ||||||
| #endif /* OVNI_H */ | #endif /* OVNI_H */ | ||||||
|  | |||||||
| @ -9,6 +9,7 @@ | |||||||
| #include <dirent.h>  | #include <dirent.h>  | ||||||
| 
 | 
 | ||||||
| #include "ovni.h" | #include "ovni.h" | ||||||
|  | #include "ovni_trace.h" | ||||||
| 
 | 
 | ||||||
| void emit(struct ovni_stream *stream, struct ovni_ev *ev) | void emit(struct ovni_stream *stream, struct ovni_ev *ev) | ||||||
| { | { | ||||||
|  | |||||||
							
								
								
									
										15
									
								
								ovni_trace.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								ovni_trace.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,15 @@ | |||||||
|  | #ifndef OVNI_TRACE_H | ||||||
|  | #define OVNI_TRACE_H | ||||||
|  | 
 | ||||||
|  | #include "ovni.h" | ||||||
|  | #include "emu.h" | ||||||
|  | 
 | ||||||
|  | void ovni_load_next_event(struct ovni_stream *stream); | ||||||
|  | 
 | ||||||
|  | int ovni_load_trace(struct ovni_trace *trace, char *tracedir); | ||||||
|  | 
 | ||||||
|  | int ovni_load_streams(struct ovni_trace *trace); | ||||||
|  | 
 | ||||||
|  | void ovni_free_streams(struct ovni_trace *trace); | ||||||
|  | 
 | ||||||
|  | #endif /* OVNI_TRACE_H */ | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user