From fa9196fd6304478e18f1cc4ba87dd6e2845a7bd2 Mon Sep 17 00:00:00 2001 From: Rodrigo Arias Date: Wed, 1 Jun 2022 16:30:46 +0200 Subject: [PATCH] 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. --- emu.c | 11 ++++++++- emu.h | 11 +++++---- emu_nosv.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 80 insertions(+), 7 deletions(-) diff --git a/emu.c b/emu.c index b7d24c2..d447c25 100644 --- a/emu.c +++ b/emu.c @@ -268,6 +268,12 @@ hook_init(struct ovni_emu *emu) hook_init_kernel(emu); } +static void +hook_end(struct ovni_emu *emu) +{ + hook_end_nosv(emu); +} + static void hook_pre(struct ovni_emu *emu) { @@ -520,6 +526,8 @@ emulate(struct ovni_emu *emu) emu_step_stream(emu, emu->cur_stream); } + hook_end(emu); + print_progress(emu); } @@ -991,6 +999,7 @@ init_threads(struct ovni_emu *emu) size_t i, j, k, gi; emu->total_nthreads = 0; + emu->total_nprocs = 0; trace = &emu->trace; @@ -1000,10 +1009,10 @@ init_threads(struct ovni_emu *emu) for(j=0; jnprocs; j++) { proc = &loom->proc[j]; + emu->total_nprocs++; for(k=0; knthreads; k++) { thread = &proc->thread[k]; - emu->total_nthreads++; } } diff --git a/emu.h b/emu.h index fee5aa9..1d4488e 100644 --- a/emu.h +++ b/emu.h @@ -120,8 +120,9 @@ struct nosv_task { }; struct nosv_task_type { - int id; - const char *label; + int gid; /* Global identifier */ + int id; /* Per-process identifier */ + char label[MAX_PCF_LABEL]; UT_hash_handle hh; }; @@ -329,7 +330,6 @@ struct ovni_eproc { struct nosv_task_type *types; struct nosv_task *tasks; - }; @@ -476,9 +476,11 @@ struct ovni_emu { /* Total counters */ size_t total_nthreads; - size_t total_proc; + size_t total_nprocs; size_t total_ncpus; + uint32_t nosv_type_counter; + /* Keep a list of dirty channels for the CPUs and threads */ struct ovni_chan *cpu_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_pre_nosv(struct ovni_emu *emu); +void hook_end_nosv(struct ovni_emu *emu); void hook_init_tampi(struct ovni_emu *emu); void hook_pre_tampi(struct ovni_emu *emu); diff --git a/emu_nosv.c b/emu_nosv.c index 47a86b9..db70d81 100644 --- a/emu_nosv.c +++ b/emu_nosv.c @@ -209,7 +209,6 @@ pre_task_resume(struct ovni_emu *emu) dbg("task id=%d resumes\n", task->id); } - static void 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 pre_type_create(struct ovni_emu *emu) { @@ -387,7 +398,14 @@ pre_type_create(struct ovni_emu *emu) } 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 */ HASH_ADD_INT(emu->cur_proc->types, id, type); @@ -582,3 +600,46 @@ hook_pre_nosv(struct ovni_emu *emu) if(emu->enable_linter) 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); + } + } + } +}