From d25bbed350668944e29351c584683e6202c1aa40 Mon Sep 17 00:00:00 2001 From: Rodrigo Arias Mallo Date: Wed, 28 Jul 2021 11:56:35 +0200 Subject: [PATCH] Distribute emulator into modules --- Makefile | 13 +-- dump.c | 4 +- emu.c | 312 +++++++++++++++++++++++++++++++++++++++++++++++++++ emu.h | 151 +++++++++++++++++++++++++ emu_nosv.c | 13 +++ emu_ovni.c | 265 +++++++++++++++++++++++++++++++++++++++++++ ovni.c | 32 +++++- ovni.h | 115 +++---------------- ovni2prv.c | 1 + ovni_trace.h | 15 +++ 10 files changed, 805 insertions(+), 116 deletions(-) create mode 100644 emu.c create mode 100644 emu.h create mode 100644 emu_nosv.c create mode 100644 emu_ovni.c create mode 100644 ovni_trace.h diff --git a/Makefile b/Makefile index 169b76c..26addf5 100644 --- a/Makefile +++ b/Makefile @@ -3,15 +3,14 @@ CFLAGS=-fPIC # Debug CFLAGS #CFLAGS+=-fsanitize=address #LDFLAGS+=-fsanitize=address -#CFLAGS+=-g -O0 +CFLAGS+=-g -O0 # Performance CFLAGS -CFLAGS+=-O3 -CFLAGS+=-fstack-protector-explicit -CFLAGS+=-flto +#CFLAGS+=-O3 +#CFLAGS+=-fstack-protector-explicit +#CFLAGS+=-flto -BIN=dump libovni.a test_speed ovni2prv -#BIN=dump libovni.a prvth test_speed emu +BIN=dump libovni.a test_speed ovni2prv emu all: $(BIN) @@ -22,7 +21,7 @@ dump: ovni.o dump.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 diff --git a/dump.c b/dump.c index 7fd2435..51506ae 100644 --- a/dump.c +++ b/dump.c @@ -9,6 +9,8 @@ #include #include "ovni.h" +#include "ovni_trace.h" +#include "emu.h" #define ENABLE_DEBUG @@ -58,7 +60,7 @@ void emit(struct ovni_stream *stream, struct ovni_ev *ev) payloadsize = ovni_payload_size(ev); for(i=0; ipayload.payload_u8[i]); + printf("%02x ", ev->payload.u8[i]); } printf("\n"); diff --git a/emu.c b/emu.c new file mode 100644 index 0000000..dad632a --- /dev/null +++ b/emu.c @@ -0,0 +1,312 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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; ipayload.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; inthreads; 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; instreams; 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; instreams; 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; inthreads; 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; itrace.nlooms; i++) + { + loom = &emu->trace.loom[i]; + for(j=0; jnprocs; j++) + { + proc = &loom->proc[j]; + for(k=0; knthreads; 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; +} diff --git a/emu.h b/emu.h new file mode 100644 index 0000000..73245cd --- /dev/null +++ b/emu.h @@ -0,0 +1,151 @@ +#ifndef OVNI_EMU_H +#define OVNI_EMU_H + +#include "ovni.h" +#include + +/* 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 */ diff --git a/emu_nosv.c b/emu_nosv.c new file mode 100644 index 0000000..2b88478 --- /dev/null +++ b/emu_nosv.c @@ -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) +{ +} diff --git a/emu_ovni.c b/emu_ovni.c new file mode 100644 index 0000000..d819dd8 --- /dev/null +++ b/emu_ovni.c @@ -0,0 +1,265 @@ +#include "ovni.h" +#include "emu.h" + +#include + +static void +print_threads_state(struct ovni_emu *emu) +{ + struct ovni_cpu *cpu; + int i, j; + + for(i=0; incpus; i++) + { + cpu = &emu->cpu[i]; + + dbg("-- cpu %d runs %d threads:", i, cpu->nthreads); + for(j=0; jnthreads; j++) + { + dbg(" %d", cpu->thread[j]->tid); + } + dbg("\n"); + } + + dbg("-- vcpu runs %d threads:", emu->vcpu.nthreads); + for(j=0; jvcpu.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; icpu[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); +} diff --git a/ovni.c b/ovni.c index f2ba373..eda549e 100644 --- a/ovni.c +++ b/ovni.c @@ -17,6 +17,7 @@ #include #include "ovni.h" +#include "ovni_trace.h" #define ENABLE_DEBUG @@ -237,9 +238,9 @@ hexdump(uint8_t *buf, size_t size) { 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 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 ovni_payload_add(struct ovni_ev *ev, uint8_t *buf, int size) { - /* Ensure we have room */ - assert(ovni_payload_size(ev) + size < 16); + int payload_size; - 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 @@ -412,6 +431,7 @@ load_proc(struct ovni_eproc *proc, char *procdir) sprintf(path, "%s/%s", procdir, dirent->d_name); thread->f = fopen(path, "r"); + thread->state = TH_ST_UNKNOWN; if(thread->f == NULL) { diff --git a/ovni.h b/ovni.h index 5196ac3..9318bbb 100644 --- a/ovni.h +++ b/ovni.h @@ -1,13 +1,12 @@ #ifndef OVNI_H #define OVNI_H +#include #include #include #include #include -#include "ovni.h" - #define OVNI_MAX_CPU 256 #define OVNI_MAX_PROC 32 #define OVNI_MAX_THR 32 @@ -19,6 +18,17 @@ /* ----------------------- 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 { /* first 4 bits reserved, last 4 for payload size */ uint8_t flags; @@ -27,12 +37,7 @@ struct __attribute__((__packed__)) ovni_ev { uint8_t value; uint16_t clock_hi; uint32_t clock_lo; - union { - uint8_t payload_u8[16]; - uint16_t payload_u16[8]; - uint32_t payload_u32[4]; - uint64_t payload_u64[2]; - } payload; + union ovni_ev_payload payload; }; /* ----------------------- runtime ------------------------ */ @@ -75,93 +80,6 @@ struct ovni_rproc { 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_thread_init(pid_t tid); @@ -185,12 +103,5 @@ void ovni_ev(struct ovni_ev *ev); 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 */ diff --git a/ovni2prv.c b/ovni2prv.c index dcf00a7..ed89246 100644 --- a/ovni2prv.c +++ b/ovni2prv.c @@ -9,6 +9,7 @@ #include #include "ovni.h" +#include "ovni_trace.h" void emit(struct ovni_stream *stream, struct ovni_ev *ev) { diff --git a/ovni_trace.h b/ovni_trace.h new file mode 100644 index 0000000..59990b9 --- /dev/null +++ b/ovni_trace.h @@ -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 */