Add nosv task support
This commit is contained in:
parent
49198afbca
commit
56c86718fd
10
emu.c
10
emu.c
@ -92,6 +92,7 @@ hook_pre(struct ovni_emu *emu)
|
||||
switch(emu->cur_ev->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);
|
||||
break;
|
||||
@ -106,6 +107,7 @@ hook_view(struct ovni_emu *emu)
|
||||
switch(emu->cur_ev->model)
|
||||
{
|
||||
case 'O': hook_view_ovni(emu); break;
|
||||
case 'V': hook_view_nosv(emu); break;
|
||||
default:
|
||||
//dbg("unknown model %c\n", emu->cur_ev->model);
|
||||
break;
|
||||
@ -144,6 +146,7 @@ next_event(struct ovni_emu *emu)
|
||||
struct ovni_ev *ev;
|
||||
struct ovni_stream *stream;
|
||||
struct ovni_trace *trace;
|
||||
static int64_t t0 = -1;
|
||||
|
||||
trace = &emu->trace;
|
||||
|
||||
@ -184,6 +187,11 @@ next_event(struct ovni_emu *emu)
|
||||
|
||||
emu->lastclock = ovni_ev_get_clock(&stream->last);
|
||||
|
||||
if(t0 < 0)
|
||||
t0 = emu->lastclock;
|
||||
|
||||
emu->delta_time = emu->lastclock - t0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -272,6 +280,8 @@ main(int argc, char *argv[])
|
||||
if(ovni_load_streams(&emu.trace))
|
||||
return 1;
|
||||
|
||||
printf("#Paraver (19/01/38 at 03:14):00000000000000000000_ns:0:1:1(%d:1)\n", 10);
|
||||
|
||||
emulate(&emu);
|
||||
|
||||
ovni_free_streams(&emu.trace);
|
||||
|
31
emu.h
31
emu.h
@ -2,6 +2,7 @@
|
||||
#define OVNI_EMU_H
|
||||
|
||||
#include "ovni.h"
|
||||
#include "uthash.h"
|
||||
#include <stdio.h>
|
||||
|
||||
/* Debug macros */
|
||||
@ -24,6 +25,23 @@ enum ethread_state {
|
||||
TH_ST_DEAD,
|
||||
};
|
||||
|
||||
|
||||
enum nosv_task_state {
|
||||
TASK_ST_CREATED,
|
||||
TASK_ST_RUNNING,
|
||||
TASK_ST_PAUSED,
|
||||
TASK_ST_DEAD,
|
||||
};
|
||||
|
||||
struct ovni_ethread;
|
||||
|
||||
struct nosv_task {
|
||||
int id;
|
||||
struct ovni_ethread *thread;
|
||||
enum nosv_task_state state;
|
||||
UT_hash_handle hh;
|
||||
};
|
||||
|
||||
/* State of each emulated thread */
|
||||
struct ovni_ethread {
|
||||
/* Emulated thread tid */
|
||||
@ -39,6 +57,12 @@ struct ovni_ethread {
|
||||
|
||||
/* Current cpu */
|
||||
struct ovni_cpu *cpu;
|
||||
|
||||
/* FIXME: Use a table with registrable pointers to custom data
|
||||
* structures */
|
||||
|
||||
/* nosv task */
|
||||
struct nosv_task *task;
|
||||
};
|
||||
|
||||
/* State of each emulated process */
|
||||
@ -132,6 +156,9 @@ struct ovni_emu {
|
||||
struct ovni_ethread *cur_thread;
|
||||
|
||||
uint64_t lastclock;
|
||||
int64_t delta_time;
|
||||
|
||||
struct nosv_task *cur_task;
|
||||
};
|
||||
|
||||
/* Emulator function declaration */
|
||||
@ -142,6 +169,10 @@ void hook_pre_ovni(struct ovni_emu *emu);
|
||||
void hook_view_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_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);
|
||||
|
239
emu_nosv.c
239
emu_nosv.c
@ -1,13 +1,244 @@
|
||||
#include "ovni.h"
|
||||
#include "ovni_trace.h"
|
||||
#include "emu.h"
|
||||
#include "uthash.h"
|
||||
#include <assert.h>
|
||||
|
||||
int
|
||||
emu_nosv_thread_init(struct ovni_emu *emu, struct ovni_ethread *thread)
|
||||
struct nosv_task *tasks = NULL;
|
||||
|
||||
struct hook_entry {
|
||||
char id[4];
|
||||
void (*hook)(struct ovni_emu *);
|
||||
};
|
||||
|
||||
static void
|
||||
pre_task_create(struct ovni_emu *emu)
|
||||
{
|
||||
struct nosv_task *task, *p = NULL;
|
||||
|
||||
task = malloc(sizeof(*task));
|
||||
|
||||
if(task == NULL)
|
||||
{
|
||||
perror("malloc");
|
||||
abort();
|
||||
}
|
||||
|
||||
int
|
||||
emu_nosv_process_ev(struct ovni_emu *emu)
|
||||
task->id = emu->cur_ev->payload.i32[0];
|
||||
task->state = TASK_ST_CREATED;
|
||||
|
||||
/* Ensure the task id is new */
|
||||
HASH_FIND_INT(tasks, &task->id, p);
|
||||
|
||||
if(p != NULL)
|
||||
{
|
||||
err("A task with id %d already exists\n", task->id);
|
||||
abort();
|
||||
}
|
||||
|
||||
/* Add the new task to the hash table */
|
||||
HASH_ADD_INT(tasks, id, task);
|
||||
|
||||
emu->cur_task = task;
|
||||
|
||||
dbg("new task created id=%d\n", task->id);
|
||||
}
|
||||
|
||||
static void
|
||||
pre_task_execute(struct ovni_emu *emu)
|
||||
{
|
||||
struct nosv_task *task;
|
||||
int taskid;
|
||||
|
||||
taskid = emu->cur_ev->payload.i32[0];
|
||||
|
||||
HASH_FIND_INT(tasks, &taskid, task);
|
||||
|
||||
assert(task != NULL);
|
||||
assert(emu->cur_thread->state == TH_ST_RUNNING);
|
||||
assert(emu->cur_thread->task == NULL);
|
||||
|
||||
task->state = TASK_ST_RUNNING;
|
||||
task->thread = emu->cur_thread;
|
||||
emu->cur_thread->task = task;
|
||||
|
||||
emu->cur_task = task;
|
||||
|
||||
dbg("task id=%d runs now\n", task->id);
|
||||
}
|
||||
|
||||
static void
|
||||
pre_task_pause(struct ovni_emu *emu)
|
||||
{
|
||||
struct nosv_task *task;
|
||||
int taskid;
|
||||
|
||||
taskid = emu->cur_ev->payload.i32[0];
|
||||
|
||||
HASH_FIND_INT(tasks, &taskid, task);
|
||||
|
||||
assert(task != NULL);
|
||||
assert(task->state == TASK_ST_RUNNING);
|
||||
assert(emu->cur_thread->state == TH_ST_RUNNING);
|
||||
assert(emu->cur_thread->task == task);
|
||||
assert(emu->cur_thread == task->thread);
|
||||
|
||||
task->state = TASK_ST_PAUSED;
|
||||
|
||||
emu->cur_task = task;
|
||||
|
||||
dbg("task id=%d pauses\n", task->id);
|
||||
}
|
||||
|
||||
static void
|
||||
pre_task_resume(struct ovni_emu *emu)
|
||||
{
|
||||
struct nosv_task *task;
|
||||
int taskid;
|
||||
|
||||
taskid = emu->cur_ev->payload.i32[0];
|
||||
|
||||
HASH_FIND_INT(tasks, &taskid, task);
|
||||
|
||||
assert(task != NULL);
|
||||
assert(task->state == TASK_ST_PAUSED);
|
||||
assert(emu->cur_thread->state == TH_ST_RUNNING);
|
||||
assert(emu->cur_thread->task == task);
|
||||
assert(emu->cur_thread == task->thread);
|
||||
|
||||
task->state = TASK_ST_RUNNING;
|
||||
|
||||
emu->cur_task = task;
|
||||
|
||||
dbg("task id=%d resumes\n", task->id);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
pre_task_end(struct ovni_emu *emu)
|
||||
{
|
||||
struct nosv_task *task;
|
||||
int taskid;
|
||||
|
||||
taskid = emu->cur_ev->payload.i32[0];
|
||||
|
||||
/* Ensure the task id is new */
|
||||
HASH_FIND_INT(tasks, &taskid, task);
|
||||
|
||||
assert(task != NULL);
|
||||
assert(task->state == TASK_ST_RUNNING);
|
||||
assert(emu->cur_thread->state == TH_ST_RUNNING);
|
||||
assert(emu->cur_thread->task == task);
|
||||
assert(emu->cur_thread == task->thread);
|
||||
|
||||
task->state = TASK_ST_DEAD;
|
||||
task->thread = NULL;
|
||||
emu->cur_thread->task = NULL;
|
||||
|
||||
emu->cur_task = task;
|
||||
|
||||
dbg("task id=%d ends\n", task->id);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
pre_task(struct ovni_emu *emu)
|
||||
{
|
||||
emu_emit(emu);
|
||||
switch(emu->cur_ev->value)
|
||||
{
|
||||
case 'c': pre_task_create(emu); break;
|
||||
case 'x': pre_task_execute(emu); break;
|
||||
case 'e': pre_task_end(emu); break;
|
||||
case 'p': pre_task_pause(emu); break;
|
||||
case 'r': pre_task_resume(emu); break;
|
||||
default:
|
||||
emu->cur_task = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
hook_pre_nosv(struct ovni_emu *emu)
|
||||
{
|
||||
dbg("pre nosv\n");
|
||||
switch(emu->cur_ev->class)
|
||||
{
|
||||
case 'T': pre_task(emu); break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* --------------------------- views ------------------------------- */
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
static void
|
||||
emit_task_execute(struct ovni_emu *emu)
|
||||
{
|
||||
emit_prv(emu, 200, emu->cur_task->id + 1);
|
||||
}
|
||||
|
||||
static void
|
||||
emit_task_pause(struct ovni_emu *emu)
|
||||
{
|
||||
emit_prv(emu, 200, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
emit_task_resume(struct ovni_emu *emu)
|
||||
{
|
||||
emit_prv(emu, 200, emu->cur_task->id + 1);
|
||||
}
|
||||
|
||||
static void
|
||||
emit_task_end(struct ovni_emu *emu)
|
||||
{
|
||||
emit_prv(emu, 200, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
emit_task(struct ovni_emu *emu)
|
||||
{
|
||||
switch(emu->cur_ev->value)
|
||||
{
|
||||
case 'c': emit_task_create(emu); break;
|
||||
case 'x': emit_task_execute(emu); break;
|
||||
case 'p': emit_task_pause(emu); break;
|
||||
case 'r': emit_task_resume(emu); break;
|
||||
case 'e': emit_task_end(emu); break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
hook_view_nosv(struct ovni_emu *emu)
|
||||
{
|
||||
dbg("pre nosv\n");
|
||||
switch(emu->cur_ev->class)
|
||||
{
|
||||
case 'T': emit_task(emu); break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
struct hook_entry pre_hooks[] = {
|
||||
{ "VTc", pre_task_create },
|
||||
{ "VTx", pre_task_create },
|
||||
};
|
||||
|
49
emu_ovni.c
49
emu_ovni.c
@ -100,8 +100,8 @@ ev_thread_execute(struct ovni_emu *emu)
|
||||
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);
|
||||
//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;
|
||||
@ -152,7 +152,7 @@ ev_thread(struct ovni_emu *emu)
|
||||
struct ovni_ethread *thread, *remote_thread;
|
||||
int i;
|
||||
|
||||
emu_emit(emu);
|
||||
//emu_emit(emu);
|
||||
|
||||
thread = emu->cur_thread;
|
||||
cpu = thread->cpu;
|
||||
@ -196,7 +196,7 @@ ev_affinity_set(struct ovni_emu *emu)
|
||||
|
||||
emu->cur_thread->cpu = newcpu;
|
||||
|
||||
dbg("cpu %d now runs %d\n", cpuid, emu->cur_thread->tid);
|
||||
//dbg("cpu %d now runs %d\n", cpuid, emu->cur_thread->tid);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -223,14 +223,14 @@ ev_affinity_remote(struct ovni_emu *emu)
|
||||
|
||||
thread->cpu = newcpu;
|
||||
|
||||
dbg("thread %d switches to cpu %d by remote petition\n", tid,
|
||||
cpuid);
|
||||
//dbg("thread %d switches to cpu %d by remote petition\n", tid,
|
||||
// cpuid);
|
||||
}
|
||||
|
||||
static void
|
||||
ev_affinity(struct ovni_emu *emu)
|
||||
{
|
||||
emu_emit(emu);
|
||||
//emu_emit(emu);
|
||||
switch(emu->cur_ev->value)
|
||||
{
|
||||
case 's': ev_affinity_set(emu); break;
|
||||
@ -322,27 +322,46 @@ hook_pre_ovni(struct ovni_emu *emu)
|
||||
break;
|
||||
}
|
||||
|
||||
print_threads_state(emu);
|
||||
//print_threads_state(emu);
|
||||
}
|
||||
|
||||
static void
|
||||
view_thread_count(struct ovni_emu *emu)
|
||||
{
|
||||
int i;
|
||||
int i, n, cpu = -1;
|
||||
int64_t delta_time;
|
||||
static int64_t t0 = -1;
|
||||
|
||||
if(t0 < 0)
|
||||
t0 = ovni_ev_get_clock(emu->cur_ev);
|
||||
|
||||
delta_time = ovni_ev_get_clock(emu->cur_ev) - t0;
|
||||
|
||||
/* Check every CPU looking for a change in nthreads */
|
||||
for(i=0; i<emu->ncpus; i++)
|
||||
{
|
||||
if(emu->cpu[i].last_nthreads == emu->cpu[i].nthreads)
|
||||
continue;
|
||||
|
||||
/* Emit the number of threads in the cpu */
|
||||
dbg("cpu %d runs %d threads\n", i, emu->cpu[i].nthreads);
|
||||
if(emu->cpu[i].last_nthreads != emu->cpu[i].nthreads)
|
||||
{
|
||||
cpu = i + 1;
|
||||
n = emu->cpu[i].nthreads;
|
||||
goto emit;
|
||||
}
|
||||
}
|
||||
|
||||
/* Same with the virtual CPU */
|
||||
if(emu->vcpu.last_nthreads != emu->vcpu.nthreads)
|
||||
dbg("vpu runs %d threads\n", emu->vcpu.nthreads);
|
||||
{
|
||||
cpu = 0;
|
||||
n = emu->vcpu.nthreads;
|
||||
goto emit;
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
emit:
|
||||
|
||||
printf("2:0:1:1:%d:%ld:100:%d\n",
|
||||
cpu+1, delta_time, n);
|
||||
}
|
||||
|
||||
void
|
||||
|
Loading…
Reference in New Issue
Block a user