Add nosv task support

This commit is contained in:
Rodrigo Arias 2021-07-29 17:46:25 +02:00
parent 49198afbca
commit 56c86718fd
5 changed files with 1537 additions and 19 deletions

10
emu.c
View File

@ -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
View File

@ -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);

View File

@ -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();
}
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);
} }
int static void
emu_nosv_process_ev(struct ovni_emu *emu) 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 },
};

View File

@ -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

1227
uthash.h Normal file

File diff suppressed because it is too large Load Diff