Add support for nOS-V task types

Use a unique identifier for each type, so we don't mix types with the
same id per-process.
This commit is contained in:
Rodrigo Arias 2022-06-01 16:30:46 +02:00
parent ca6c85b2fb
commit fa9196fd63
3 changed files with 80 additions and 7 deletions

11
emu.c
View File

@ -268,6 +268,12 @@ hook_init(struct ovni_emu *emu)
hook_init_kernel(emu); hook_init_kernel(emu);
} }
static void
hook_end(struct ovni_emu *emu)
{
hook_end_nosv(emu);
}
static void static void
hook_pre(struct ovni_emu *emu) hook_pre(struct ovni_emu *emu)
{ {
@ -520,6 +526,8 @@ emulate(struct ovni_emu *emu)
emu_step_stream(emu, emu->cur_stream); emu_step_stream(emu, emu->cur_stream);
} }
hook_end(emu);
print_progress(emu); print_progress(emu);
} }
@ -991,6 +999,7 @@ init_threads(struct ovni_emu *emu)
size_t i, j, k, gi; size_t i, j, k, gi;
emu->total_nthreads = 0; emu->total_nthreads = 0;
emu->total_nprocs = 0;
trace = &emu->trace; trace = &emu->trace;
@ -1000,10 +1009,10 @@ init_threads(struct ovni_emu *emu)
for(j=0; j<loom->nprocs; j++) for(j=0; j<loom->nprocs; j++)
{ {
proc = &loom->proc[j]; proc = &loom->proc[j];
emu->total_nprocs++;
for(k=0; k<proc->nthreads; k++) for(k=0; k<proc->nthreads; k++)
{ {
thread = &proc->thread[k]; thread = &proc->thread[k];
emu->total_nthreads++; emu->total_nthreads++;
} }
} }

11
emu.h
View File

@ -120,8 +120,9 @@ struct nosv_task {
}; };
struct nosv_task_type { struct nosv_task_type {
int id; int gid; /* Global identifier */
const char *label; int id; /* Per-process identifier */
char label[MAX_PCF_LABEL];
UT_hash_handle hh; UT_hash_handle hh;
}; };
@ -329,7 +330,6 @@ struct ovni_eproc {
struct nosv_task_type *types; struct nosv_task_type *types;
struct nosv_task *tasks; struct nosv_task *tasks;
}; };
@ -476,9 +476,11 @@ struct ovni_emu {
/* Total counters */ /* Total counters */
size_t total_nthreads; size_t total_nthreads;
size_t total_proc; size_t total_nprocs;
size_t total_ncpus; size_t total_ncpus;
uint32_t nosv_type_counter;
/* Keep a list of dirty channels for the CPUs and threads */ /* Keep a list of dirty channels for the CPUs and threads */
struct ovni_chan *cpu_chan; struct ovni_chan *cpu_chan;
struct ovni_chan *th_chan; struct ovni_chan *th_chan;
@ -493,6 +495,7 @@ void hook_pre_ovni(struct ovni_emu *emu);
void hook_init_nosv(struct ovni_emu *emu); void hook_init_nosv(struct ovni_emu *emu);
void hook_pre_nosv(struct ovni_emu *emu); void hook_pre_nosv(struct ovni_emu *emu);
void hook_end_nosv(struct ovni_emu *emu);
void hook_init_tampi(struct ovni_emu *emu); void hook_init_tampi(struct ovni_emu *emu);
void hook_pre_tampi(struct ovni_emu *emu); void hook_pre_tampi(struct ovni_emu *emu);

View File

@ -209,7 +209,6 @@ pre_task_resume(struct ovni_emu *emu)
dbg("task id=%d resumes\n", task->id); dbg("task id=%d resumes\n", task->id);
} }
static void static void
pre_task_end(struct ovni_emu *emu) pre_task_end(struct ovni_emu *emu)
{ {
@ -350,6 +349,18 @@ pre_task(struct ovni_emu *emu)
} }
} }
static uint32_t
get_task_type_gid(struct ovni_emu *emu, struct ovni_eproc *proc, uint32_t id)
{
/* Don't use emu->cur_proc, so we can use it at any point */
uint32_t gid = id * emu->total_nprocs + proc->gindex;
if (gid == 0)
die("invalid global task type id %d\n", gid);
return gid;
}
static void static void
pre_type_create(struct ovni_emu *emu) pre_type_create(struct ovni_emu *emu)
{ {
@ -387,7 +398,14 @@ pre_type_create(struct ovni_emu *emu)
} }
type->id = *typeid; type->id = *typeid;
type->label = label;
if(type->id == 0)
die("invalid task type id %d\n", type->id);
type->gid = get_task_type_gid(emu, emu->cur_proc, type->id);
int n = snprintf(type->label, MAX_PCF_LABEL, "%s", label);
if(n >= MAX_PCF_LABEL)
die("task label too long: %s\n", label);
/* Add the new task type to the hash table */ /* Add the new task type to the hash table */
HASH_ADD_INT(emu->cur_proc->types, id, type); HASH_ADD_INT(emu->cur_proc->types, id, type);
@ -582,3 +600,46 @@ hook_pre_nosv(struct ovni_emu *emu)
if(emu->enable_linter) if(emu->enable_linter)
check_affinity(emu); check_affinity(emu);
} }
static void
create_pcf_task_types(struct ovni_eproc *proc, struct pcf_type *pcftype)
{
char buf[MAX_PCF_LABEL];
/* Emit types for all task types */
struct nosv_task_type *tt;
for(tt = proc->types; tt != NULL; tt=tt->hh.next)
{
/* Use a unique identifier for the task types */
int value = tt->gid;
int n = snprintf(buf, MAX_PCF_LABEL, "%s (%d)",
tt->label, tt->id);
if(n >= MAX_PCF_LABEL)
die("generated label too long: %s\n", buf);
pcf_add_value(pcftype, value, buf);
}
}
void
hook_end_nosv(struct ovni_emu *emu)
{
/* Emit types for all channel types and processes */
for(enum chan_type ct = 0; ct < CHAN_MAXTYPE; ct++)
{
struct pcf_file *pcf = &emu->pcf[ct];
int typeid = chan_to_prvtype[CHAN_NOSV_TYPEID][ct];
struct pcf_type *pcftype = pcf_find_type(pcf, typeid);
for(size_t i = 0; i < emu->trace.nlooms; i++)
{
struct ovni_loom *loom = &emu->trace.loom[i];
for(size_t j = 0; j < loom->nprocs; j++)
{
struct ovni_eproc *proc = &loom->proc[j];
create_pcf_task_types(proc, pcftype);
}
}
}
}