Finish task types in PCF for nanos6

This commit is contained in:
Rodrigo Arias 2023-02-02 16:23:20 +01:00 committed by Rodrigo Arias Mallo
parent dbea90f525
commit a91b1c554a
11 changed files with 155 additions and 20 deletions

View File

@ -43,6 +43,7 @@ add_library(emu STATIC
nanos6/create.c nanos6/create.c
nanos6/event.c nanos6/event.c
nanos6/pvt.c nanos6/pvt.c
nanos6/finish.c
) )
add_executable(ovniemu ovniemu.c) add_executable(ovniemu ovniemu.c)

View File

@ -160,9 +160,15 @@ emu_step(struct emu *emu)
int int
emu_finish(struct emu *emu) emu_finish(struct emu *emu)
{ {
if (model_finish(&emu->model, emu) != 0) {
err("model_finish failed");
return -1;
}
if (recorder_finish(&emu->recorder) != 0) { if (recorder_finish(&emu->recorder) != 0) {
err("recorder_finish failed"); err("recorder_finish failed");
return -1; return -1;
} }
return 0; return 0;
} }

View File

@ -105,3 +105,22 @@ model_event(struct model *model, struct emu *emu, int index)
return 0; return 0;
} }
int
model_finish(struct model *model, struct emu *emu)
{
for (int i = 0; i < MAX_MODELS; i++) {
if (!model->enabled[i])
continue;
struct model_spec *spec = model->spec[i];
if (spec->finish == NULL)
continue;
if (spec->finish(emu) != 0) {
err("finish failed for model '%c'", (char) i);
return -1;
}
}
return 0;
}

View File

@ -14,6 +14,7 @@ struct model_spec {
emu_hook_t *create; emu_hook_t *create;
emu_hook_t *connect; emu_hook_t *connect;
emu_hook_t *event; emu_hook_t *event;
emu_hook_t *finish;
}; };
#define MAX_MODELS 256 #define MAX_MODELS 256
@ -31,5 +32,6 @@ int model_probe(struct model *model, struct emu *emu);
int model_create(struct model *model, struct emu *emu); int model_create(struct model *model, struct emu *emu);
int model_connect(struct model *model, struct emu *emu); int model_connect(struct model *model, struct emu *emu);
int model_event(struct model *model, struct emu *emu, int index); int model_event(struct model *model, struct emu *emu, int index);
int model_finish(struct model *model, struct emu *emu);
#endif /* MODEL_H */ #endif /* MODEL_H */

44
src/emu/nanos6/finish.c Normal file
View File

@ -0,0 +1,44 @@
#include "nanos6_priv.h"
static int
end_lint(struct emu *emu)
{
struct system *sys = &emu->system;
/* Ensure we run out of subsystem states */
for (struct thread *t = sys->threads; t; t = t->gnext) {
struct nanos6_thread *th = EXT(t, '6');
struct chan *ch = &th->ch[CH_SUBSYSTEM];
int stacked = ch->data.stack.n;
if (stacked > 0) {
struct value top;
if (chan_read(ch, &top) != 0) {
err("chan_read failed for subsystem");
return -1;
}
err("thread %d ended with %d stacked nanos6 subsystems, top=\"%s\"\n",
t->tid, stacked, ss_name(top.i));
return -1;
}
}
return 0;
}
int
nanos6_finish(struct emu *emu)
{
if (finish_pvt(emu) != 0) {
err("finish_pvt failed");
return -1;
}
/* When running in linter mode perform additional checks */
if (emu->args.linter_mode && end_lint(emu) != 0) {
err("end_lint failed");
return -1;
}
return 0;
}

View File

@ -98,7 +98,10 @@ int nanos6_probe(struct emu *emu);
int nanos6_create(struct emu *emu); int nanos6_create(struct emu *emu);
int nanos6_connect(struct emu *emu); int nanos6_connect(struct emu *emu);
int nanos6_event(struct emu *emu); int nanos6_event(struct emu *emu);
int nanos6_finish(struct emu *emu);
int init_pvt(struct emu *emu); int init_pvt(struct emu *emu);
int finish_pvt(struct emu *emu);
const char *ss_name(int ss);
#endif /* NANOS6_PRIV_H */ #endif /* NANOS6_PRIV_H */

View File

@ -7,6 +7,7 @@ struct model_spec model_nanos6 = {
.connect = nanos6_connect, .connect = nanos6_connect,
.event = nanos6_event, .event = nanos6_event,
.probe = nanos6_probe, .probe = nanos6_probe,
.finish = nanos6_finish,
}; };
int int

View File

@ -1,6 +1,12 @@
#include "nanos6_priv.h" #include "nanos6_priv.h"
/* TODO: Assign types on runtime and generate configs */ /* TODO: Assign types on runtime and generate configs */
static const char *pvt_name[CT_MAX] = {
[CT_TH] = "thread",
[CT_CPU] = "cpu",
};
static const int pvt_type[] = { static const int pvt_type[] = {
[CH_TASKID] = 35, [CH_TASKID] = 35,
[CH_TYPE] = 36, [CH_TYPE] = 36,
@ -240,3 +246,48 @@ init_pvt(struct emu *emu)
return 0; return 0;
} }
int
finish_pvt(struct emu *emu)
{
struct system *sys = &emu->system;
/* Emit task types for all channel types and processes */
for (enum chan_type ct = 0; ct < CHAN_MAXTYPE; ct++) {
struct pvt *pvt = recorder_find_pvt(&emu->recorder, pvt_name[ct]);
if (pvt == NULL) {
err("cannot find pvt with name '%s'", pvt_name[ct]);
return -1;
}
struct pcf *pcf = pvt_get_pcf(pvt);
long typeid = pvt_type[CH_TYPE];
struct pcf_type *pcftype = pcf_find_type(pcf, typeid);
for (struct proc *p = sys->procs; p; p = p->gnext) {
struct nanos6_proc *nanos6proc = EXT(p, '6');
struct task_info *info = &nanos6proc->task_info;
if (task_create_pcf_types(pcftype, info->types) != 0) {
err("task_create_pcf_types failed");
return -1;
}
}
}
return 0;
}
const char *
ss_name(int ss)
{
static const char *unknown = "(unknown)";
const char *name = unknown;
const struct pcf_value_label *pv;
for (pv = &nanos6_ss_values[0]; pv->label; pv++) {
if (pv->value == ss) {
name = pv->label;
break;
}
}
return name;
}

View File

@ -5,6 +5,7 @@
#include "uthash.h" #include "uthash.h"
#include "utlist.h" #include "utlist.h"
#include "pcf.h"
struct task * struct task *
task_find(struct task *tasks, uint32_t task_id) task_find(struct task *tasks, uint32_t task_id)
@ -281,24 +282,31 @@ task_type_create(struct task_info *info, uint32_t type_id, const char *label)
return 0; return 0;
} }
//void int
//task_create_pcf_types(struct pcf_type *pcftype, struct task_type *types) task_create_pcf_types(struct pcf_type *pcftype, struct task_type *types)
//{ {
// /* Emit types for all task types */ int ret = 0;
// for (struct task_type *tt = types; tt != NULL; tt = tt->hh.next) {
// struct pcf_value *pcfvalue = pcf_find_value(pcftype, tt->gid); /* Emit types for all task types */
// if (pcfvalue != NULL) { for (struct task_type *tt = types; tt != NULL; tt = tt->hh.next) {
// /* Ensure the label is the same, so we know that struct pcf_value *pcfvalue = pcf_find_value(pcftype, tt->gid);
// * no collision occurred */ if (pcfvalue != NULL) {
// if (strcmp(pcfvalue->label, tt->label) != 0) /* Ensure the label is the same, so we know that
// die("collision occurred in task type labels"); * no collision occurred */
// else if (strcmp(pcfvalue->label, tt->label) != 0) {
// continue; err("collision occurred in task type labels: %s and %s",
// } pcfvalue->label, tt->label);
// ret = -1;
// pcf_add_value(pcftype, tt->gid, tt->label); } else {
// } continue;
//} }
}
pcf_add_value(pcftype, tt->gid, tt->label);
}
return ret;
}
struct task * struct task *
task_get_running(struct task_stack *stack) task_get_running(struct task_stack *stack)

View File

@ -64,7 +64,7 @@ int task_end(struct task_stack *stack, struct task *task);
struct task_type *task_type_find(struct task_type *types, uint32_t type_id); struct task_type *task_type_find(struct task_type *types, uint32_t type_id);
int task_type_create(struct task_info *info, uint32_t type_id, const char *label); int task_type_create(struct task_info *info, uint32_t type_id, const char *label);
//void task_create_pcf_types(struct pcf_type *pcftype, struct task_type *types); int task_create_pcf_types(struct pcf_type *pcftype, struct task_type *types);
struct task *task_get_running(struct task_stack *stack); struct task *task_get_running(struct task_stack *stack);
#endif /* TASK_H */ #endif /* TASK_H */

View File

@ -7,4 +7,4 @@ ovni_test(nested-tasks-bad.c SHOULD_FAIL
ovni_test(task-types.c MP) ovni_test(task-types.c MP)
ovni_test(blocking.c MP) ovni_test(blocking.c MP)
ovni_test(ss-mismatch.c SHOULD_FAIL ovni_test(ss-mismatch.c SHOULD_FAIL
REGEX "thread [0-9]\\+ ended with 1 extra stacked nanos6 subsystems, top=\"Worker: Looking for work\"") REGEX "thread [0-9]\\+ ended with 1 stacked nanos6 subsystems, top=\"Worker: Looking for work\"")