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)
|
switch(emu->cur_ev->model)
|
||||||
{
|
{
|
||||||
case 'O': hook_pre_ovni(emu); break;
|
case 'O': hook_pre_ovni(emu); break;
|
||||||
|
case 'V': hook_pre_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;
|
||||||
@ -106,6 +107,7 @@ hook_view(struct ovni_emu *emu)
|
|||||||
switch(emu->cur_ev->model)
|
switch(emu->cur_ev->model)
|
||||||
{
|
{
|
||||||
case 'O': hook_view_ovni(emu); break;
|
case 'O': hook_view_ovni(emu); break;
|
||||||
|
case 'V': hook_view_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;
|
||||||
@ -144,6 +146,7 @@ next_event(struct ovni_emu *emu)
|
|||||||
struct ovni_ev *ev;
|
struct ovni_ev *ev;
|
||||||
struct ovni_stream *stream;
|
struct ovni_stream *stream;
|
||||||
struct ovni_trace *trace;
|
struct ovni_trace *trace;
|
||||||
|
static int64_t t0 = -1;
|
||||||
|
|
||||||
trace = &emu->trace;
|
trace = &emu->trace;
|
||||||
|
|
||||||
@ -184,6 +187,11 @@ next_event(struct ovni_emu *emu)
|
|||||||
|
|
||||||
emu->lastclock = ovni_ev_get_clock(&stream->last);
|
emu->lastclock = ovni_ev_get_clock(&stream->last);
|
||||||
|
|
||||||
|
if(t0 < 0)
|
||||||
|
t0 = emu->lastclock;
|
||||||
|
|
||||||
|
emu->delta_time = emu->lastclock - t0;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -272,6 +280,8 @@ main(int argc, char *argv[])
|
|||||||
if(ovni_load_streams(&emu.trace))
|
if(ovni_load_streams(&emu.trace))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
printf("#Paraver (19/01/38 at 03:14):00000000000000000000_ns:0:1:1(%d:1)\n", 10);
|
||||||
|
|
||||||
emulate(&emu);
|
emulate(&emu);
|
||||||
|
|
||||||
ovni_free_streams(&emu.trace);
|
ovni_free_streams(&emu.trace);
|
||||||
|
31
emu.h
31
emu.h
@ -2,6 +2,7 @@
|
|||||||
#define OVNI_EMU_H
|
#define OVNI_EMU_H
|
||||||
|
|
||||||
#include "ovni.h"
|
#include "ovni.h"
|
||||||
|
#include "uthash.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
/* Debug macros */
|
/* Debug macros */
|
||||||
@ -24,6 +25,23 @@ enum ethread_state {
|
|||||||
TH_ST_DEAD,
|
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 */
|
/* State of each emulated thread */
|
||||||
struct ovni_ethread {
|
struct ovni_ethread {
|
||||||
/* Emulated thread tid */
|
/* Emulated thread tid */
|
||||||
@ -39,6 +57,12 @@ struct ovni_ethread {
|
|||||||
|
|
||||||
/* Current cpu */
|
/* Current cpu */
|
||||||
struct ovni_cpu *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 */
|
/* State of each emulated process */
|
||||||
@ -132,6 +156,9 @@ struct ovni_emu {
|
|||||||
struct ovni_ethread *cur_thread;
|
struct ovni_ethread *cur_thread;
|
||||||
|
|
||||||
uint64_t lastclock;
|
uint64_t lastclock;
|
||||||
|
int64_t delta_time;
|
||||||
|
|
||||||
|
struct nosv_task *cur_task;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Emulator function declaration */
|
/* 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_view_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_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_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);
|
||||||
|
239
emu_nosv.c
239
emu_nosv.c
@ -1,13 +1,244 @@
|
|||||||
#include "ovni.h"
|
#include "ovni.h"
|
||||||
#include "ovni_trace.h"
|
#include "ovni_trace.h"
|
||||||
#include "emu.h"
|
#include "emu.h"
|
||||||
|
#include "uthash.h"
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
int
|
struct nosv_task *tasks = NULL;
|
||||||
emu_nosv_thread_init(struct ovni_emu *emu, struct ovni_ethread *thread)
|
|
||||||
|
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
|
task->id = emu->cur_ev->payload.i32[0];
|
||||||
emu_nosv_process_ev(struct ovni_emu *emu)
|
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);
|
assert(emu->cur_thread->state != TH_ST_RUNNING);
|
||||||
|
|
||||||
cpuid = emu->cur_ev->payload.i32[0];
|
cpuid = emu->cur_ev->payload.i32[0];
|
||||||
dbg("thread %d runs in cpuid %d\n", emu->cur_thread->tid,
|
//dbg("thread %d runs in cpuid %d\n", emu->cur_thread->tid,
|
||||||
cpuid);
|
// cpuid);
|
||||||
cpu = emu_get_cpu(emu, cpuid);
|
cpu = emu_get_cpu(emu, cpuid);
|
||||||
|
|
||||||
emu->cur_thread->state = TH_ST_RUNNING;
|
emu->cur_thread->state = TH_ST_RUNNING;
|
||||||
@ -152,7 +152,7 @@ ev_thread(struct ovni_emu *emu)
|
|||||||
struct ovni_ethread *thread, *remote_thread;
|
struct ovni_ethread *thread, *remote_thread;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
emu_emit(emu);
|
//emu_emit(emu);
|
||||||
|
|
||||||
thread = emu->cur_thread;
|
thread = emu->cur_thread;
|
||||||
cpu = thread->cpu;
|
cpu = thread->cpu;
|
||||||
@ -196,7 +196,7 @@ ev_affinity_set(struct ovni_emu *emu)
|
|||||||
|
|
||||||
emu->cur_thread->cpu = newcpu;
|
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
|
static void
|
||||||
@ -223,14 +223,14 @@ ev_affinity_remote(struct ovni_emu *emu)
|
|||||||
|
|
||||||
thread->cpu = newcpu;
|
thread->cpu = newcpu;
|
||||||
|
|
||||||
dbg("thread %d switches to cpu %d by remote petition\n", tid,
|
//dbg("thread %d switches to cpu %d by remote petition\n", tid,
|
||||||
cpuid);
|
// cpuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ev_affinity(struct ovni_emu *emu)
|
ev_affinity(struct ovni_emu *emu)
|
||||||
{
|
{
|
||||||
emu_emit(emu);
|
//emu_emit(emu);
|
||||||
switch(emu->cur_ev->value)
|
switch(emu->cur_ev->value)
|
||||||
{
|
{
|
||||||
case 's': ev_affinity_set(emu); break;
|
case 's': ev_affinity_set(emu); break;
|
||||||
@ -322,27 +322,46 @@ hook_pre_ovni(struct ovni_emu *emu)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
print_threads_state(emu);
|
//print_threads_state(emu);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
view_thread_count(struct ovni_emu *emu)
|
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 */
|
/* Check every CPU looking for a change in nthreads */
|
||||||
for(i=0; i<emu->ncpus; i++)
|
for(i=0; i<emu->ncpus; i++)
|
||||||
{
|
{
|
||||||
if(emu->cpu[i].last_nthreads == emu->cpu[i].nthreads)
|
if(emu->cpu[i].last_nthreads != emu->cpu[i].nthreads)
|
||||||
continue;
|
{
|
||||||
|
cpu = i + 1;
|
||||||
/* Emit the number of threads in the cpu */
|
n = emu->cpu[i].nthreads;
|
||||||
dbg("cpu %d runs %d threads\n", i, emu->cpu[i].nthreads);
|
goto emit;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Same with the virtual CPU */
|
/* Same with the virtual CPU */
|
||||||
if(emu->vcpu.last_nthreads != emu->vcpu.nthreads)
|
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
|
void
|
||||||
|
Loading…
Reference in New Issue
Block a user