Load process directories using the pid
This commit is contained in:
parent
d7c81b3048
commit
dc2df90cc4
18
emu.c
18
emu.c
@ -79,14 +79,14 @@ hook_pre(struct ovni_emu *emu)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
hook_view(struct ovni_emu *emu)
|
hook_emit(struct ovni_emu *emu)
|
||||||
{
|
{
|
||||||
//emu_emit(emu);
|
//emu_emit(emu);
|
||||||
|
|
||||||
switch(emu->cur_ev->header.model)
|
switch(emu->cur_ev->header.model)
|
||||||
{
|
{
|
||||||
case 'O': hook_view_ovni(emu); break;
|
case 'O': hook_emit_ovni(emu); break;
|
||||||
case 'V': hook_view_nosv(emu); break;
|
case 'V': hook_emit_nosv(emu); break;
|
||||||
default:
|
default:
|
||||||
//dbg("unknown model %c\n", emu->cur_ev->model);
|
//dbg("unknown model %c\n", emu->cur_ev->model);
|
||||||
break;
|
break;
|
||||||
@ -197,7 +197,7 @@ emulate(struct ovni_emu *emu)
|
|||||||
{
|
{
|
||||||
//fprintf(stdout, "step %i\n", i);
|
//fprintf(stdout, "step %i\n", i);
|
||||||
hook_pre(emu);
|
hook_pre(emu);
|
||||||
hook_view(emu);
|
hook_emit(emu);
|
||||||
hook_post(emu);
|
hook_post(emu);
|
||||||
|
|
||||||
/* Read the next event */
|
/* Read the next event */
|
||||||
@ -237,6 +237,16 @@ emu_get_thread(struct ovni_emu *emu, int tid)
|
|||||||
return thread;
|
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
|
int
|
||||||
main(int argc, char *argv[])
|
main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
17
emu.h
17
emu.h
@ -73,9 +73,7 @@ struct ovni_ethread {
|
|||||||
|
|
||||||
/* State of each emulated process */
|
/* State of each emulated process */
|
||||||
struct ovni_eproc {
|
struct ovni_eproc {
|
||||||
/* Monotonic counter for process index */
|
int pid;
|
||||||
/* TODO: Use pid? */
|
|
||||||
int proc;
|
|
||||||
|
|
||||||
/* Path of the process tracedir */
|
/* Path of the process tracedir */
|
||||||
char dir[PATH_MAX];
|
char dir[PATH_MAX];
|
||||||
@ -83,6 +81,13 @@ struct ovni_eproc {
|
|||||||
/* Threads */
|
/* Threads */
|
||||||
size_t nthreads;
|
size_t nthreads;
|
||||||
struct ovni_ethread thread[OVNI_MAX_THR];
|
struct ovni_ethread thread[OVNI_MAX_THR];
|
||||||
|
|
||||||
|
/* ------ Subsystem specific data --------*/
|
||||||
|
/* TODO: Use dynamic allocation */
|
||||||
|
|
||||||
|
struct nosv_task_type *types;
|
||||||
|
struct nosv_task *tasks;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* ----------------------- trace ------------------------ */
|
/* ----------------------- trace ------------------------ */
|
||||||
@ -174,15 +179,17 @@ struct ovni_emu {
|
|||||||
void emu_emit(struct ovni_emu *emu);
|
void emu_emit(struct ovni_emu *emu);
|
||||||
|
|
||||||
void hook_pre_ovni(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_post_ovni(struct ovni_emu *emu);
|
||||||
|
|
||||||
void hook_pre_nosv(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);
|
void hook_post_nosv(struct ovni_emu *emu);
|
||||||
|
|
||||||
struct ovni_cpu *emu_get_cpu(struct ovni_emu *emu, int cpuid);
|
struct ovni_cpu *emu_get_cpu(struct ovni_emu *emu, int cpuid);
|
||||||
|
|
||||||
struct ovni_ethread *emu_get_thread(struct ovni_emu *emu, int tid);
|
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 */
|
#endif /* OVNI_EMU_H */
|
||||||
|
53
emu_nosv.c
53
emu_nosv.c
@ -4,8 +4,9 @@
|
|||||||
#include "uthash.h"
|
#include "uthash.h"
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
struct nosv_task *tasks = NULL;
|
enum nosv_prv_type {
|
||||||
struct nosv_task_type *types = NULL;
|
PRV_TYPE_PROCID
|
||||||
|
};
|
||||||
|
|
||||||
struct hook_entry {
|
struct hook_entry {
|
||||||
char id[4];
|
char id[4];
|
||||||
@ -32,7 +33,7 @@ pre_task_create(struct ovni_emu *emu)
|
|||||||
task->state = TASK_ST_CREATED;
|
task->state = TASK_ST_CREATED;
|
||||||
|
|
||||||
/* Ensure the task id is new */
|
/* 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)
|
if(p != NULL)
|
||||||
{
|
{
|
||||||
@ -41,7 +42,7 @@ pre_task_create(struct ovni_emu *emu)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Add the new task to the hash table */
|
/* 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;
|
emu->cur_task = task;
|
||||||
|
|
||||||
@ -56,7 +57,7 @@ pre_task_execute(struct ovni_emu *emu)
|
|||||||
|
|
||||||
taskid = emu->cur_ev->payload.i32[0];
|
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 != NULL);
|
||||||
assert(emu->cur_thread->state == TH_ST_RUNNING);
|
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];
|
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 != NULL);
|
||||||
assert(task->state == TASK_ST_RUNNING);
|
assert(task->state == TASK_ST_RUNNING);
|
||||||
@ -102,7 +103,7 @@ pre_task_resume(struct ovni_emu *emu)
|
|||||||
|
|
||||||
taskid = emu->cur_ev->payload.i32[0];
|
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 != NULL);
|
||||||
assert(task->state == TASK_ST_PAUSED);
|
assert(task->state == TASK_ST_PAUSED);
|
||||||
@ -126,7 +127,7 @@ pre_task_end(struct ovni_emu *emu)
|
|||||||
|
|
||||||
taskid = emu->cur_ev->payload.i32[0];
|
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 != NULL);
|
||||||
assert(task->state == TASK_ST_RUNNING);
|
assert(task->state == TASK_ST_RUNNING);
|
||||||
@ -164,7 +165,7 @@ pre_task(struct ovni_emu *emu)
|
|||||||
static void
|
static void
|
||||||
pre_type_create(struct ovni_emu *emu)
|
pre_type_create(struct ovni_emu *emu)
|
||||||
{
|
{
|
||||||
struct nosv_task_type *type, *p = NULL;
|
struct nosv_task_type *type;
|
||||||
uint8_t *data;
|
uint8_t *data;
|
||||||
uint32_t *typeid;
|
uint32_t *typeid;
|
||||||
const char *label;
|
const char *label;
|
||||||
@ -181,7 +182,7 @@ pre_type_create(struct ovni_emu *emu)
|
|||||||
label = (const char *) data;
|
label = (const char *) data;
|
||||||
|
|
||||||
/* Ensure the type id is new */
|
/* Ensure the type id is new */
|
||||||
HASH_FIND_INT(types, typeid, type);
|
HASH_FIND_INT(emu->cur_proc->types, typeid, type);
|
||||||
|
|
||||||
if(type != NULL)
|
if(type != NULL)
|
||||||
{
|
{
|
||||||
@ -201,7 +202,7 @@ pre_type_create(struct ovni_emu *emu)
|
|||||||
type->label = label;
|
type->label = label;
|
||||||
|
|
||||||
/* Add the new task type to the hash table */
|
/* 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,
|
dbg("new task type created id=%d label=%s\n", type->id,
|
||||||
type->label);
|
type->label);
|
||||||
@ -233,47 +234,39 @@ hook_pre_nosv(struct ovni_emu *emu)
|
|||||||
|
|
||||||
/* --------------------------- emit ------------------------------- */
|
/* --------------------------- 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
|
static void
|
||||||
emit_task_create(struct ovni_emu *emu)
|
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
|
static void
|
||||||
emit_task_execute(struct ovni_emu *emu)
|
emit_task_execute(struct ovni_emu *emu)
|
||||||
{
|
{
|
||||||
emit_prv(emu, 200, emu->cur_task->id + 1);
|
emu_emit_prv(emu, 200, emu->cur_task->id + 1);
|
||||||
emit_prv(emu, 300, emu->cur_task->type_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
|
static void
|
||||||
emit_task_pause(struct ovni_emu *emu)
|
emit_task_pause(struct ovni_emu *emu)
|
||||||
{
|
{
|
||||||
emit_prv(emu, 200, 0);
|
emu_emit_prv(emu, 200, 0);
|
||||||
emit_prv(emu, 300, 0);
|
emu_emit_prv(emu, 300, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
emit_task_resume(struct ovni_emu *emu)
|
emit_task_resume(struct ovni_emu *emu)
|
||||||
{
|
{
|
||||||
emit_prv(emu, 200, emu->cur_task->id + 1);
|
emu_emit_prv(emu, 200, emu->cur_task->id + 1);
|
||||||
emit_prv(emu, 300, emu->cur_task->type_id + 1);
|
emu_emit_prv(emu, 300, emu->cur_task->type_id + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
emit_task_end(struct ovni_emu *emu)
|
emit_task_end(struct ovni_emu *emu)
|
||||||
{
|
{
|
||||||
emit_prv(emu, 200, 0);
|
emu_emit_prv(emu, 200, 0);
|
||||||
emit_prv(emu, 300, 0);
|
emu_emit_prv(emu, 300, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -292,7 +285,7 @@ emit_task(struct ovni_emu *emu)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
hook_view_nosv(struct ovni_emu *emu)
|
hook_emit_nosv(struct ovni_emu *emu)
|
||||||
{
|
{
|
||||||
dbg("pre nosv\n");
|
dbg("pre nosv\n");
|
||||||
switch(emu->cur_ev->header.class)
|
switch(emu->cur_ev->header.class)
|
||||||
|
17
emu_ovni.c
17
emu_ovni.c
@ -326,7 +326,7 @@ hook_pre_ovni(struct ovni_emu *emu)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
view_thread_count(struct ovni_emu *emu)
|
emit_thread_count(struct ovni_emu *emu)
|
||||||
{
|
{
|
||||||
int i, n, cpu = -1;
|
int i, n, cpu = -1;
|
||||||
int64_t delta_time;
|
int64_t delta_time;
|
||||||
@ -364,15 +364,25 @@ emit:
|
|||||||
cpu+1, delta_time, n);
|
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
|
void
|
||||||
hook_view_ovni(struct ovni_emu *emu)
|
hook_emit_ovni(struct ovni_emu *emu)
|
||||||
{
|
{
|
||||||
switch(emu->cur_ev->header.class)
|
switch(emu->cur_ev->header.class)
|
||||||
{
|
{
|
||||||
case 'H':
|
case 'H':
|
||||||
case 'A':
|
case 'A':
|
||||||
case 'C':
|
case 'C':
|
||||||
view_thread_count(emu);
|
emit_thread_count(emu);
|
||||||
|
emit_current_pid(emu);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -391,4 +401,3 @@ hook_post_ovni(struct ovni_emu *emu)
|
|||||||
|
|
||||||
emu->vcpu.last_nthreads = emu->vcpu.nthreads;
|
emu->vcpu.last_nthreads = emu->vcpu.nthreads;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
102
ovni.c
102
ovni.c
@ -444,6 +444,31 @@ ovni_ev(struct ovni_ev *ev)
|
|||||||
ovni_ev_add(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
|
static int
|
||||||
load_thread(struct ovni_ethread *thread, int tid, char *filepath)
|
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
|
static int
|
||||||
load_proc(struct ovni_eproc *proc, char *procdir)
|
load_proc(struct ovni_eproc *proc, int pid, char *procdir)
|
||||||
{
|
{
|
||||||
struct dirent *dirent;
|
struct dirent *dirent;
|
||||||
DIR *dir;
|
DIR *dir;
|
||||||
char path[PATH_MAX];
|
char path[PATH_MAX];
|
||||||
char *p;
|
|
||||||
struct ovni_ethread *thread;
|
struct ovni_ethread *thread;
|
||||||
|
int tid;
|
||||||
|
|
||||||
|
proc->pid = pid;
|
||||||
|
|
||||||
if((dir = opendir(procdir)) == NULL)
|
if((dir = opendir(procdir)) == NULL)
|
||||||
{
|
{
|
||||||
@ -478,24 +505,24 @@ load_proc(struct ovni_eproc *proc, char *procdir)
|
|||||||
|
|
||||||
while((dirent = readdir(dir)) != NULL)
|
while((dirent = readdir(dir)) != NULL)
|
||||||
{
|
{
|
||||||
if(dirent->d_name[0] != 't')
|
if(find_dir_prefix(dirent, "thread", &tid) != 0)
|
||||||
continue;
|
|
||||||
p = strchr(dirent->d_name, '.');
|
|
||||||
if(p == NULL)
|
|
||||||
continue;
|
|
||||||
p++;
|
|
||||||
if(*p == '\0')
|
|
||||||
{
|
{
|
||||||
fprintf(stderr, "bad thread stream file: %s\n",
|
err("warning: ignoring bogus directory entry %s\n",
|
||||||
dirent->d_name);
|
dirent->d_name);
|
||||||
return -1;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
sprintf(path, "%s/%s", procdir, dirent->d_name);
|
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++];
|
thread = &proc->thread[proc->nthreads++];
|
||||||
|
|
||||||
if(load_thread(thread, atoi(p), path) != 0)
|
if(load_thread(thread, tid, path) != 0)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -505,38 +532,47 @@ load_proc(struct ovni_eproc *proc, char *procdir)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
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];
|
char path[PATH_MAX];
|
||||||
struct stat st;
|
struct stat st;
|
||||||
|
DIR *dir;
|
||||||
|
struct dirent *dirent;
|
||||||
|
struct ovni_eproc *proc;
|
||||||
|
|
||||||
for(proc=0; proc<OVNI_MAX_PROC; proc++)
|
if((dir = opendir(loomdir)) == NULL)
|
||||||
{
|
{
|
||||||
sprintf(path, "%s/proc.%d", loomdir, proc);
|
fprintf(stderr, "opendir %s failed: %s\n",
|
||||||
|
loomdir, strerror(errno));
|
||||||
if(stat(path, &st) != 0)
|
|
||||||
{
|
|
||||||
/* No more proc.N directories */
|
|
||||||
if(errno == ENOENT)
|
|
||||||
break;
|
|
||||||
|
|
||||||
fprintf(stderr, "cannot stat %s: %s\n", path,
|
|
||||||
strerror(errno));
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!S_ISDIR(st.st_mode))
|
while((dirent = readdir(dir)) != NULL)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "not a dir %s\n", path);
|
if(find_dir_prefix(dirent, "proc", &pid) != 0)
|
||||||
|
{
|
||||||
|
err("warning: ignoring bogus directory entry %s\n",
|
||||||
|
dirent->d_name);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
sprintf(path, "%s/%s", loomdir, dirent->d_name);
|
||||||
|
|
||||||
|
if(loom->nprocs >= OVNI_MAX_PROC)
|
||||||
|
{
|
||||||
|
err("too many process streams for loom %d\n",
|
||||||
|
loomid);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
proc = &loom->proc[loom->nprocs++];
|
||||||
|
|
||||||
|
if(load_proc(proc, pid, path) != 0)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(load_proc(&loom->proc[proc], path))
|
closedir(dir);
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
loom->nprocs = proc;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -553,7 +589,7 @@ ovni_load_trace(struct ovni_trace *trace, char *tracedir)
|
|||||||
|
|
||||||
sprintf(path, "%s/loom.%d", tracedir, loom);
|
sprintf(path, "%s/loom.%d", tracedir, loom);
|
||||||
|
|
||||||
if(load_loom(&trace->loom[loom], path))
|
if(load_loom(&trace->loom[loom], loom, path))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
trace->nlooms = nlooms;
|
trace->nlooms = nlooms;
|
||||||
|
Loading…
Reference in New Issue
Block a user