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/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)
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
@ -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
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_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 */
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
@ -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)
|
||||||
|
@ -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 */
|
||||||
|
@ -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\"")
|
||||||
|
Loading…
Reference in New Issue
Block a user