Finish task types in PCF for nanos6
This commit is contained in:
parent
dbea90f525
commit
a91b1c554a
@ -43,6 +43,7 @@ add_library(emu STATIC
|
||||
nanos6/create.c
|
||||
nanos6/event.c
|
||||
nanos6/pvt.c
|
||||
nanos6/finish.c
|
||||
)
|
||||
|
||||
add_executable(ovniemu ovniemu.c)
|
||||
|
@ -160,9 +160,15 @@ emu_step(struct emu *emu)
|
||||
int
|
||||
emu_finish(struct emu *emu)
|
||||
{
|
||||
if (model_finish(&emu->model, emu) != 0) {
|
||||
err("model_finish failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (recorder_finish(&emu->recorder) != 0) {
|
||||
err("recorder_finish failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -105,3 +105,22 @@ model_event(struct model *model, struct emu *emu, int index)
|
||||
|
||||
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;
|
||||
}
|
||||
|
@ -14,6 +14,7 @@ struct model_spec {
|
||||
emu_hook_t *create;
|
||||
emu_hook_t *connect;
|
||||
emu_hook_t *event;
|
||||
emu_hook_t *finish;
|
||||
};
|
||||
|
||||
#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_connect(struct model *model, struct emu *emu);
|
||||
int model_event(struct model *model, struct emu *emu, int index);
|
||||
int model_finish(struct model *model, struct emu *emu);
|
||||
|
||||
#endif /* MODEL_H */
|
||||
|
44
src/emu/nanos6/finish.c
Normal file
44
src/emu/nanos6/finish.c
Normal 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;
|
||||
}
|
@ -98,7 +98,10 @@ int nanos6_probe(struct emu *emu);
|
||||
int nanos6_create(struct emu *emu);
|
||||
int nanos6_connect(struct emu *emu);
|
||||
int nanos6_event(struct emu *emu);
|
||||
int nanos6_finish(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 */
|
||||
|
@ -7,6 +7,7 @@ struct model_spec model_nanos6 = {
|
||||
.connect = nanos6_connect,
|
||||
.event = nanos6_event,
|
||||
.probe = nanos6_probe,
|
||||
.finish = nanos6_finish,
|
||||
};
|
||||
|
||||
int
|
||||
|
@ -1,6 +1,12 @@
|
||||
#include "nanos6_priv.h"
|
||||
|
||||
/* 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[] = {
|
||||
[CH_TASKID] = 35,
|
||||
[CH_TYPE] = 36,
|
||||
@ -240,3 +246,48 @@ init_pvt(struct emu *emu)
|
||||
|
||||
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;
|
||||
}
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
#include "uthash.h"
|
||||
#include "utlist.h"
|
||||
#include "pcf.h"
|
||||
|
||||
struct task *
|
||||
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;
|
||||
}
|
||||
|
||||
//void
|
||||
//task_create_pcf_types(struct pcf_type *pcftype, struct task_type *types)
|
||||
//{
|
||||
// /* Emit types for all task types */
|
||||
// for (struct task_type *tt = types; tt != NULL; tt = tt->hh.next) {
|
||||
// struct pcf_value *pcfvalue = pcf_find_value(pcftype, tt->gid);
|
||||
// if (pcfvalue != NULL) {
|
||||
// /* Ensure the label is the same, so we know that
|
||||
// * no collision occurred */
|
||||
// if (strcmp(pcfvalue->label, tt->label) != 0)
|
||||
// die("collision occurred in task type labels");
|
||||
// else
|
||||
// continue;
|
||||
// }
|
||||
//
|
||||
// pcf_add_value(pcftype, tt->gid, tt->label);
|
||||
// }
|
||||
//}
|
||||
int
|
||||
task_create_pcf_types(struct pcf_type *pcftype, struct task_type *types)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
/* Emit types for all task types */
|
||||
for (struct task_type *tt = types; tt != NULL; tt = tt->hh.next) {
|
||||
struct pcf_value *pcfvalue = pcf_find_value(pcftype, tt->gid);
|
||||
if (pcfvalue != NULL) {
|
||||
/* Ensure the label is the same, so we know that
|
||||
* no collision occurred */
|
||||
if (strcmp(pcfvalue->label, tt->label) != 0) {
|
||||
err("collision occurred in task type labels: %s and %s",
|
||||
pcfvalue->label, tt->label);
|
||||
ret = -1;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
pcf_add_value(pcftype, tt->gid, tt->label);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct task *
|
||||
task_get_running(struct task_stack *stack)
|
||||
|
@ -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);
|
||||
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);
|
||||
|
||||
#endif /* TASK_H */
|
||||
|
@ -7,4 +7,4 @@ ovni_test(nested-tasks-bad.c SHOULD_FAIL
|
||||
ovni_test(task-types.c MP)
|
||||
ovni_test(blocking.c MP)
|
||||
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\"")
|
||||
|
Loading…
Reference in New Issue
Block a user