diff --git a/emu.c b/emu.c index 3fbc77a..2e46f78 100644 --- a/emu.c +++ b/emu.c @@ -79,14 +79,14 @@ hook_pre(struct ovni_emu *emu) } static void -hook_view(struct ovni_emu *emu) +hook_emit(struct ovni_emu *emu) { //emu_emit(emu); switch(emu->cur_ev->header.model) { - case 'O': hook_view_ovni(emu); break; - case 'V': hook_view_nosv(emu); break; + case 'O': hook_emit_ovni(emu); break; + case 'V': hook_emit_nosv(emu); break; default: //dbg("unknown model %c\n", emu->cur_ev->model); break; @@ -197,7 +197,7 @@ emulate(struct ovni_emu *emu) { //fprintf(stdout, "step %i\n", i); hook_pre(emu); - hook_view(emu); + hook_emit(emu); hook_post(emu); /* Read the next event */ @@ -237,6 +237,16 @@ emu_get_thread(struct ovni_emu *emu, int tid) return thread; } +void +emu_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); +} + + int main(int argc, char *argv[]) { diff --git a/emu.h b/emu.h index 777f87e..a6f402c 100644 --- a/emu.h +++ b/emu.h @@ -73,9 +73,7 @@ struct ovni_ethread { /* State of each emulated process */ struct ovni_eproc { - /* Monotonic counter for process index */ - /* TODO: Use pid? */ - int proc; + int pid; /* Path of the process tracedir */ char dir[PATH_MAX]; @@ -83,6 +81,13 @@ struct ovni_eproc { /* Threads */ size_t nthreads; struct ovni_ethread thread[OVNI_MAX_THR]; + + /* ------ Subsystem specific data --------*/ + /* TODO: Use dynamic allocation */ + + struct nosv_task_type *types; + struct nosv_task *tasks; + }; /* ----------------------- trace ------------------------ */ @@ -174,15 +179,17 @@ struct ovni_emu { void emu_emit(struct ovni_emu *emu); void hook_pre_ovni(struct ovni_emu *emu); -void hook_view_ovni(struct ovni_emu *emu); +void hook_emit_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_emit_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); +void emu_emit_prv(struct ovni_emu *emu, int type, int val); + #endif /* OVNI_EMU_H */ diff --git a/emu_nosv.c b/emu_nosv.c index 1b63609..96230c9 100644 --- a/emu_nosv.c +++ b/emu_nosv.c @@ -4,8 +4,9 @@ #include "uthash.h" #include -struct nosv_task *tasks = NULL; -struct nosv_task_type *types = NULL; +enum nosv_prv_type { + PRV_TYPE_PROCID +}; struct hook_entry { char id[4]; @@ -32,7 +33,7 @@ pre_task_create(struct ovni_emu *emu) task->state = TASK_ST_CREATED; /* Ensure the task id is new */ - HASH_FIND_INT(tasks, &task->id, p); + HASH_FIND_INT(emu->cur_proc->tasks, &task->id, p); if(p != NULL) { @@ -41,7 +42,7 @@ pre_task_create(struct ovni_emu *emu) } /* Add the new task to the hash table */ - HASH_ADD_INT(tasks, id, task); + HASH_ADD_INT(emu->cur_proc->tasks, id, task); emu->cur_task = task; @@ -56,7 +57,7 @@ pre_task_execute(struct ovni_emu *emu) taskid = emu->cur_ev->payload.i32[0]; - HASH_FIND_INT(tasks, &taskid, task); + HASH_FIND_INT(emu->cur_proc->tasks, &taskid, task); assert(task != NULL); assert(emu->cur_thread->state == TH_ST_RUNNING); @@ -79,7 +80,7 @@ pre_task_pause(struct ovni_emu *emu) taskid = emu->cur_ev->payload.i32[0]; - HASH_FIND_INT(tasks, &taskid, task); + HASH_FIND_INT(emu->cur_proc->tasks, &taskid, task); assert(task != NULL); assert(task->state == TASK_ST_RUNNING); @@ -102,7 +103,7 @@ pre_task_resume(struct ovni_emu *emu) taskid = emu->cur_ev->payload.i32[0]; - HASH_FIND_INT(tasks, &taskid, task); + HASH_FIND_INT(emu->cur_proc->tasks, &taskid, task); assert(task != NULL); assert(task->state == TASK_ST_PAUSED); @@ -126,7 +127,7 @@ pre_task_end(struct ovni_emu *emu) taskid = emu->cur_ev->payload.i32[0]; - HASH_FIND_INT(tasks, &taskid, task); + HASH_FIND_INT(emu->cur_proc->tasks, &taskid, task); assert(task != NULL); assert(task->state == TASK_ST_RUNNING); @@ -164,7 +165,7 @@ pre_task(struct ovni_emu *emu) static void pre_type_create(struct ovni_emu *emu) { - struct nosv_task_type *type, *p = NULL; + struct nosv_task_type *type; uint8_t *data; uint32_t *typeid; const char *label; @@ -181,7 +182,7 @@ pre_type_create(struct ovni_emu *emu) label = (const char *) data; /* Ensure the type id is new */ - HASH_FIND_INT(types, typeid, type); + HASH_FIND_INT(emu->cur_proc->types, typeid, type); if(type != NULL) { @@ -201,7 +202,7 @@ pre_type_create(struct ovni_emu *emu) type->label = label; /* Add the new task type to the hash table */ - HASH_ADD_INT(types, id, type); + HASH_ADD_INT(emu->cur_proc->types, id, type); dbg("new task type created id=%d label=%s\n", type->id, type->label); @@ -233,47 +234,39 @@ hook_pre_nosv(struct ovni_emu *emu) /* --------------------------- emit ------------------------------- */ -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); + //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); - emit_prv(emu, 300, emu->cur_task->type_id + 1); + emu_emit_prv(emu, 200, emu->cur_task->id + 1); + emu_emit_prv(emu, 300, emu->cur_task->type_id + 1); + emu_emit_prv(emu, 300, emu->cur_task->type_id + 1); } static void emit_task_pause(struct ovni_emu *emu) { - emit_prv(emu, 200, 0); - emit_prv(emu, 300, 0); + emu_emit_prv(emu, 200, 0); + emu_emit_prv(emu, 300, 0); } static void emit_task_resume(struct ovni_emu *emu) { - emit_prv(emu, 200, emu->cur_task->id + 1); - emit_prv(emu, 300, emu->cur_task->type_id + 1); + emu_emit_prv(emu, 200, emu->cur_task->id + 1); + emu_emit_prv(emu, 300, emu->cur_task->type_id + 1); } static void emit_task_end(struct ovni_emu *emu) { - emit_prv(emu, 200, 0); - emit_prv(emu, 300, 0); + emu_emit_prv(emu, 200, 0); + emu_emit_prv(emu, 300, 0); } static void @@ -292,7 +285,7 @@ emit_task(struct ovni_emu *emu) } void -hook_view_nosv(struct ovni_emu *emu) +hook_emit_nosv(struct ovni_emu *emu) { dbg("pre nosv\n"); switch(emu->cur_ev->header.class) diff --git a/emu_ovni.c b/emu_ovni.c index 5d88d7f..d0cce55 100644 --- a/emu_ovni.c +++ b/emu_ovni.c @@ -326,7 +326,7 @@ hook_pre_ovni(struct ovni_emu *emu) } static void -view_thread_count(struct ovni_emu *emu) +emit_thread_count(struct ovni_emu *emu) { int i, n, cpu = -1; int64_t delta_time; @@ -364,15 +364,25 @@ emit: cpu+1, delta_time, n); } +static void +emit_current_pid(struct ovni_emu *emu) +{ + if(emu->cur_thread->cpu == NULL) + return; + + emu_emit_prv(emu, 400, emu->cur_proc->pid); +} + void -hook_view_ovni(struct ovni_emu *emu) +hook_emit_ovni(struct ovni_emu *emu) { switch(emu->cur_ev->header.class) { case 'H': case 'A': case 'C': - view_thread_count(emu); + emit_thread_count(emu); + emit_current_pid(emu); break; default: break; @@ -391,4 +401,3 @@ hook_post_ovni(struct ovni_emu *emu) emu->vcpu.last_nthreads = emu->vcpu.nthreads; } - diff --git a/ovni.c b/ovni.c index 4aff761..65a7adf 100644 --- a/ovni.c +++ b/ovni.c @@ -444,6 +444,31 @@ ovni_ev(struct ovni_ev *ev) ovni_ev_add(ev); } +static int +find_dir_prefix(struct dirent *dirent, const char *prefix, int *num) +{ + const char *p; + + p = dirent->d_name; + + /* Check the prefix */ + if(strncmp(p, prefix, strlen(prefix)) != 0) + return -1; + + p += strlen(prefix); + + /* Find the dot */ + if(*p != '.') + return -1; + + p++; + + /* Convert the end to a number */ + *num = atoi(p); + + return 0; +} + static int load_thread(struct ovni_ethread *thread, int tid, char *filepath) { @@ -461,13 +486,15 @@ load_thread(struct ovni_ethread *thread, int tid, char *filepath) } static int -load_proc(struct ovni_eproc *proc, char *procdir) +load_proc(struct ovni_eproc *proc, int pid, char *procdir) { struct dirent *dirent; DIR *dir; char path[PATH_MAX]; - char *p; struct ovni_ethread *thread; + int tid; + + proc->pid = pid; if((dir = opendir(procdir)) == NULL) { @@ -478,24 +505,24 @@ load_proc(struct ovni_eproc *proc, char *procdir) while((dirent = readdir(dir)) != NULL) { - if(dirent->d_name[0] != 't') - continue; - p = strchr(dirent->d_name, '.'); - if(p == NULL) - continue; - p++; - if(*p == '\0') + if(find_dir_prefix(dirent, "thread", &tid) != 0) { - fprintf(stderr, "bad thread stream file: %s\n", + err("warning: ignoring bogus directory entry %s\n", dirent->d_name); - return -1; + continue; } sprintf(path, "%s/%s", procdir, dirent->d_name); + if(proc->nthreads >= OVNI_MAX_THR) + { + err("too many thread streams for process %d\n", pid); + abort(); + } + thread = &proc->thread[proc->nthreads++]; - if(load_thread(thread, atoi(p), path) != 0) + if(load_thread(thread, tid, path) != 0) return -1; } @@ -505,38 +532,47 @@ load_proc(struct ovni_eproc *proc, char *procdir) } static int -load_loom(struct ovni_loom *loom, char *loomdir) +load_loom(struct ovni_loom *loom, int loomid, char *loomdir) { - int proc; + int pid; char path[PATH_MAX]; struct stat st; + DIR *dir; + struct dirent *dirent; + struct ovni_eproc *proc; - for(proc=0; procd_name); + continue; } - if(!S_ISDIR(st.st_mode)) + sprintf(path, "%s/%s", loomdir, dirent->d_name); + + if(loom->nprocs >= OVNI_MAX_PROC) { - fprintf(stderr, "not a dir %s\n", path); - return -1; + err("too many process streams for loom %d\n", + loomid); + abort(); } - if(load_proc(&loom->proc[proc], path)) + proc = &loom->proc[loom->nprocs++]; + + if(load_proc(proc, pid, path) != 0) return -1; } - loom->nprocs = proc; + closedir(dir); return 0; } @@ -553,7 +589,7 @@ ovni_load_trace(struct ovni_trace *trace, char *tracedir) sprintf(path, "%s/loom.%d", tracedir, loom); - if(load_loom(&trace->loom[loom], path)) + if(load_loom(&trace->loom[loom], loom, path)) return -1; trace->nlooms = nlooms;