Add PCF information for nanos6
This commit is contained in:
parent
c94a786c1e
commit
4e2164646c
@ -27,6 +27,7 @@ add_library(emu STATIC
|
|||||||
mux.c
|
mux.c
|
||||||
path.c
|
path.c
|
||||||
proc.c
|
proc.c
|
||||||
|
pcf.c
|
||||||
prv.c
|
prv.c
|
||||||
pvt.c
|
pvt.c
|
||||||
recorder.c
|
recorder.c
|
||||||
@ -41,6 +42,7 @@ add_library(emu STATIC
|
|||||||
nanos6/connect.c
|
nanos6/connect.c
|
||||||
nanos6/create.c
|
nanos6/create.c
|
||||||
nanos6/event.c
|
nanos6/event.c
|
||||||
|
nanos6/pvt.c
|
||||||
)
|
)
|
||||||
|
|
||||||
add_executable(ovniemu ovniemu.c)
|
add_executable(ovniemu ovniemu.c)
|
||||||
|
@ -156,3 +156,13 @@ emu_step(struct emu *emu)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
emu_finish(struct emu *emu)
|
||||||
|
{
|
||||||
|
if (recorder_finish(&emu->recorder) != 0) {
|
||||||
|
err("recorder_finish failed");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@ -39,6 +39,7 @@ struct emu {
|
|||||||
int emu_init(struct emu *emu, int argc, char *argv[]);
|
int emu_init(struct emu *emu, int argc, char *argv[]);
|
||||||
int emu_connect(struct emu *emu);
|
int emu_connect(struct emu *emu);
|
||||||
int emu_step(struct emu *emu);
|
int emu_step(struct emu *emu);
|
||||||
|
int emu_finish(struct emu *emu);
|
||||||
|
|
||||||
static inline struct emu *
|
static inline struct emu *
|
||||||
emu_get(void *ptr)
|
emu_get(void *ptr)
|
||||||
|
@ -1,32 +1,14 @@
|
|||||||
#include "nanos6_priv.h"
|
#include "nanos6_priv.h"
|
||||||
|
|
||||||
const enum nanos6_track th_track[] = {
|
const enum nanos6_track chan_track[CH_MAX][CT_MAX] = {
|
||||||
[CH_TASKID] = RUN_TH,
|
/* Thread CPU */
|
||||||
[CH_TYPE] = RUN_TH,
|
[CH_TASKID] = { RUN_TH, RUN_TH },
|
||||||
[CH_SUBSYSTEM] = ACT_TH,
|
[CH_TYPE] = { RUN_TH, RUN_TH },
|
||||||
[CH_RANK] = RUN_TH,
|
[CH_SUBSYSTEM] = { ACT_TH, RUN_TH },
|
||||||
[CH_THREAD] = NONE,
|
[CH_RANK] = { RUN_TH, RUN_TH },
|
||||||
|
[CH_THREAD] = { NONE, RUN_TH },
|
||||||
};
|
};
|
||||||
|
|
||||||
const enum nanos6_track cpu_track[] = {
|
|
||||||
[CH_TASKID] = RUN_TH,
|
|
||||||
[CH_TYPE] = RUN_TH,
|
|
||||||
[CH_SUBSYSTEM] = RUN_TH,
|
|
||||||
[CH_RANK] = RUN_TH,
|
|
||||||
[CH_THREAD] = RUN_TH,
|
|
||||||
};
|
|
||||||
|
|
||||||
static const int th_type[] = {
|
|
||||||
[CH_TASKID] = 35,
|
|
||||||
[CH_TYPE] = 36,
|
|
||||||
[CH_SUBSYSTEM] = 37,
|
|
||||||
[CH_RANK] = 38,
|
|
||||||
[CH_THREAD] = 39,
|
|
||||||
};
|
|
||||||
|
|
||||||
static const int *cpu_type = th_type;
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
connect_thread_mux(struct emu *emu, struct thread *thread)
|
connect_thread_mux(struct emu *emu, struct thread *thread)
|
||||||
{
|
{
|
||||||
@ -67,9 +49,10 @@ connect_thread_mux(struct emu *emu, struct thread *thread)
|
|||||||
|
|
||||||
/* The tracking only sets the ch_out, but we keep both tracking
|
/* The tracking only sets the ch_out, but we keep both tracking
|
||||||
* updated as the CPU tracking channels may use them. */
|
* updated as the CPU tracking channels may use them. */
|
||||||
if (th_track[i] == RUN_TH)
|
enum nanos6_track track = chan_track[i][CT_TH];
|
||||||
|
if (track == RUN_TH)
|
||||||
th->ch_out[i] = &th->ch_run[i];
|
th->ch_out[i] = &th->ch_run[i];
|
||||||
else if (th_track[i] == ACT_TH)
|
else if (track == ACT_TH)
|
||||||
th->ch_out[i] = &th->ch_act[i];
|
th->ch_out[i] = &th->ch_act[i];
|
||||||
else
|
else
|
||||||
th->ch_out[i] = &th->ch[i];
|
th->ch_out[i] = &th->ch[i];
|
||||||
@ -79,23 +62,6 @@ connect_thread_mux(struct emu *emu, struct thread *thread)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
connect_thread_prv(struct emu *emu, struct thread *thread, struct prv *prv)
|
|
||||||
{
|
|
||||||
struct nanos6_thread *th = EXT(thread, '6');
|
|
||||||
for (int i = 0; i < CH_MAX; i++) {
|
|
||||||
struct chan *out = th->ch_out[i];
|
|
||||||
long type = th_type[i];
|
|
||||||
long row = thread->gindex;
|
|
||||||
if (prv_register(prv, row, type, &emu->bay, out, PRV_DUP)) {
|
|
||||||
err("prv_register failed");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
add_inputs_cpu_mux(struct emu *emu, struct mux *mux, int i)
|
add_inputs_cpu_mux(struct emu *emu, struct mux *mux, int i)
|
||||||
{
|
{
|
||||||
@ -104,12 +70,13 @@ add_inputs_cpu_mux(struct emu *emu, struct mux *mux, int i)
|
|||||||
|
|
||||||
/* Choose input thread channel based on tracking mode */
|
/* Choose input thread channel based on tracking mode */
|
||||||
struct chan *inp = NULL;
|
struct chan *inp = NULL;
|
||||||
if (cpu_track[i] == RUN_TH)
|
enum nanos6_track track = chan_track[i][CT_CPU];
|
||||||
|
if (track == RUN_TH)
|
||||||
inp = &th->ch_run[i];
|
inp = &th->ch_run[i];
|
||||||
else if (cpu_track[i] == ACT_TH)
|
else if (track == ACT_TH)
|
||||||
inp = &th->ch_act[i];
|
inp = &th->ch_act[i];
|
||||||
else
|
else
|
||||||
die("cpu tracking must be 'running' or 'active'");
|
die("cpu tracking must be running or active");
|
||||||
|
|
||||||
if (mux_add_input(mux, value_int64(t->gindex), inp) != 0) {
|
if (mux_add_input(mux, value_int64(t->gindex), inp) != 0) {
|
||||||
err("mux_add_input failed");
|
err("mux_add_input failed");
|
||||||
@ -130,12 +97,13 @@ connect_cpu_mux(struct emu *emu, struct cpu *scpu)
|
|||||||
|
|
||||||
/* Choose select CPU channel based on tracking mode */
|
/* Choose select CPU channel based on tracking mode */
|
||||||
struct chan *sel = NULL;
|
struct chan *sel = NULL;
|
||||||
if (cpu_track[i] == RUN_TH)
|
enum nanos6_track track = chan_track[i][CT_CPU];
|
||||||
|
if (track == RUN_TH)
|
||||||
sel = &scpu->chan[CPU_CHAN_THRUN];
|
sel = &scpu->chan[CPU_CHAN_THRUN];
|
||||||
else if (cpu_track[i] == ACT_TH)
|
else if (track == ACT_TH)
|
||||||
sel = &scpu->chan[CPU_CHAN_THACT];
|
sel = &scpu->chan[CPU_CHAN_THACT];
|
||||||
else
|
else
|
||||||
die("cpu tracking must be 'running' or 'active'");
|
die("cpu tracking must be running or active");
|
||||||
|
|
||||||
if (mux_init(mux, &emu->bay, sel, out, NULL) != 0) {
|
if (mux_init(mux, &emu->bay, sel, out, NULL) != 0) {
|
||||||
err("mux_init failed");
|
err("mux_init failed");
|
||||||
@ -151,8 +119,8 @@ connect_cpu_mux(struct emu *emu, struct cpu *scpu)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
int
|
||||||
connect_threads(struct emu *emu)
|
nanos6_connect(struct emu *emu)
|
||||||
{
|
{
|
||||||
struct system *sys = &emu->system;
|
struct system *sys = &emu->system;
|
||||||
|
|
||||||
@ -164,51 +132,6 @@ connect_threads(struct emu *emu)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get thread PRV */
|
|
||||||
struct pvt *pvt = recorder_find_pvt(&emu->recorder, "thread");
|
|
||||||
if (pvt == NULL) {
|
|
||||||
err("cannot find thread pvt");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
struct prv *prv = pvt_get_prv(pvt);
|
|
||||||
|
|
||||||
for (struct thread *t = sys->threads; t; t = t->gnext) {
|
|
||||||
if (connect_thread_prv(emu, t, prv) != 0) {
|
|
||||||
err("connect_thread_prv failed");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
connect_cpu_prv(struct emu *emu, struct cpu *scpu, struct prv *prv)
|
|
||||||
{
|
|
||||||
struct nanos6_cpu *cpu = EXT(scpu, '6');
|
|
||||||
for (int i = 0; i < CH_MAX; i++) {
|
|
||||||
struct chan *out = &cpu->ch[i];
|
|
||||||
long type = cpu_type[i];
|
|
||||||
long row = scpu->gindex;
|
|
||||||
if (prv_register(prv, row, type, &emu->bay, out, PRV_DUP)) {
|
|
||||||
err("prv_register failed");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//static int
|
|
||||||
//populate_cpu_pcf(struct emu *emu, struct pcf *pcf)
|
|
||||||
//{
|
|
||||||
//}
|
|
||||||
|
|
||||||
static int
|
|
||||||
connect_cpus(struct emu *emu)
|
|
||||||
{
|
|
||||||
struct system *sys = &emu->system;
|
|
||||||
|
|
||||||
/* cpus */
|
/* cpus */
|
||||||
for (struct cpu *c = sys->cpus; c; c = c->next) {
|
for (struct cpu *c = sys->cpus; c; c = c->next) {
|
||||||
if (connect_cpu_mux(emu, c) != 0) {
|
if (connect_cpu_mux(emu, c) != 0) {
|
||||||
@ -217,37 +140,8 @@ connect_cpus(struct emu *emu)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get cpu PRV */
|
if (init_pvt(emu) != 0) {
|
||||||
struct pvt *pvt = recorder_find_pvt(&emu->recorder, "cpu");
|
err("init_pvt failed");
|
||||||
if (pvt == NULL) {
|
|
||||||
err("cannot find cpu pvt");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
struct prv *prv = pvt_get_prv(pvt);
|
|
||||||
|
|
||||||
for (struct cpu *c = sys->cpus; c; c = c->next) {
|
|
||||||
if (connect_cpu_prv(emu, c, prv) != 0) {
|
|
||||||
err("connect_cpu_prv failed");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// struct pcf *pcf = pvt_get_pcf(pvt);
|
|
||||||
// populate_cpu_pcf(pcf, emu);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
nanos6_connect(struct emu *emu)
|
|
||||||
{
|
|
||||||
if (connect_threads(emu) != 0) {
|
|
||||||
err("connect_threads failed");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (connect_cpus(emu) != 0) {
|
|
||||||
err("connect_cpus failed");
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,7 +10,14 @@
|
|||||||
#include "task.h"
|
#include "task.h"
|
||||||
|
|
||||||
/* Private enums */
|
/* Private enums */
|
||||||
|
|
||||||
enum nanos6_chan_type {
|
enum nanos6_chan_type {
|
||||||
|
CT_TH = 0,
|
||||||
|
CT_CPU,
|
||||||
|
CT_MAX
|
||||||
|
};
|
||||||
|
|
||||||
|
enum nanos6_chan {
|
||||||
CH_TASKID = 0,
|
CH_TASKID = 0,
|
||||||
CH_TYPE,
|
CH_TYPE,
|
||||||
CH_SUBSYSTEM,
|
CH_SUBSYSTEM,
|
||||||
@ -26,8 +33,7 @@ enum nanos6_track {
|
|||||||
TRACK_MAX,
|
TRACK_MAX,
|
||||||
};
|
};
|
||||||
|
|
||||||
extern const enum nanos6_track th_track[CH_MAX];
|
extern const enum nanos6_track chan_track[CH_MAX][CT_MAX];
|
||||||
extern const enum nanos6_track cpu_track[CH_MAX];
|
|
||||||
|
|
||||||
enum nanos6_ss_state {
|
enum nanos6_ss_state {
|
||||||
ST_TASK_BODY = 1,
|
ST_TASK_BODY = 1,
|
||||||
@ -93,4 +99,6 @@ 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 init_pvt(struct emu *emu);
|
||||||
|
|
||||||
#endif /* NANOS6_PRIV_H */
|
#endif /* NANOS6_PRIV_H */
|
||||||
|
242
src/emu/nanos6/pvt.c
Normal file
242
src/emu/nanos6/pvt.c
Normal file
@ -0,0 +1,242 @@
|
|||||||
|
#include "nanos6_priv.h"
|
||||||
|
|
||||||
|
/* TODO: Assign types on runtime and generate configs */
|
||||||
|
static const int pvt_type[] = {
|
||||||
|
[CH_TASKID] = 35,
|
||||||
|
[CH_TYPE] = 36,
|
||||||
|
[CH_SUBSYSTEM] = 37,
|
||||||
|
[CH_RANK] = 38,
|
||||||
|
[CH_THREAD] = 39,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char *pcf_prefix[CH_MAX] = {
|
||||||
|
[CH_TASKID] = "Nanos6 task ID",
|
||||||
|
[CH_TYPE] = "Nanos6 task type",
|
||||||
|
[CH_SUBSYSTEM] = "Nanos6 subsystem",
|
||||||
|
[CH_RANK] = "Nanos6 task MPI rank",
|
||||||
|
[CH_THREAD] = "Nanos6 thread type",
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char *pcf_suffix[TRACK_MAX] = {
|
||||||
|
[NONE] = "",
|
||||||
|
[RUN_TH] = "of the RUNNING thread",
|
||||||
|
[ACT_TH] = "of the ACTIVE thread",
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct pcf_value_label nanos6_ss_values[] = {
|
||||||
|
{ ST_TASK_BODY, "Task: Running body" },
|
||||||
|
{ ST_TASK_CREATING, "Task: Creating" },
|
||||||
|
{ ST_TASK_SUBMIT, "Task: Submitting" },
|
||||||
|
{ ST_TASK_SPAWNING, "Task: Spawning function" },
|
||||||
|
{ ST_TASK_FOR, "Task: Running task for" },
|
||||||
|
{ ST_SCHED_SERVING, "Scheduler: Serving tasks" },
|
||||||
|
{ ST_SCHED_ADDING, "Scheduler: Adding ready tasks" },
|
||||||
|
{ ST_SCHED_PROCESSING, "Scheduler: Processing ready tasks" },
|
||||||
|
{ ST_DEP_REG, "Dependency: Registering" },
|
||||||
|
{ ST_DEP_UNREG, "Dependency: Unregistering" },
|
||||||
|
{ ST_BLK_TASKWAIT, "Blocking: Taskwait" },
|
||||||
|
{ ST_BLK_BLOCKING, "Blocking: Blocking current task" },
|
||||||
|
{ ST_BLK_UNBLOCKING, "Blocking: Unblocking remote task" },
|
||||||
|
{ ST_BLK_WAITFOR, "Blocking: Wait for deadline" },
|
||||||
|
{ ST_HANDLING_TASK, "Worker: Handling task" },
|
||||||
|
{ ST_WORKER_LOOP, "Worker: Looking for work" },
|
||||||
|
{ ST_SWITCH_TO, "Worker: Switching to another thread" },
|
||||||
|
{ ST_MIGRATE, "Worker: Migrating CPU" },
|
||||||
|
{ ST_SUSPEND, "Worker: Suspending thread" },
|
||||||
|
{ ST_RESUME, "Worker: Resuming another thread" },
|
||||||
|
{ ST_ALLOCATING, "Memory: Allocating" },
|
||||||
|
{ ST_FREEING, "Memory: Freeing" },
|
||||||
|
|
||||||
|
{ EV_SCHED_SEND, "EV Scheduler: Send task" },
|
||||||
|
{ EV_SCHED_RECV, "EV Scheduler: Recv task" },
|
||||||
|
{ EV_SCHED_SELF, "EV Scheduler: Self-assign task" },
|
||||||
|
{ EV_CPU_IDLE, "EV CPU: Becomes idle" },
|
||||||
|
{ EV_CPU_ACTIVE, "EV CPU: Becomes active" },
|
||||||
|
{ EV_SIGNAL, "EV Worker: Wakening another thread" },
|
||||||
|
{ -1, NULL },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct pcf_value_label nanos6_thread_type[] = {
|
||||||
|
{ ST_TH_EXTERNAL, "External" },
|
||||||
|
{ ST_TH_WORKER, "Worker" },
|
||||||
|
{ ST_TH_LEADER, "Leader" },
|
||||||
|
{ ST_TH_MAIN, "Main" },
|
||||||
|
{ -1, NULL },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct pcf_value_label (*pcf_chan_value_labels[CH_MAX])[] = {
|
||||||
|
[CH_SUBSYSTEM] = &nanos6_ss_values,
|
||||||
|
[CH_THREAD] = &nanos6_thread_type,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* ------------------------------ pcf ------------------------------ */
|
||||||
|
|
||||||
|
static int
|
||||||
|
create_values(struct pcf_type *t, int c)
|
||||||
|
{
|
||||||
|
const struct pcf_value_label(*q)[] = pcf_chan_value_labels[c];
|
||||||
|
|
||||||
|
if (q == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
for (const struct pcf_value_label *p = *q; p->label != NULL; p++)
|
||||||
|
pcf_add_value(t, p->value, p->label);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
create_type(struct pcf *pcf, enum nanos6_chan c, enum nanos6_chan_type ct)
|
||||||
|
{
|
||||||
|
long type = pvt_type[c];
|
||||||
|
|
||||||
|
if (type == -1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* Compute the label by joining the two parts */
|
||||||
|
const char *prefix = pcf_prefix[c];
|
||||||
|
int track_mode = chan_track[c][ct];
|
||||||
|
const char *suffix = pcf_suffix[track_mode];
|
||||||
|
|
||||||
|
char label[MAX_PCF_LABEL];
|
||||||
|
int ret = snprintf(label, MAX_PCF_LABEL, "%s %s",
|
||||||
|
prefix, suffix);
|
||||||
|
|
||||||
|
if (ret >= MAX_PCF_LABEL) {
|
||||||
|
err("computed type label too long");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct pcf_type *pcftype = pcf_add_type(pcf, type, label);
|
||||||
|
|
||||||
|
return create_values(pcftype, c);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
init_pcf(struct pcf *pcf, enum nanos6_chan_type ct)
|
||||||
|
{
|
||||||
|
/* Create default types and values */
|
||||||
|
for (enum nanos6_chan c = 0; c < CH_MAX; c++) {
|
||||||
|
if (create_type(pcf, c, ct) != 0) {
|
||||||
|
err("create_type failed");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------ prv ------------------------------ */
|
||||||
|
|
||||||
|
static int
|
||||||
|
connect_thread_prv(struct emu *emu, struct thread *thread, struct prv *prv)
|
||||||
|
{
|
||||||
|
struct nanos6_thread *th = EXT(thread, '6');
|
||||||
|
for (int i = 0; i < CH_MAX; i++) {
|
||||||
|
struct chan *out = th->ch_out[i];
|
||||||
|
long type = pvt_type[i];
|
||||||
|
long row = thread->gindex;
|
||||||
|
if (prv_register(prv, row, type, &emu->bay, out, PRV_DUP)) {
|
||||||
|
err("prv_register failed");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
connect_cpu_prv(struct emu *emu, struct cpu *scpu, struct prv *prv)
|
||||||
|
{
|
||||||
|
struct nanos6_cpu *cpu = EXT(scpu, '6');
|
||||||
|
for (int i = 0; i < CH_MAX; i++) {
|
||||||
|
struct chan *out = &cpu->ch[i];
|
||||||
|
long type = pvt_type[i];
|
||||||
|
long row = scpu->gindex;
|
||||||
|
if (prv_register(prv, row, type, &emu->bay, out, PRV_DUP)) {
|
||||||
|
err("prv_register failed");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
connect_threads(struct emu *emu)
|
||||||
|
{
|
||||||
|
struct system *sys = &emu->system;
|
||||||
|
|
||||||
|
/* Get thread PRV */
|
||||||
|
struct pvt *pvt = recorder_find_pvt(&emu->recorder, "thread");
|
||||||
|
if (pvt == NULL) {
|
||||||
|
err("cannot find thread pvt");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Connect thread channels to PRV */
|
||||||
|
struct prv *prv = pvt_get_prv(pvt);
|
||||||
|
for (struct thread *t = sys->threads; t; t = t->gnext) {
|
||||||
|
if (connect_thread_prv(emu, t, prv) != 0) {
|
||||||
|
err("connect_thread_prv failed");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Init thread PCF */
|
||||||
|
struct pcf *pcf = pvt_get_pcf(pvt);
|
||||||
|
if (init_pcf(pcf, CT_TH) != 0) {
|
||||||
|
err("init_pcf failed");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
connect_cpus(struct emu *emu)
|
||||||
|
{
|
||||||
|
struct system *sys = &emu->system;
|
||||||
|
|
||||||
|
/* Get cpu PRV */
|
||||||
|
struct pvt *pvt = recorder_find_pvt(&emu->recorder, "cpu");
|
||||||
|
if (pvt == NULL) {
|
||||||
|
err("cannot find cpu pvt");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Connect CPU channels to PRV */
|
||||||
|
struct prv *prv = pvt_get_prv(pvt);
|
||||||
|
for (struct cpu *c = sys->cpus; c; c = c->next) {
|
||||||
|
if (connect_cpu_prv(emu, c, prv) != 0) {
|
||||||
|
err("connect_cpu_prv failed");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Init CPU PCF */
|
||||||
|
struct pcf *pcf = pvt_get_pcf(pvt);
|
||||||
|
if (init_pcf(pcf, CT_CPU) != 0) {
|
||||||
|
err("init_pcf failed");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Connect all outputs to the paraver trace and setup PCF types */
|
||||||
|
int
|
||||||
|
init_pvt(struct emu *emu)
|
||||||
|
{
|
||||||
|
if (connect_threads(emu) != 0) {
|
||||||
|
err("connect_threads failed");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (connect_cpus(emu) != 0) {
|
||||||
|
err("connect_cpus failed");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -21,16 +21,25 @@ main(int argc, char *argv[])
|
|||||||
if (emu_connect(emu) != 0)
|
if (emu_connect(emu) != 0)
|
||||||
die("emu_connect failed\n");
|
die("emu_connect failed\n");
|
||||||
|
|
||||||
err("emulation starts\n");
|
err("emulation starts");
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
while ((ret = emu_step(emu)) == 0);
|
while ((ret = emu_step(emu)) == 0);
|
||||||
|
|
||||||
if (ret < 0)
|
if (ret < 0) {
|
||||||
die("emu_step failed\n");
|
err("emu_step failed");
|
||||||
|
ret = 1;
|
||||||
|
/* continue to close the trace files */
|
||||||
|
err("emulation aborts!");
|
||||||
|
} else {
|
||||||
|
err("emulation ends");
|
||||||
|
}
|
||||||
|
|
||||||
err("emulation ends\n");
|
if (emu_finish(emu) != 0) {
|
||||||
|
err("emu_finish failed");
|
||||||
|
ret = 1;
|
||||||
|
}
|
||||||
|
|
||||||
free(emu);
|
free(emu);
|
||||||
|
|
||||||
return 0;
|
return ret;
|
||||||
}
|
}
|
||||||
|
473
src/emu/pcf.c
473
src/emu/pcf.c
@ -2,9 +2,8 @@
|
|||||||
* SPDX-License-Identifier: GPL-3.0-or-later */
|
* SPDX-License-Identifier: GPL-3.0-or-later */
|
||||||
|
|
||||||
#include "pcf.h"
|
#include "pcf.h"
|
||||||
#include "emu.h"
|
|
||||||
#include "prv.h"
|
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -69,210 +68,210 @@ const uint32_t pcf_def_palette[] = {
|
|||||||
const uint32_t *pcf_palette = pcf_def_palette;
|
const uint32_t *pcf_palette = pcf_def_palette;
|
||||||
const int pcf_palette_len = ARRAY_LEN(pcf_def_palette);
|
const int pcf_palette_len = ARRAY_LEN(pcf_def_palette);
|
||||||
|
|
||||||
/* ------------------ Value labels --------------------- */
|
///* ------------------ Value labels --------------------- */
|
||||||
|
//
|
||||||
struct pcf_value_label default_values[] = {
|
//struct pcf_value_label default_values[] = {
|
||||||
{ ST_TOO_MANY_TH, "Unknown: Multiple threads running" },
|
// { ST_TOO_MANY_TH, "Unknown: Multiple threads running" },
|
||||||
{ -1, NULL },
|
// { -1, NULL },
|
||||||
};
|
//};
|
||||||
|
//
|
||||||
struct pcf_value_label ovni_state_values[] = {
|
//struct pcf_value_label ovni_state_values[] = {
|
||||||
{ TH_ST_UNKNOWN, "Unknown" },
|
// { TH_ST_UNKNOWN, "Unknown" },
|
||||||
{ TH_ST_RUNNING, "Running" },
|
// { TH_ST_RUNNING, "Running" },
|
||||||
{ TH_ST_PAUSED, "Paused" },
|
// { TH_ST_PAUSED, "Paused" },
|
||||||
{ TH_ST_DEAD, "Dead" },
|
// { TH_ST_DEAD, "Dead" },
|
||||||
{ TH_ST_COOLING, "Cooling" },
|
// { TH_ST_COOLING, "Cooling" },
|
||||||
{ TH_ST_WARMING, "Warming" },
|
// { TH_ST_WARMING, "Warming" },
|
||||||
{ -1, NULL },
|
// { -1, NULL },
|
||||||
};
|
//};
|
||||||
|
//
|
||||||
struct pcf_value_label ovni_flush_values[] = {
|
//struct pcf_value_label ovni_flush_values[] = {
|
||||||
{ 0, "None" },
|
// { 0, "None" },
|
||||||
{ ST_OVNI_FLUSHING, "Flushing" },
|
// { ST_OVNI_FLUSHING, "Flushing" },
|
||||||
{ ST_TOO_MANY_TH, "Unknown flushing state: Multiple threads running" },
|
// { ST_TOO_MANY_TH, "Unknown flushing state: Multiple threads running" },
|
||||||
{ -1, NULL },
|
// { -1, NULL },
|
||||||
};
|
//};
|
||||||
|
//
|
||||||
struct pcf_value_label nosv_ss_values[] = {
|
//struct pcf_value_label nosv_ss_values[] = {
|
||||||
/* Errors */
|
// /* Errors */
|
||||||
{ ST_BAD, "Unknown: bad happened (report bug)" },
|
// { ST_BAD, "Unknown: bad happened (report bug)" },
|
||||||
{ ST_TOO_MANY_TH, "Unknown: multiple threads running" },
|
// { ST_TOO_MANY_TH, "Unknown: multiple threads running" },
|
||||||
/* Good values */
|
// /* Good values */
|
||||||
{ ST_NULL, "No subsystem" },
|
// { ST_NULL, "No subsystem" },
|
||||||
{ ST_NOSV_SCHED_HUNGRY, "Scheduler: Hungry" },
|
// { ST_NOSV_SCHED_HUNGRY, "Scheduler: Hungry" },
|
||||||
{ ST_NOSV_SCHED_SERVING, "Scheduler: Serving" },
|
// { ST_NOSV_SCHED_SERVING, "Scheduler: Serving" },
|
||||||
{ ST_NOSV_SCHED_SUBMITTING, "Scheduler: Submitting" },
|
// { ST_NOSV_SCHED_SUBMITTING, "Scheduler: Submitting" },
|
||||||
{ ST_NOSV_MEM_ALLOCATING, "Memory: Allocating" },
|
// { ST_NOSV_MEM_ALLOCATING, "Memory: Allocating" },
|
||||||
{ ST_NOSV_MEM_FREEING, "Memory: Freeing" },
|
// { ST_NOSV_MEM_FREEING, "Memory: Freeing" },
|
||||||
{ ST_NOSV_TASK_RUNNING, "Task: Running" },
|
// { ST_NOSV_TASK_RUNNING, "Task: Running" },
|
||||||
{ ST_NOSV_API_SUBMIT, "API: Submit" },
|
// { ST_NOSV_API_SUBMIT, "API: Submit" },
|
||||||
{ ST_NOSV_API_PAUSE, "API: Pause" },
|
// { ST_NOSV_API_PAUSE, "API: Pause" },
|
||||||
{ ST_NOSV_API_YIELD, "API: Yield" },
|
// { ST_NOSV_API_YIELD, "API: Yield" },
|
||||||
{ ST_NOSV_API_WAITFOR, "API: Waitfor" },
|
// { ST_NOSV_API_WAITFOR, "API: Waitfor" },
|
||||||
{ ST_NOSV_API_SCHEDPOINT, "API: Scheduling point" },
|
// { ST_NOSV_API_SCHEDPOINT, "API: Scheduling point" },
|
||||||
{ ST_NOSV_ATTACH, "Thread: Attached" },
|
// { ST_NOSV_ATTACH, "Thread: Attached" },
|
||||||
{ ST_NOSV_WORKER, "Thread: Worker" },
|
// { ST_NOSV_WORKER, "Thread: Worker" },
|
||||||
{ ST_NOSV_DELEGATE, "Thread: Delegate" },
|
// { ST_NOSV_DELEGATE, "Thread: Delegate" },
|
||||||
{ EV_NOSV_SCHED_SEND, "EV Scheduler: Send task" },
|
// { EV_NOSV_SCHED_SEND, "EV Scheduler: Send task" },
|
||||||
{ EV_NOSV_SCHED_RECV, "EV Scheduler: Recv task" },
|
// { EV_NOSV_SCHED_RECV, "EV Scheduler: Recv task" },
|
||||||
{ EV_NOSV_SCHED_SELF, "EV Scheduler: Self-assign task" },
|
// { EV_NOSV_SCHED_SELF, "EV Scheduler: Self-assign task" },
|
||||||
{ -1, NULL },
|
// { -1, NULL },
|
||||||
};
|
//};
|
||||||
|
//
|
||||||
struct pcf_value_label nodes_mode_values[] = {
|
//struct pcf_value_label nodes_mode_values[] = {
|
||||||
{ ST_NULL, "NULL" },
|
// { ST_NULL, "NULL" },
|
||||||
{ ST_TOO_MANY_TH, "NODES: Multiple threads running" },
|
// { ST_TOO_MANY_TH, "NODES: Multiple threads running" },
|
||||||
{ ST_NODES_REGISTER, "Dependencies: Registering task accesses" },
|
// { ST_NODES_REGISTER, "Dependencies: Registering task accesses" },
|
||||||
{ ST_NODES_UNREGISTER, "Dependencies: Unregistering task accesses" },
|
// { ST_NODES_UNREGISTER, "Dependencies: Unregistering task accesses" },
|
||||||
{ ST_NODES_IF0_WAIT, "If0: Waiting for an If0 task" },
|
// { ST_NODES_IF0_WAIT, "If0: Waiting for an If0 task" },
|
||||||
{ ST_NODES_IF0_INLINE, "If0: Executing an If0 task inline" },
|
// { ST_NODES_IF0_INLINE, "If0: Executing an If0 task inline" },
|
||||||
{ ST_NODES_TASKWAIT, "Taskwait: Taskwait" },
|
// { ST_NODES_TASKWAIT, "Taskwait: Taskwait" },
|
||||||
{ ST_NODES_CREATE, "Add Task: Creating a task" },
|
// { ST_NODES_CREATE, "Add Task: Creating a task" },
|
||||||
{ ST_NODES_SUBMIT, "Add Task: Submitting a task" },
|
// { ST_NODES_SUBMIT, "Add Task: Submitting a task" },
|
||||||
{ ST_NODES_SPAWN, "Spawn Function: Spawning a function" },
|
// { ST_NODES_SPAWN, "Spawn Function: Spawning a function" },
|
||||||
{ -1, NULL },
|
// { -1, NULL },
|
||||||
};
|
//};
|
||||||
|
//
|
||||||
struct pcf_value_label kernel_cs_values[] = {
|
//struct pcf_value_label kernel_cs_values[] = {
|
||||||
{ ST_NULL, "NULL" },
|
// { ST_NULL, "NULL" },
|
||||||
{ ST_TOO_MANY_TH, "Unknown: multiple threads running" },
|
// { ST_TOO_MANY_TH, "Unknown: multiple threads running" },
|
||||||
{ ST_KERNEL_CSOUT, "Context switch: Out of the CPU" },
|
// { ST_KERNEL_CSOUT, "Context switch: Out of the CPU" },
|
||||||
{ -1, NULL },
|
// { -1, NULL },
|
||||||
};
|
//};
|
||||||
|
//
|
||||||
struct pcf_value_label nanos6_ss_values[] = {
|
//struct pcf_value_label nanos6_ss_values[] = {
|
||||||
{ ST_NULL, "No subsystem" },
|
// { ST_NULL, "No subsystem" },
|
||||||
{ ST_TOO_MANY_TH, "Unknown: multiple threads running" },
|
// { ST_TOO_MANY_TH, "Unknown: multiple threads running" },
|
||||||
{ ST_NANOS6_TASK_BODY, "Task: Running body" },
|
// { ST_NANOS6_TASK_BODY, "Task: Running body" },
|
||||||
{ ST_NANOS6_TASK_CREATING, "Task: Creating" },
|
// { ST_NANOS6_TASK_CREATING, "Task: Creating" },
|
||||||
{ ST_NANOS6_TASK_SUBMIT, "Task: Submitting" },
|
// { ST_NANOS6_TASK_SUBMIT, "Task: Submitting" },
|
||||||
{ ST_NANOS6_TASK_SPAWNING, "Task: Spawning function" },
|
// { ST_NANOS6_TASK_SPAWNING, "Task: Spawning function" },
|
||||||
{ ST_NANOS6_TASK_FOR, "Task: Running task for" },
|
// { ST_NANOS6_TASK_FOR, "Task: Running task for" },
|
||||||
{ ST_NANOS6_SCHED_SERVING, "Scheduler: Serving tasks" },
|
// { ST_NANOS6_SCHED_SERVING, "Scheduler: Serving tasks" },
|
||||||
{ ST_NANOS6_SCHED_ADDING, "Scheduler: Adding ready tasks" },
|
// { ST_NANOS6_SCHED_ADDING, "Scheduler: Adding ready tasks" },
|
||||||
{ ST_NANOS6_SCHED_PROCESSING, "Scheduler: Processing ready tasks" },
|
// { ST_NANOS6_SCHED_PROCESSING, "Scheduler: Processing ready tasks" },
|
||||||
{ ST_NANOS6_DEP_REG, "Dependency: Registering" },
|
// { ST_NANOS6_DEP_REG, "Dependency: Registering" },
|
||||||
{ ST_NANOS6_DEP_UNREG, "Dependency: Unregistering" },
|
// { ST_NANOS6_DEP_UNREG, "Dependency: Unregistering" },
|
||||||
{ ST_NANOS6_BLK_TASKWAIT, "Blocking: Taskwait" },
|
// { ST_NANOS6_BLK_TASKWAIT, "Blocking: Taskwait" },
|
||||||
{ ST_NANOS6_BLK_BLOCKING, "Blocking: Blocking current task" },
|
// { ST_NANOS6_BLK_BLOCKING, "Blocking: Blocking current task" },
|
||||||
{ ST_NANOS6_BLK_UNBLOCKING, "Blocking: Unblocking remote task" },
|
// { ST_NANOS6_BLK_UNBLOCKING, "Blocking: Unblocking remote task" },
|
||||||
{ ST_NANOS6_BLK_WAITFOR, "Blocking: Wait for deadline" },
|
// { ST_NANOS6_BLK_WAITFOR, "Blocking: Wait for deadline" },
|
||||||
{ ST_NANOS6_HANDLING_TASK, "Worker: Handling task" },
|
// { ST_NANOS6_HANDLING_TASK, "Worker: Handling task" },
|
||||||
{ ST_NANOS6_WORKER_LOOP, "Worker: Looking for work" },
|
// { ST_NANOS6_WORKER_LOOP, "Worker: Looking for work" },
|
||||||
{ ST_NANOS6_SWITCH_TO, "Worker: Switching to another thread" },
|
// { ST_NANOS6_SWITCH_TO, "Worker: Switching to another thread" },
|
||||||
{ ST_NANOS6_MIGRATE, "Worker: Migrating CPU" },
|
// { ST_NANOS6_MIGRATE, "Worker: Migrating CPU" },
|
||||||
{ ST_NANOS6_SUSPEND, "Worker: Suspending thread" },
|
// { ST_NANOS6_SUSPEND, "Worker: Suspending thread" },
|
||||||
{ ST_NANOS6_RESUME, "Worker: Resuming another thread" },
|
// { ST_NANOS6_RESUME, "Worker: Resuming another thread" },
|
||||||
{ ST_NANOS6_ALLOCATING, "Memory: Allocating" },
|
// { ST_NANOS6_ALLOCATING, "Memory: Allocating" },
|
||||||
{ ST_NANOS6_FREEING, "Memory: Freeing" },
|
// { ST_NANOS6_FREEING, "Memory: Freeing" },
|
||||||
{ EV_NANOS6_SCHED_SEND, "EV Scheduler: Send task" },
|
// { EV_NANOS6_SCHED_SEND, "EV Scheduler: Send task" },
|
||||||
{ EV_NANOS6_SCHED_RECV, "EV Scheduler: Recv task" },
|
// { EV_NANOS6_SCHED_RECV, "EV Scheduler: Recv task" },
|
||||||
{ EV_NANOS6_SCHED_SELF, "EV Scheduler: Self-assign task" },
|
// { EV_NANOS6_SCHED_SELF, "EV Scheduler: Self-assign task" },
|
||||||
{ EV_NANOS6_CPU_IDLE, "EV CPU: Becomes idle" },
|
// { EV_NANOS6_CPU_IDLE, "EV CPU: Becomes idle" },
|
||||||
{ EV_NANOS6_CPU_ACTIVE, "EV CPU: Becomes active" },
|
// { EV_NANOS6_CPU_ACTIVE, "EV CPU: Becomes active" },
|
||||||
{ EV_NANOS6_SIGNAL, "EV Worker: Wakening another thread" },
|
// { EV_NANOS6_SIGNAL, "EV Worker: Wakening another thread" },
|
||||||
{ -1, NULL },
|
// { -1, NULL },
|
||||||
};
|
//};
|
||||||
|
//
|
||||||
struct pcf_value_label nanos6_thread_type[] = {
|
//struct pcf_value_label nanos6_thread_type[] = {
|
||||||
{ ST_NULL, "No type" },
|
// { ST_NULL, "No type" },
|
||||||
{ ST_TOO_MANY_TH, "Unknown: multiple threads running" },
|
// { ST_TOO_MANY_TH, "Unknown: multiple threads running" },
|
||||||
{ ST_NANOS6_TH_EXTERNAL, "External" },
|
// { ST_NANOS6_TH_EXTERNAL, "External" },
|
||||||
{ ST_NANOS6_TH_WORKER, "Worker" },
|
// { ST_NANOS6_TH_WORKER, "Worker" },
|
||||||
{ ST_NANOS6_TH_LEADER, "Leader" },
|
// { ST_NANOS6_TH_LEADER, "Leader" },
|
||||||
{ ST_NANOS6_TH_MAIN, "Main" },
|
// { ST_NANOS6_TH_MAIN, "Main" },
|
||||||
{ -1, NULL },
|
// { -1, NULL },
|
||||||
};
|
//};
|
||||||
|
//
|
||||||
struct pcf_value_label (*pcf_chan_value_labels[CHAN_MAX])[] = {
|
//struct pcf_value_label (*pcf_chan_value_labels[CHAN_MAX])[] = {
|
||||||
[CHAN_OVNI_PID] = &default_values,
|
// [CHAN_OVNI_PID] = &default_values,
|
||||||
[CHAN_OVNI_TID] = &default_values,
|
// [CHAN_OVNI_TID] = &default_values,
|
||||||
[CHAN_OVNI_NRTHREADS] = &default_values,
|
// [CHAN_OVNI_NRTHREADS] = &default_values,
|
||||||
[CHAN_OVNI_STATE] = &ovni_state_values,
|
// [CHAN_OVNI_STATE] = &ovni_state_values,
|
||||||
[CHAN_OVNI_APPID] = &default_values,
|
// [CHAN_OVNI_APPID] = &default_values,
|
||||||
[CHAN_OVNI_CPU] = &default_values,
|
// [CHAN_OVNI_CPU] = &default_values,
|
||||||
[CHAN_OVNI_FLUSH] = &ovni_flush_values,
|
// [CHAN_OVNI_FLUSH] = &ovni_flush_values,
|
||||||
|
//
|
||||||
[CHAN_NOSV_TASKID] = &default_values,
|
// [CHAN_NOSV_TASKID] = &default_values,
|
||||||
[CHAN_NOSV_TYPE] = &default_values,
|
// [CHAN_NOSV_TYPE] = &default_values,
|
||||||
[CHAN_NOSV_APPID] = &default_values,
|
// [CHAN_NOSV_APPID] = &default_values,
|
||||||
[CHAN_NOSV_SUBSYSTEM] = &nosv_ss_values,
|
// [CHAN_NOSV_SUBSYSTEM] = &nosv_ss_values,
|
||||||
[CHAN_NOSV_RANK] = &default_values,
|
// [CHAN_NOSV_RANK] = &default_values,
|
||||||
|
//
|
||||||
[CHAN_NODES_SUBSYSTEM] = &nodes_mode_values,
|
// [CHAN_NODES_SUBSYSTEM] = &nodes_mode_values,
|
||||||
|
//
|
||||||
[CHAN_NANOS6_TASKID] = &default_values,
|
// [CHAN_NANOS6_TASKID] = &default_values,
|
||||||
[CHAN_NANOS6_TYPE] = &default_values,
|
// [CHAN_NANOS6_TYPE] = &default_values,
|
||||||
[CHAN_NANOS6_SUBSYSTEM] = &nanos6_ss_values,
|
// [CHAN_NANOS6_SUBSYSTEM] = &nanos6_ss_values,
|
||||||
[CHAN_NANOS6_RANK] = &default_values,
|
// [CHAN_NANOS6_RANK] = &default_values,
|
||||||
[CHAN_NANOS6_THREAD] = &nanos6_thread_type,
|
// [CHAN_NANOS6_THREAD] = &nanos6_thread_type,
|
||||||
|
//
|
||||||
[CHAN_KERNEL_CS] = &kernel_cs_values,
|
// [CHAN_KERNEL_CS] = &kernel_cs_values,
|
||||||
};
|
//};
|
||||||
|
//
|
||||||
/* ------------------ Type labels --------------------- */
|
///* ------------------ Type labels --------------------- */
|
||||||
|
//
|
||||||
char *pcf_chan_name[CHAN_MAX] = {
|
//char *pcf_chan_name[CHAN_MAX] = {
|
||||||
[CHAN_OVNI_PID] = "PID",
|
// [CHAN_OVNI_PID] = "PID",
|
||||||
[CHAN_OVNI_TID] = "TID",
|
// [CHAN_OVNI_TID] = "TID",
|
||||||
[CHAN_OVNI_NRTHREADS] = "Number of RUNNING threads",
|
// [CHAN_OVNI_NRTHREADS] = "Number of RUNNING threads",
|
||||||
[CHAN_OVNI_STATE] = "Execution state",
|
// [CHAN_OVNI_STATE] = "Execution state",
|
||||||
[CHAN_OVNI_APPID] = "AppID",
|
// [CHAN_OVNI_APPID] = "AppID",
|
||||||
[CHAN_OVNI_CPU] = "CPU affinity",
|
// [CHAN_OVNI_CPU] = "CPU affinity",
|
||||||
[CHAN_OVNI_FLUSH] = "Flushing state",
|
// [CHAN_OVNI_FLUSH] = "Flushing state",
|
||||||
|
//
|
||||||
[CHAN_NOSV_TASKID] = "nOS-V TaskID",
|
// [CHAN_NOSV_TASKID] = "nOS-V TaskID",
|
||||||
[CHAN_NOSV_TYPE] = "nOS-V task type",
|
// [CHAN_NOSV_TYPE] = "nOS-V task type",
|
||||||
[CHAN_NOSV_APPID] = "nOS-V task AppID",
|
// [CHAN_NOSV_APPID] = "nOS-V task AppID",
|
||||||
[CHAN_NOSV_SUBSYSTEM] = "nOS-V subsystem",
|
// [CHAN_NOSV_SUBSYSTEM] = "nOS-V subsystem",
|
||||||
[CHAN_NOSV_RANK] = "nOS-V task MPI rank",
|
// [CHAN_NOSV_RANK] = "nOS-V task MPI rank",
|
||||||
|
//
|
||||||
[CHAN_NODES_SUBSYSTEM] = "NODES subsystem",
|
// [CHAN_NODES_SUBSYSTEM] = "NODES subsystem",
|
||||||
|
//
|
||||||
[CHAN_NANOS6_TASKID] = "Nanos6 task ID",
|
// [CHAN_NANOS6_TASKID] = "Nanos6 task ID",
|
||||||
[CHAN_NANOS6_TYPE] = "Nanos6 task type",
|
// [CHAN_NANOS6_TYPE] = "Nanos6 task type",
|
||||||
[CHAN_NANOS6_SUBSYSTEM] = "Nanos6 subsystem",
|
// [CHAN_NANOS6_SUBSYSTEM] = "Nanos6 subsystem",
|
||||||
[CHAN_NANOS6_RANK] = "Nanos6 task MPI rank",
|
// [CHAN_NANOS6_RANK] = "Nanos6 task MPI rank",
|
||||||
[CHAN_NANOS6_THREAD] = "Nanos6 thread type",
|
// [CHAN_NANOS6_THREAD] = "Nanos6 thread type",
|
||||||
|
//
|
||||||
[CHAN_KERNEL_CS] = "Context switches",
|
// [CHAN_KERNEL_CS] = "Context switches",
|
||||||
};
|
//};
|
||||||
|
//
|
||||||
enum pcf_suffix { NONE = 0, CUR_TH, RUN_TH, ACT_TH, SUFFIX_MAX };
|
//enum pcf_suffix { NONE = 0, CUR_TH, RUN_TH, ACT_TH, SUFFIX_MAX };
|
||||||
|
//
|
||||||
char *pcf_suffix_name[SUFFIX_MAX] = {
|
//char *pcf_suffix_name[SUFFIX_MAX] = {
|
||||||
[NONE] = "",
|
// [NONE] = "",
|
||||||
[CUR_TH] = "of the CURRENT thread",
|
// [CUR_TH] = "of the CURRENT thread",
|
||||||
[RUN_TH] = "of the RUNNING thread",
|
// [RUN_TH] = "of the RUNNING thread",
|
||||||
[ACT_TH] = "of the ACTIVE thread",
|
// [ACT_TH] = "of the ACTIVE thread",
|
||||||
};
|
//};
|
||||||
|
//
|
||||||
int pcf_chan_suffix[CHAN_MAX][CHAN_MAXTYPE] = {
|
//int pcf_chan_suffix[CHAN_MAX][CHAN_MAXTYPE] = {
|
||||||
/* Thread CPU */
|
// /* Thread CPU */
|
||||||
[CHAN_OVNI_PID] = { RUN_TH, RUN_TH },
|
// [CHAN_OVNI_PID] = { RUN_TH, RUN_TH },
|
||||||
[CHAN_OVNI_TID] = { RUN_TH, RUN_TH },
|
// [CHAN_OVNI_TID] = { RUN_TH, RUN_TH },
|
||||||
[CHAN_OVNI_NRTHREADS] = { NONE, NONE },
|
// [CHAN_OVNI_NRTHREADS] = { NONE, NONE },
|
||||||
[CHAN_OVNI_STATE] = { CUR_TH, NONE },
|
// [CHAN_OVNI_STATE] = { CUR_TH, NONE },
|
||||||
[CHAN_OVNI_APPID] = { NONE, RUN_TH },
|
// [CHAN_OVNI_APPID] = { NONE, RUN_TH },
|
||||||
[CHAN_OVNI_CPU] = { CUR_TH, NONE },
|
// [CHAN_OVNI_CPU] = { CUR_TH, NONE },
|
||||||
[CHAN_OVNI_FLUSH] = { CUR_TH, RUN_TH },
|
// [CHAN_OVNI_FLUSH] = { CUR_TH, RUN_TH },
|
||||||
|
//
|
||||||
[CHAN_NOSV_TASKID] = { RUN_TH, RUN_TH },
|
// [CHAN_NOSV_TASKID] = { RUN_TH, RUN_TH },
|
||||||
[CHAN_NOSV_TYPE] = { RUN_TH, RUN_TH },
|
// [CHAN_NOSV_TYPE] = { RUN_TH, RUN_TH },
|
||||||
[CHAN_NOSV_APPID] = { RUN_TH, RUN_TH },
|
// [CHAN_NOSV_APPID] = { RUN_TH, RUN_TH },
|
||||||
[CHAN_NOSV_SUBSYSTEM] = { ACT_TH, RUN_TH },
|
// [CHAN_NOSV_SUBSYSTEM] = { ACT_TH, RUN_TH },
|
||||||
[CHAN_NOSV_RANK] = { RUN_TH, RUN_TH },
|
// [CHAN_NOSV_RANK] = { RUN_TH, RUN_TH },
|
||||||
|
//
|
||||||
[CHAN_NODES_SUBSYSTEM] = { RUN_TH, RUN_TH },
|
// [CHAN_NODES_SUBSYSTEM] = { RUN_TH, RUN_TH },
|
||||||
|
//
|
||||||
[CHAN_NANOS6_TASKID] = { RUN_TH, RUN_TH },
|
// [CHAN_NANOS6_TASKID] = { RUN_TH, RUN_TH },
|
||||||
[CHAN_NANOS6_TYPE] = { RUN_TH, RUN_TH },
|
// [CHAN_NANOS6_TYPE] = { RUN_TH, RUN_TH },
|
||||||
[CHAN_NANOS6_SUBSYSTEM] = { ACT_TH, RUN_TH },
|
// [CHAN_NANOS6_SUBSYSTEM] = { ACT_TH, RUN_TH },
|
||||||
[CHAN_NANOS6_RANK] = { RUN_TH, RUN_TH },
|
// [CHAN_NANOS6_RANK] = { RUN_TH, RUN_TH },
|
||||||
[CHAN_NANOS6_THREAD] = { RUN_TH, NONE },
|
// [CHAN_NANOS6_THREAD] = { RUN_TH, NONE },
|
||||||
|
//
|
||||||
[CHAN_KERNEL_CS] = { RUN_TH, ACT_TH },
|
// [CHAN_KERNEL_CS] = { RUN_TH, ACT_TH },
|
||||||
};
|
//};
|
||||||
|
|
||||||
/* clang-format on */
|
/* clang-format on */
|
||||||
|
|
||||||
@ -324,61 +323,20 @@ write_types(struct pcf *pcf)
|
|||||||
write_type(pcf->f, t);
|
write_type(pcf->f, t);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
create_values(struct pcf_type *t, enum chan c)
|
|
||||||
{
|
|
||||||
struct pcf_value_label(*q)[] = pcf_chan_value_labels[c];
|
|
||||||
|
|
||||||
if (q == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
for (struct pcf_value_label *p = *q; p->label != NULL; p++)
|
|
||||||
pcf_add_value(t, p->value, p->label);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
create_type(struct pcf *pcf, enum chan c)
|
|
||||||
{
|
|
||||||
enum chan_type ct = pcf->chantype;
|
|
||||||
int prv_type = chan_to_prvtype[c];
|
|
||||||
|
|
||||||
if (prv_type == -1)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* Compute the label by joining the two parts */
|
|
||||||
char *prefix = pcf_chan_name[c];
|
|
||||||
int isuffix = pcf_chan_suffix[c][ct];
|
|
||||||
char *suffix = pcf_suffix_name[isuffix];
|
|
||||||
|
|
||||||
char label[MAX_PCF_LABEL];
|
|
||||||
int ret = snprintf(label, MAX_PCF_LABEL, "%s %s",
|
|
||||||
prefix, suffix);
|
|
||||||
|
|
||||||
if (ret >= MAX_PCF_LABEL)
|
|
||||||
die("computed type label too long\n");
|
|
||||||
|
|
||||||
struct pcf_type *t = pcf_add_type(pcf, prv_type, label);
|
|
||||||
|
|
||||||
create_values(t, c);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Open the given PCF file and create the default events. */
|
/** Open the given PCF file and create the default events. */
|
||||||
void
|
int
|
||||||
pcf_open(struct pcf *pcf, char *path, int chantype)
|
pcf_open(struct pcf *pcf, char *path)
|
||||||
{
|
{
|
||||||
memset(pcf, 0, sizeof(*pcf));
|
memset(pcf, 0, sizeof(*pcf));
|
||||||
|
|
||||||
pcf->f = fopen(path, "w");
|
pcf->f = fopen(path, "w");
|
||||||
pcf->chantype = chantype;
|
|
||||||
|
|
||||||
if (pcf->f == NULL) {
|
if (pcf->f == NULL) {
|
||||||
die("cannot open PCF file '%s': %s\n",
|
err("cannot open PCF file '%s':", path);
|
||||||
path, strerror(errno));
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create default types and values */
|
return 0;
|
||||||
for (enum chan c = 0; c < CHAN_MAX; c++)
|
|
||||||
create_type(pcf, c);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct pcf_type *
|
struct pcf_type *
|
||||||
@ -461,17 +419,14 @@ pcf_add_value(struct pcf_type *type, int value, const char *label)
|
|||||||
return pcfvalue;
|
return pcfvalue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Writes the defined event and values to the PCF file. */
|
/** Writes the defined event and values to the PCF file and closes the file. */
|
||||||
void
|
int
|
||||||
pcf_write(struct pcf *pcf)
|
pcf_close(struct pcf *pcf)
|
||||||
{
|
{
|
||||||
write_header(pcf->f);
|
write_header(pcf->f);
|
||||||
write_colors(pcf->f, pcf_palette, pcf_palette_len);
|
write_colors(pcf->f, pcf_palette, pcf_palette_len);
|
||||||
write_types(pcf);
|
write_types(pcf);
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
pcf_close(struct pcf *pcf)
|
|
||||||
{
|
|
||||||
fclose(pcf->f);
|
fclose(pcf->f);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,6 @@ struct pcf_type {
|
|||||||
|
|
||||||
struct pcf {
|
struct pcf {
|
||||||
FILE *f;
|
FILE *f;
|
||||||
int chantype;
|
|
||||||
int pcf_ntypes;
|
int pcf_ntypes;
|
||||||
struct pcf_type *types;
|
struct pcf_type *types;
|
||||||
};
|
};
|
||||||
@ -42,22 +41,12 @@ struct pcf_value_label {
|
|||||||
char *label;
|
char *label;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct pcf_value_label nanos6_ss_values[];
|
int pcf_open(struct pcf *pcf, char *path);
|
||||||
|
int pcf_close(struct pcf *pcf);
|
||||||
void pcf_open(struct pcf *pcf, char *path, int chantype);
|
|
||||||
|
|
||||||
void pcf_write(struct pcf *pcf);
|
|
||||||
|
|
||||||
void pcf_close(struct pcf *pcf);
|
|
||||||
|
|
||||||
struct pcf_type *pcf_find_type(struct pcf *pcf, int type_id);
|
struct pcf_type *pcf_find_type(struct pcf *pcf, int type_id);
|
||||||
|
struct pcf_type *pcf_add_type(struct pcf *pcf, int type_id, const char *label);
|
||||||
struct pcf_type *pcf_add_type(struct pcf *pcf, int type_id,
|
struct pcf_value *pcf_add_value(struct pcf_type *type, int value, const char *label);
|
||||||
const char *label);
|
|
||||||
|
|
||||||
struct pcf_value *pcf_add_value(struct pcf_type *type, int value,
|
|
||||||
const char *label);
|
|
||||||
|
|
||||||
struct pcf_value *pcf_find_value(struct pcf_type *type, int value);
|
struct pcf_value *pcf_find_value(struct pcf_type *type, int value);
|
||||||
|
|
||||||
#endif /* OVNI_PCF_H */
|
#endif /* OVNI_PCF_H */
|
||||||
|
@ -42,13 +42,14 @@ prv_open(struct prv *prv, long nrows, const char *path)
|
|||||||
return prv_open_file(prv, nrows, f);
|
return prv_open_file(prv, nrows, f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
int
|
||||||
prv_close(struct prv *prv)
|
prv_close(struct prv *prv)
|
||||||
{
|
{
|
||||||
/* Fix the header with the current duration */
|
/* Fix the header with the current duration */
|
||||||
fseek(prv->file, 0, SEEK_SET);
|
fseek(prv->file, 0, SEEK_SET);
|
||||||
write_header(prv->file, prv->time, prv->nrows);
|
write_header(prv->file, prv->time, prv->nrows);
|
||||||
fclose(prv->file);
|
fclose(prv->file);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct prv_chan *
|
static struct prv_chan *
|
||||||
|
@ -37,6 +37,6 @@ int prv_open(struct prv *prv, long nrows, const char *path);
|
|||||||
int prv_open_file(struct prv *prv, long nrows, FILE *file);
|
int prv_open_file(struct prv *prv, long nrows, FILE *file);
|
||||||
int prv_register(struct prv *prv, long row, long type, struct bay *bay, struct chan *chan, long flags);
|
int prv_register(struct prv *prv, long row, long type, struct bay *bay, struct chan *chan, long flags);
|
||||||
int prv_advance(struct prv *prv, int64_t time);
|
int prv_advance(struct prv *prv, int64_t time);
|
||||||
void prv_close(struct prv *prv);
|
int prv_close(struct prv *prv);
|
||||||
|
|
||||||
#endif /* PRV_H */
|
#endif /* PRV_H */
|
||||||
|
@ -26,6 +26,17 @@ pvt_open(struct pvt *pvt, long nrows, const char *dir, const char *name)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char pcfpath[PATH_MAX];
|
||||||
|
if (snprintf(pcfpath, PATH_MAX, "%s/%s.pcf", dir, name) >= PATH_MAX) {
|
||||||
|
err("snprintf failed: path too long");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pcf_open(&pvt->pcf, pcfpath) != 0) {
|
||||||
|
err("pcf_open failed");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -35,8 +46,30 @@ pvt_get_prv(struct pvt *pvt)
|
|||||||
return &pvt->prv;
|
return &pvt->prv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct pcf *
|
||||||
|
pvt_get_pcf(struct pvt *pvt)
|
||||||
|
{
|
||||||
|
return &pvt->pcf;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
pvt_advance(struct pvt *pvt, int64_t time)
|
pvt_advance(struct pvt *pvt, int64_t time)
|
||||||
{
|
{
|
||||||
return prv_advance(&pvt->prv, time);
|
return prv_advance(&pvt->prv, time);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
pvt_close(struct pvt *pvt)
|
||||||
|
{
|
||||||
|
if (prv_close(&pvt->prv) != 0) {
|
||||||
|
err("prv_close failed");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pcf_close(&pvt->pcf) != 0) {
|
||||||
|
err("pcf_close failed");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@ -22,5 +22,6 @@ int pvt_open(struct pvt *pvt, long nrows, const char *dir, const char *name);
|
|||||||
struct prv *pvt_get_prv(struct pvt *pvt);
|
struct prv *pvt_get_prv(struct pvt *pvt);
|
||||||
struct pcf *pvt_get_pcf(struct pvt *pvt);
|
struct pcf *pvt_get_pcf(struct pvt *pvt);
|
||||||
int pvt_advance(struct pvt *pvt, int64_t time);
|
int pvt_advance(struct pvt *pvt, int64_t time);
|
||||||
|
int pvt_close(struct pvt *pvt);
|
||||||
|
|
||||||
#endif /* PVT_H */
|
#endif /* PVT_H */
|
||||||
|
@ -64,3 +64,16 @@ recorder_advance(struct recorder *rec, int64_t time)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
recorder_finish(struct recorder *rec)
|
||||||
|
{
|
||||||
|
for (struct pvt *pvt = rec->pvt; pvt; pvt = pvt->hh.next) {
|
||||||
|
if (pvt_close(pvt) != 0) {
|
||||||
|
err("pvt_close failed");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@ -19,5 +19,6 @@ int recorder_init(struct recorder *rec, const char *dir);
|
|||||||
struct pvt *recorder_find_pvt(struct recorder *rec, const char *name);
|
struct pvt *recorder_find_pvt(struct recorder *rec, const char *name);
|
||||||
struct pvt *recorder_add_pvt(struct recorder *rec, const char *name, long nrows);
|
struct pvt *recorder_add_pvt(struct recorder *rec, const char *name, long nrows);
|
||||||
int recorder_advance(struct recorder *rec, int64_t time);
|
int recorder_advance(struct recorder *rec, int64_t time);
|
||||||
|
int recorder_finish(struct recorder *rec);
|
||||||
|
|
||||||
#endif /* RECORDER_H */
|
#endif /* RECORDER_H */
|
||||||
|
Loading…
Reference in New Issue
Block a user