Add dynamic PCF types and values
This commit is contained in:
parent
d460290415
commit
c22457d7d3
50
emu.c
50
emu.c
@ -737,26 +737,10 @@ open_pcfs(struct ovni_emu *emu, char *tracedir)
|
|||||||
char path[PATH_MAX];
|
char path[PATH_MAX];
|
||||||
|
|
||||||
sprintf(path, "%s/%s", tracedir, "thread.pcf");
|
sprintf(path, "%s/%s", tracedir, "thread.pcf");
|
||||||
|
pcf_open(&emu->pcf[CHAN_TH], path, CHAN_TH);
|
||||||
emu->pcf_thread = fopen(path, "w");
|
|
||||||
|
|
||||||
if(emu->pcf_thread == NULL)
|
|
||||||
{
|
|
||||||
err("error opening thread PCF file %s: %s\n", path,
|
|
||||||
strerror(errno));
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
sprintf(path, "%s/%s", tracedir, "cpu.pcf");
|
sprintf(path, "%s/%s", tracedir, "cpu.pcf");
|
||||||
|
pcf_open(&emu->pcf[CHAN_CPU], path, CHAN_CPU);
|
||||||
emu->pcf_cpu = fopen(path, "w");
|
|
||||||
|
|
||||||
if(emu->pcf_cpu == NULL)
|
|
||||||
{
|
|
||||||
err("error opening cpu PCF file %s: %s\n", path,
|
|
||||||
strerror(errno));
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fix the trace duration at the end */
|
/* Fix the trace duration at the end */
|
||||||
@ -777,8 +761,8 @@ close_prvs(struct ovni_emu *emu)
|
|||||||
static void
|
static void
|
||||||
close_pcfs(struct ovni_emu *emu)
|
close_pcfs(struct ovni_emu *emu)
|
||||||
{
|
{
|
||||||
fclose(emu->pcf_thread);
|
pcf_close(&emu->pcf[CHAN_TH]);
|
||||||
fclose(emu->pcf_cpu);
|
pcf_close(&emu->pcf[CHAN_CPU]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -1097,6 +1081,26 @@ init_cpus(struct ovni_emu *emu)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
create_pcf_cpus(struct ovni_emu *emu)
|
||||||
|
{
|
||||||
|
/* Only needed for the thread PCF */
|
||||||
|
struct pcf_file *pcf = &emu->pcf[CHAN_TH];
|
||||||
|
int prvtype = CHAN_PRV_TH(CHAN_OVNI_CPU);
|
||||||
|
struct pcf_type *type = pcf_find_type(pcf, prvtype);
|
||||||
|
|
||||||
|
if (type == NULL)
|
||||||
|
die("cannot find PCF type for CHAN_OVNI_CPU\n");
|
||||||
|
|
||||||
|
for(size_t i=0; i<emu->total_ncpus; i++)
|
||||||
|
{
|
||||||
|
int value = i + 1;
|
||||||
|
char *label = emu->global_cpu[i]->name;
|
||||||
|
|
||||||
|
pcf_add_value(type, value, label);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
emu_init(struct ovni_emu *emu, int argc, char *argv[])
|
emu_init(struct ovni_emu *emu, int argc, char *argv[])
|
||||||
{
|
{
|
||||||
@ -1127,6 +1131,8 @@ emu_init(struct ovni_emu *emu, int argc, char *argv[])
|
|||||||
open_prvs(emu, emu->tracedir);
|
open_prvs(emu, emu->tracedir);
|
||||||
open_pcfs(emu, emu->tracedir);
|
open_pcfs(emu, emu->tracedir);
|
||||||
|
|
||||||
|
create_pcf_cpus(emu);
|
||||||
|
|
||||||
emu->global_size = 0;
|
emu->global_size = 0;
|
||||||
emu->global_offset = 0;
|
emu->global_offset = 0;
|
||||||
|
|
||||||
@ -1139,8 +1145,8 @@ static void
|
|||||||
emu_post(struct ovni_emu *emu)
|
emu_post(struct ovni_emu *emu)
|
||||||
{
|
{
|
||||||
/* Write the PCF files */
|
/* Write the PCF files */
|
||||||
pcf_write(emu->pcf_thread, emu);
|
pcf_write(&emu->pcf[CHAN_TH]);
|
||||||
pcf_write(emu->pcf_cpu, emu);
|
pcf_write(&emu->pcf[CHAN_CPU]);
|
||||||
|
|
||||||
write_row_cpu(emu);
|
write_row_cpu(emu);
|
||||||
write_row_thread(emu);
|
write_row_thread(emu);
|
||||||
|
13
emu.h
13
emu.h
@ -25,6 +25,7 @@
|
|||||||
#include "uthash.h"
|
#include "uthash.h"
|
||||||
#include "parson.h"
|
#include "parson.h"
|
||||||
#include "heap.h"
|
#include "heap.h"
|
||||||
|
#include "pcf.h"
|
||||||
|
|
||||||
/* Emulated thread runtime status */
|
/* Emulated thread runtime status */
|
||||||
enum ethread_state {
|
enum ethread_state {
|
||||||
@ -163,10 +164,10 @@ enum chan {
|
|||||||
CHAN_MAX
|
CHAN_MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
enum chan_to_prv_type {
|
enum chan_type {
|
||||||
CHAN_ID = 0,
|
CHAN_TH = 0,
|
||||||
CHAN_TH = 1,
|
CHAN_CPU = 1,
|
||||||
CHAN_CPU = 2,
|
CHAN_MAXTYPE = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum chan_dirty {
|
enum chan_dirty {
|
||||||
@ -468,8 +469,8 @@ struct ovni_emu {
|
|||||||
|
|
||||||
FILE *prv_thread;
|
FILE *prv_thread;
|
||||||
FILE *prv_cpu;
|
FILE *prv_cpu;
|
||||||
FILE *pcf_thread;
|
|
||||||
FILE *pcf_cpu;
|
struct pcf_file pcf[CHAN_MAXTYPE];
|
||||||
|
|
||||||
char *clock_offset_file;
|
char *clock_offset_file;
|
||||||
char *tracedir;
|
char *tracedir;
|
||||||
|
557
pcf.c
557
pcf.c
@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
const char *pcf_def_header =
|
const char *pcf_def_header =
|
||||||
"DEFAULT_OPTIONS\n"
|
"DEFAULT_OPTIONS\n"
|
||||||
@ -72,91 +73,28 @@ const uint32_t pcf_def_palette[] = {
|
|||||||
LIGHTGREY, /* busy wait */
|
LIGHTGREY, /* busy wait */
|
||||||
RED, /* task */
|
RED, /* task */
|
||||||
GREEN,
|
GREEN,
|
||||||
YELLOW,
|
YELLOW, ORANGE, PURPLE, CYAN, MAGENTA, LIME, PINK,
|
||||||
ORANGE,
|
TEAL, GREY, LAVENDER, BROWN, BEIGE, MAROON, MINT,
|
||||||
PURPLE,
|
OLIVE, APRICOT, NAVY, DEEPBLUE
|
||||||
CYAN,
|
|
||||||
MAGENTA,
|
|
||||||
LIME,
|
|
||||||
PINK,
|
|
||||||
TEAL,
|
|
||||||
GREY,
|
|
||||||
LAVENDER,
|
|
||||||
BROWN,
|
|
||||||
BEIGE,
|
|
||||||
MAROON,
|
|
||||||
MINT,
|
|
||||||
OLIVE,
|
|
||||||
APRICOT,
|
|
||||||
NAVY,
|
|
||||||
DEEPBLUE
|
|
||||||
};
|
};
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
struct event_value {
|
/* Only used to generate tables */
|
||||||
|
struct pcf_value_label {
|
||||||
int value;
|
int value;
|
||||||
const char *label;
|
char *label;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct event_type {
|
/* ------------------ Value labels --------------------- */
|
||||||
int index;
|
|
||||||
int chan_id;
|
|
||||||
int chan_type;
|
|
||||||
const char *label;
|
|
||||||
const struct event_value *values;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* ---------------- CHAN_OVNI_PID ---------------- */
|
struct pcf_value_label default_values[] = {
|
||||||
|
{ ST_TOO_MANY_TH, "Unknown: Multiple threads running" },
|
||||||
static const struct event_value ovni_pid_values[] = {
|
|
||||||
{ 0, "None" },
|
|
||||||
{ ST_TOO_MANY_TH, "Unknown PID: Multiple threads running" },
|
|
||||||
/* FIXME: PID values may collide with error code values */
|
|
||||||
{ -1, NULL },
|
{ -1, NULL },
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct event_type thread_ovni_pid = {
|
struct pcf_value_label ovni_state_values[] = {
|
||||||
0, CHAN_OVNI_PID, CHAN_TH,
|
|
||||||
"Thread: PID of the RUNNING thread",
|
|
||||||
ovni_pid_values
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct event_type cpu_ovni_pid = {
|
|
||||||
0, CHAN_OVNI_PID, CHAN_CPU,
|
|
||||||
"CPU: PID of the RUNNING thread",
|
|
||||||
ovni_pid_values
|
|
||||||
};
|
|
||||||
|
|
||||||
/* ---------------- CHAN_OVNI_TID ---------------- */
|
|
||||||
|
|
||||||
static const struct event_value ovni_tid_values[] = {
|
|
||||||
{ 0, "None" },
|
|
||||||
{ ST_TOO_MANY_TH, "Unknown TID: Multiple threads running" },
|
|
||||||
/* FIXME: TID values may collide with error code values */
|
|
||||||
{ -1, NULL },
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct event_type thread_ovni_tid = {
|
|
||||||
0, CHAN_OVNI_TID, CHAN_TH,
|
|
||||||
"Thread: TID of the RUNNING thread",
|
|
||||||
ovni_tid_values
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct event_type cpu_ovni_tid = {
|
|
||||||
0, CHAN_OVNI_TID, CHAN_CPU,
|
|
||||||
"CPU: TID of the RUNNING thread",
|
|
||||||
ovni_tid_values
|
|
||||||
};
|
|
||||||
|
|
||||||
/* ---------------- CHAN_OVNI_NRTHREADS ---------------- */
|
|
||||||
|
|
||||||
/* Not used */
|
|
||||||
|
|
||||||
/* ---------------- CHAN_OVNI_STATE ---------------- */
|
|
||||||
|
|
||||||
static const struct event_value 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" },
|
||||||
@ -166,121 +104,25 @@ static const struct event_value ovni_state_values[] = {
|
|||||||
{ -1, NULL },
|
{ -1, NULL },
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct event_type thread_ovni_state = {
|
struct pcf_value_label ovni_flush_values[] = {
|
||||||
0, CHAN_OVNI_STATE, CHAN_TH,
|
|
||||||
"Thread: State of the CURRENT thread",
|
|
||||||
ovni_state_values
|
|
||||||
};
|
|
||||||
|
|
||||||
/* PRV CPU not used for the state */
|
|
||||||
|
|
||||||
/* ---------------- CHAN_OVNI_APPID ---------------- */
|
|
||||||
|
|
||||||
/* Not used */
|
|
||||||
|
|
||||||
/* ---------------- CHAN_OVNI_CPU ---------------- */
|
|
||||||
|
|
||||||
static const struct event_type thread_cpu_affinity = {
|
|
||||||
0, CHAN_OVNI_CPU, CHAN_TH,
|
|
||||||
"Thread: CPU affinity of the CURRENT thread",
|
|
||||||
/* Ignored */ NULL
|
|
||||||
};
|
|
||||||
|
|
||||||
/* ---------------- CHAN_OVNI_FLUSH ---------------- */
|
|
||||||
|
|
||||||
static const struct event_value 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 },
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct event_type thread_ovni_flush = {
|
struct pcf_value_label nosv_ss_values[] = {
|
||||||
0, CHAN_OVNI_FLUSH, CHAN_TH,
|
|
||||||
"Thread: Flushing state of the CURRENT thread",
|
|
||||||
ovni_flush_values
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct event_type cpu_ovni_flush = {
|
|
||||||
0, CHAN_OVNI_FLUSH, CHAN_CPU,
|
|
||||||
"CPU: Flusing state of the RUNNING thread",
|
|
||||||
ovni_flush_values
|
|
||||||
};
|
|
||||||
|
|
||||||
/* ---------------- CHAN_NOSV_TASKID ---------------- */
|
|
||||||
|
|
||||||
static const struct event_value nosv_taskid_values[] = {
|
|
||||||
{ ST_TOO_MANY_TH, "Unknown TaskID: Multiple threads running" },
|
|
||||||
/* FIXME: Task ID values may collide with error code values */
|
|
||||||
{ -1, NULL },
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct event_type thread_nosv_taskid = {
|
|
||||||
0, CHAN_NOSV_TASKID, CHAN_TH,
|
|
||||||
"Thread: nOS-V TaskID of the RUNNING thread",
|
|
||||||
nosv_taskid_values
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct event_type cpu_nosv_taskid = {
|
|
||||||
0, CHAN_NOSV_TASKID, CHAN_CPU,
|
|
||||||
"CPU: nOS-V TaskID of the RUNNING thread",
|
|
||||||
nosv_taskid_values
|
|
||||||
};
|
|
||||||
|
|
||||||
/* ---------------- CHAN_NOSV_TYPEID ---------------- */
|
|
||||||
|
|
||||||
static const struct event_value nosv_typeid_values[] = {
|
|
||||||
{ ST_TOO_MANY_TH, "Unknown Task TypeID: Multiple threads running" },
|
|
||||||
/* FIXME: Task ID values may collide with error code values */
|
|
||||||
{ -1, NULL },
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct event_type thread_nosv_typeid = {
|
|
||||||
0, CHAN_NOSV_TYPEID, CHAN_TH,
|
|
||||||
"Thread: nOS-V task TypeID of the RUNNING thread",
|
|
||||||
nosv_typeid_values
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct event_type cpu_nosv_typeid = {
|
|
||||||
0, CHAN_NOSV_TYPEID, CHAN_CPU,
|
|
||||||
"CPU: nOS-V task TypeID of the RUNNING thread",
|
|
||||||
nosv_typeid_values
|
|
||||||
};
|
|
||||||
|
|
||||||
/* ---------------- CHAN_NOSV_APPID ---------------- */
|
|
||||||
|
|
||||||
static const struct event_value nosv_appid_values[] = {
|
|
||||||
{ ST_TOO_MANY_TH, "Unknown Task AppID: Multiple threads running" },
|
|
||||||
/* FIXME: Task ID values may collide with error code values */
|
|
||||||
{ -1, NULL },
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct event_type thread_nosv_appid = {
|
|
||||||
0, CHAN_NOSV_APPID, CHAN_TH,
|
|
||||||
"Thread: nOS-V task AppID of the RUNNING thread",
|
|
||||||
nosv_appid_values
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct event_type cpu_nosv_appid = {
|
|
||||||
0, CHAN_NOSV_APPID, CHAN_CPU,
|
|
||||||
"CPU: nOS-V task AppID of the RUNNING thread",
|
|
||||||
nosv_appid_values
|
|
||||||
};
|
|
||||||
|
|
||||||
/* ---------------- CHAN_NOSV_SUBSYSTEM ---------------- */
|
|
||||||
|
|
||||||
static const struct event_value nosv_ss_values[] = {
|
|
||||||
/* Errors */
|
/* Errors */
|
||||||
{ ST_BAD, "Unknown subsystem: Bad happened (report bug)" },
|
{ ST_BAD, "Unknown: bad happened (report bug)" },
|
||||||
{ ST_TOO_MANY_TH, "Unknown subsystem: 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_TASK_RUNNING, "Task: Running" },
|
|
||||||
{ 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_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" },
|
||||||
@ -295,21 +137,7 @@ static const struct event_value nosv_ss_values[] = {
|
|||||||
{ -1, NULL },
|
{ -1, NULL },
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct event_type thread_nosv_ss = {
|
struct pcf_value_label tampi_mode_values[] = {
|
||||||
0, CHAN_NOSV_SUBSYSTEM, CHAN_TH,
|
|
||||||
"Thread: nOS-V subsystem of the ACTIVE thread",
|
|
||||||
nosv_ss_values
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct event_type cpu_nosv_ss = {
|
|
||||||
0, CHAN_NOSV_SUBSYSTEM, CHAN_CPU,
|
|
||||||
"CPU: nOS-V subsystem of the RUNNING thread",
|
|
||||||
nosv_ss_values
|
|
||||||
};
|
|
||||||
|
|
||||||
/* ---------------- CHAN_TAMPI_MODE ---------------- */
|
|
||||||
|
|
||||||
static const struct event_value tampi_mode_values[] = {
|
|
||||||
{ ST_NULL, "NULL" },
|
{ ST_NULL, "NULL" },
|
||||||
{ ST_TOO_MANY_TH, "TAMPI: Unknown, multiple threads running" },
|
{ ST_TOO_MANY_TH, "TAMPI: Unknown, multiple threads running" },
|
||||||
{ ST_TAMPI_SEND, "TAMPI: Send" },
|
{ ST_TAMPI_SEND, "TAMPI: Send" },
|
||||||
@ -321,21 +149,7 @@ static const struct event_value tampi_mode_values[] = {
|
|||||||
{ -1, NULL },
|
{ -1, NULL },
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct event_type thread_tampi_mode = {
|
struct pcf_value_label openmp_mode_values[] = {
|
||||||
0, CHAN_TAMPI_MODE, CHAN_TH,
|
|
||||||
"Thread: TAMPI mode of the RUNNING thread",
|
|
||||||
tampi_mode_values
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct event_type cpu_tampi_mode = {
|
|
||||||
0, CHAN_TAMPI_MODE, CHAN_CPU,
|
|
||||||
"CPU: TAMPI mode of the RUNNING thread",
|
|
||||||
tampi_mode_values
|
|
||||||
};
|
|
||||||
|
|
||||||
/* ---------------- CHAN_OPENMP_MODE ---------------- */
|
|
||||||
|
|
||||||
static const struct event_value openmp_mode_values[] = {
|
|
||||||
{ ST_NULL, "NULL" },
|
{ ST_NULL, "NULL" },
|
||||||
{ ST_TOO_MANY_TH, "OpenMP: Unknown, multiple threads running" },
|
{ ST_TOO_MANY_TH, "OpenMP: Unknown, multiple threads running" },
|
||||||
{ ST_OPENMP_TASK, "OpenMP: Task" },
|
{ ST_OPENMP_TASK, "OpenMP: Task" },
|
||||||
@ -343,21 +157,7 @@ static const struct event_value openmp_mode_values[] = {
|
|||||||
{ -1, NULL },
|
{ -1, NULL },
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct event_type thread_openmp_mode = {
|
struct pcf_value_label nodes_mode_values[] = {
|
||||||
0, CHAN_OPENMP_MODE, CHAN_TH,
|
|
||||||
"Thread: OpenMP mode of the RUNNING thread",
|
|
||||||
openmp_mode_values
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct event_type cpu_openmp_mode = {
|
|
||||||
0, CHAN_OPENMP_MODE, CHAN_CPU,
|
|
||||||
"CPU: OpenMP mode of the RUNNING thread",
|
|
||||||
openmp_mode_values
|
|
||||||
};
|
|
||||||
|
|
||||||
/* ---------------- CHAN_NODES_SUBSYSTEM ---------------- */
|
|
||||||
|
|
||||||
static const struct event_value 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" },
|
||||||
@ -371,37 +171,89 @@ static const struct event_value nodes_mode_values[] = {
|
|||||||
{ -1, NULL },
|
{ -1, NULL },
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct event_type cpu_nodes_mode = {
|
struct pcf_value_label kernel_cs_values[] = {
|
||||||
0, CHAN_NODES_SUBSYSTEM, CHAN_CPU,
|
|
||||||
"CPU: NODES subsystem of the RUNNING thread",
|
|
||||||
nodes_mode_values
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct event_type thread_nodes_mode = {
|
|
||||||
0, CHAN_NODES_SUBSYSTEM, CHAN_TH,
|
|
||||||
"Thread: NODES subsystem of the RUNNING thread",
|
|
||||||
nodes_mode_values
|
|
||||||
};
|
|
||||||
|
|
||||||
/* ---------------- CHAN_KERNEL_CS ---------------- */
|
|
||||||
|
|
||||||
struct event_value kernel_cs_values[] = {
|
|
||||||
{ ST_NULL, "NULL" },
|
{ ST_NULL, "NULL" },
|
||||||
{ ST_TOO_MANY_TH, "Kernel CS: 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 event_type cpu_kernel_cs = {
|
struct pcf_value_label (*pcf_chan_value_labels[CHAN_MAX])[] = {
|
||||||
0, CHAN_KERNEL_CS, CHAN_CPU,
|
[CHAN_OVNI_PID] = &default_values,
|
||||||
"CPU: Context switches of the ACTIVE thread",
|
[CHAN_OVNI_TID] = &default_values,
|
||||||
kernel_cs_values
|
[CHAN_OVNI_NRTHREADS] = &default_values,
|
||||||
|
[CHAN_OVNI_STATE] = &ovni_state_values,
|
||||||
|
[CHAN_OVNI_APPID] = &default_values,
|
||||||
|
[CHAN_OVNI_CPU] = &default_values,
|
||||||
|
[CHAN_OVNI_FLUSH] = &ovni_flush_values,
|
||||||
|
|
||||||
|
[CHAN_NOSV_TASKID] = &default_values,
|
||||||
|
[CHAN_NOSV_TYPEID] = &default_values,
|
||||||
|
[CHAN_NOSV_APPID] = &default_values,
|
||||||
|
[CHAN_NOSV_SUBSYSTEM] = &nosv_ss_values,
|
||||||
|
[CHAN_NOSV_RANK] = &default_values,
|
||||||
|
|
||||||
|
[CHAN_TAMPI_MODE] = &tampi_mode_values,
|
||||||
|
[CHAN_OPENMP_MODE] = &openmp_mode_values,
|
||||||
|
[CHAN_NODES_SUBSYSTEM] = &nodes_mode_values,
|
||||||
|
|
||||||
|
[CHAN_KERNEL_CS] = &kernel_cs_values,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct event_type thread_kernel_cs = {
|
/* ------------------ Type labels --------------------- */
|
||||||
0, CHAN_KERNEL_CS, CHAN_TH,
|
|
||||||
"Thread: Context switches of the CURRENT thread",
|
char *pcf_chan_name[CHAN_MAX] = {
|
||||||
kernel_cs_values
|
[CHAN_OVNI_PID] = "PID",
|
||||||
|
[CHAN_OVNI_TID] = "TID",
|
||||||
|
[CHAN_OVNI_NRTHREADS] = "Number of RUNNING threads",
|
||||||
|
[CHAN_OVNI_STATE] = "Execution state",
|
||||||
|
[CHAN_OVNI_APPID] = "AppID",
|
||||||
|
[CHAN_OVNI_CPU] = "CPU affinity",
|
||||||
|
[CHAN_OVNI_FLUSH] = "Flushing state",
|
||||||
|
|
||||||
|
[CHAN_NOSV_TASKID] = "nOS-V TaskID",
|
||||||
|
[CHAN_NOSV_TYPEID] = "nOS-V task TypeID",
|
||||||
|
[CHAN_NOSV_APPID] = "nOS-V task AppID",
|
||||||
|
[CHAN_NOSV_SUBSYSTEM] = "nOS-V subsystem",
|
||||||
|
[CHAN_NOSV_RANK] = "MPI rank",
|
||||||
|
|
||||||
|
[CHAN_TAMPI_MODE] = "TAMPI mode",
|
||||||
|
[CHAN_OPENMP_MODE] = "OpenMP mode",
|
||||||
|
[CHAN_NODES_SUBSYSTEM] = "NODES subsystem",
|
||||||
|
|
||||||
|
[CHAN_KERNEL_CS] = "Context switches",
|
||||||
|
};
|
||||||
|
|
||||||
|
enum pcf_suffix { NONE = 0, CUR_TH, RUN_TH, ACT_TH, SUFFIX_MAX };
|
||||||
|
|
||||||
|
char *pcf_suffix_name[SUFFIX_MAX] = {
|
||||||
|
[NONE] = "",
|
||||||
|
[CUR_TH] = "of the CURRENT thread",
|
||||||
|
[RUN_TH] = "of the RUNNING thread",
|
||||||
|
[ACT_TH] = "of the ACTIVE thread",
|
||||||
|
};
|
||||||
|
|
||||||
|
int pcf_chan_suffix[CHAN_MAX][CHAN_MAXTYPE] = {
|
||||||
|
/* Thread CPU */
|
||||||
|
[CHAN_OVNI_PID] = { CUR_TH, CUR_TH },
|
||||||
|
[CHAN_OVNI_TID] = { CUR_TH, CUR_TH },
|
||||||
|
[CHAN_OVNI_NRTHREADS] = { NONE, NONE },
|
||||||
|
[CHAN_OVNI_STATE] = { CUR_TH, NONE },
|
||||||
|
[CHAN_OVNI_APPID] = { NONE, RUN_TH },
|
||||||
|
[CHAN_OVNI_CPU] = { CUR_TH, NONE },
|
||||||
|
[CHAN_OVNI_FLUSH] = { CUR_TH, RUN_TH },
|
||||||
|
|
||||||
|
[CHAN_NOSV_TASKID] = { RUN_TH, RUN_TH },
|
||||||
|
[CHAN_NOSV_TYPEID] = { RUN_TH, RUN_TH },
|
||||||
|
[CHAN_NOSV_APPID] = { RUN_TH, RUN_TH },
|
||||||
|
[CHAN_NOSV_SUBSYSTEM] = { ACT_TH, RUN_TH },
|
||||||
|
[CHAN_NOSV_RANK] = { RUN_TH, RUN_TH },
|
||||||
|
|
||||||
|
[CHAN_TAMPI_MODE] = { RUN_TH, RUN_TH },
|
||||||
|
[CHAN_OPENMP_MODE] = { RUN_TH, RUN_TH },
|
||||||
|
[CHAN_NODES_SUBSYSTEM] = { RUN_TH, RUN_TH },
|
||||||
|
|
||||||
|
[CHAN_KERNEL_CS] = { CUR_TH, ACT_TH },
|
||||||
};
|
};
|
||||||
|
|
||||||
/* ----------------------------------------------- */
|
/* ----------------------------------------------- */
|
||||||
@ -437,94 +289,173 @@ write_colors(FILE *f, const uint32_t *palette, int n)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
write_event_type_header(FILE *f, int index, int type, const char *label)
|
write_type(FILE *f, struct pcf_type *type)
|
||||||
{
|
{
|
||||||
fprintf(f, "\n\n");
|
fprintf(f, "\n\n");
|
||||||
fprintf(f, "EVENT_TYPE\n");
|
fprintf(f, "EVENT_TYPE\n");
|
||||||
fprintf(f, "%-4d %-10d %s\n", index, type, label);
|
fprintf(f, "0 %-10d %s\n", type->id, type->label);
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
write_event_type(FILE *f, const struct event_type *ev)
|
|
||||||
{
|
|
||||||
int i, type;
|
|
||||||
|
|
||||||
type = chan_to_prvtype[ev->chan_id][ev->chan_type];
|
|
||||||
write_event_type_header(f, ev->index, type, ev->label);
|
|
||||||
|
|
||||||
fprintf(f, "VALUES\n");
|
fprintf(f, "VALUES\n");
|
||||||
|
|
||||||
for(i=0; ev->values[i].label; i++)
|
for(struct pcf_value *v = type->values; v != NULL; v = v->hh.next)
|
||||||
{
|
fprintf(f, "%-4d %s\n", v->value, v->label);
|
||||||
fprintf(f, "%-4d %s\n",
|
|
||||||
ev->values[i].value,
|
|
||||||
ev->values[i].label);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
write_cpu_type(FILE *f, const struct event_type *ev, struct ovni_emu *emu)
|
write_types(struct pcf_file *pcf)
|
||||||
{
|
{
|
||||||
size_t i;
|
struct pcf_type *t;
|
||||||
int type;
|
|
||||||
|
|
||||||
type = chan_to_prvtype[ev->chan_id][ev->chan_type];
|
for(t = pcf->types; t != NULL; t = t->hh.next)
|
||||||
write_event_type_header(f, ev->index, type, ev->label);
|
write_type(pcf->f, t);
|
||||||
|
|
||||||
fprintf(f, "VALUES\n");
|
|
||||||
|
|
||||||
for(i=0; i<emu->total_ncpus; i++)
|
|
||||||
{
|
|
||||||
fprintf(f, "%-4ld %s\n", i+1, emu->global_cpu[i]->name);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
write_events(FILE *f, struct ovni_emu *emu)
|
create_values(struct pcf_type *t, enum chan c)
|
||||||
{
|
{
|
||||||
/* Threads */
|
struct pcf_value_label (*q)[] = pcf_chan_value_labels[c];
|
||||||
write_event_type(f, &thread_ovni_pid);
|
|
||||||
write_event_type(f, &thread_ovni_tid);
|
|
||||||
/* thread_ovni_nthreads not needed */
|
|
||||||
write_event_type(f, &thread_ovni_state);
|
|
||||||
/* thread_ovni_appid not needed */
|
|
||||||
write_event_type(f, &thread_ovni_flush);
|
|
||||||
write_event_type(f, &thread_nosv_taskid);
|
|
||||||
write_event_type(f, &thread_nosv_typeid);
|
|
||||||
write_event_type(f, &thread_nosv_appid);
|
|
||||||
write_event_type(f, &thread_nosv_ss);
|
|
||||||
write_event_type(f, &thread_tampi_mode);
|
|
||||||
write_event_type(f, &thread_openmp_mode);
|
|
||||||
write_event_type(f, &thread_nodes_mode);
|
|
||||||
write_event_type(f, &thread_kernel_cs);
|
|
||||||
|
|
||||||
/* CPU */
|
if(q == NULL)
|
||||||
write_event_type(f, &cpu_ovni_pid);
|
return;
|
||||||
write_event_type(f, &cpu_ovni_tid);
|
|
||||||
/* cpu_ovni_nthreads not needed */
|
|
||||||
/* cpu_ovni_state not needed */
|
|
||||||
/* cpu_ovni_appid not needed */
|
|
||||||
/* cpu_ovni_cpu not needed */
|
|
||||||
write_event_type(f, &cpu_ovni_flush);
|
|
||||||
write_event_type(f, &cpu_nosv_taskid);
|
|
||||||
write_event_type(f, &cpu_nosv_typeid);
|
|
||||||
write_event_type(f, &cpu_nosv_appid);
|
|
||||||
write_event_type(f, &cpu_nosv_ss);
|
|
||||||
write_event_type(f, &cpu_tampi_mode);
|
|
||||||
write_event_type(f, &cpu_openmp_mode);
|
|
||||||
write_event_type(f, &cpu_nodes_mode);
|
|
||||||
write_event_type(f, &cpu_kernel_cs);
|
|
||||||
|
|
||||||
/* Custom */
|
for(struct pcf_value_label *p = *q; p->label != NULL; p++)
|
||||||
write_cpu_type(f, &thread_cpu_affinity, emu);
|
pcf_add_value(t, p->value, p->label);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
static void
|
||||||
pcf_write(FILE *f, struct ovni_emu *emu)
|
create_type(struct pcf_file *pcf, enum chan c)
|
||||||
{
|
{
|
||||||
write_header(f);
|
char label[MAX_PCF_LABEL];
|
||||||
write_colors(f, pcf_palette, pcf_palette_len);
|
enum chan_type ct = pcf->chantype;
|
||||||
write_events(f, emu);
|
int prv_type = chan_to_prvtype[c][ct];
|
||||||
|
|
||||||
return 0;
|
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];
|
||||||
|
|
||||||
|
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. */
|
||||||
|
void
|
||||||
|
pcf_open(struct pcf_file *pcf, char *path, int chantype)
|
||||||
|
{
|
||||||
|
memset(pcf, 0, sizeof(*pcf));
|
||||||
|
|
||||||
|
pcf->f = fopen(path, "w");
|
||||||
|
pcf->chantype = chantype;
|
||||||
|
|
||||||
|
if(pcf->f == NULL)
|
||||||
|
{
|
||||||
|
die("cannot open PCF file '%s': %s\n",
|
||||||
|
path, strerror(errno));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create default types and values */
|
||||||
|
for(enum chan c = 0; c < CHAN_MAX; c++)
|
||||||
|
create_type(pcf, c);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct pcf_type *
|
||||||
|
pcf_find_type(struct pcf_file *pcf, int type_id)
|
||||||
|
{
|
||||||
|
struct pcf_type *type;
|
||||||
|
|
||||||
|
HASH_FIND_INT(pcf->types, &type_id, type);
|
||||||
|
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Creates a new pcf_type with the given type_id and label. The label
|
||||||
|
* can be disposed after return.
|
||||||
|
*
|
||||||
|
* @return The pcf_type created.
|
||||||
|
*/
|
||||||
|
struct pcf_type *
|
||||||
|
pcf_add_type(struct pcf_file *pcf, int type_id, const char *label)
|
||||||
|
{
|
||||||
|
struct pcf_type *type;
|
||||||
|
|
||||||
|
type = pcf_find_type(pcf, type_id);
|
||||||
|
|
||||||
|
if(type != NULL)
|
||||||
|
die("PCF type %d already defined\n", type_id);
|
||||||
|
|
||||||
|
type = calloc(1, sizeof(struct pcf_type));
|
||||||
|
|
||||||
|
if(type == NULL)
|
||||||
|
die("calloc failed: %s\n", strerror(errno));
|
||||||
|
|
||||||
|
type->id = type_id;
|
||||||
|
type->values = NULL;
|
||||||
|
type->nvalues = 0;
|
||||||
|
if(snprintf(type->label, MAX_PCF_LABEL,
|
||||||
|
"%s", label) >= MAX_PCF_LABEL)
|
||||||
|
{
|
||||||
|
die("PCF label too long\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
HASH_ADD_INT(pcf->types, id, type);
|
||||||
|
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Adds a new value to the given pcf_type. The label can be disposed
|
||||||
|
* after return.
|
||||||
|
*
|
||||||
|
* @return The new pcf_value created
|
||||||
|
*/
|
||||||
|
struct pcf_value *
|
||||||
|
pcf_add_value(struct pcf_type *type, int value, const char *label)
|
||||||
|
{
|
||||||
|
struct pcf_value *pv;
|
||||||
|
|
||||||
|
HASH_FIND_INT(type->values, &value, pv);
|
||||||
|
|
||||||
|
if(pv != NULL)
|
||||||
|
die("PCF value %d already in type %d\n", value, type->id);
|
||||||
|
|
||||||
|
pv = calloc(1, sizeof(struct pcf_value));
|
||||||
|
|
||||||
|
if(pv == NULL)
|
||||||
|
die("calloc failed: %s\n", strerror(errno));
|
||||||
|
|
||||||
|
pv->value = value;
|
||||||
|
|
||||||
|
int len = snprintf(pv->label, MAX_PCF_LABEL, "%s", label);
|
||||||
|
|
||||||
|
if(len >= MAX_PCF_LABEL)
|
||||||
|
die("PCF label too long\n");
|
||||||
|
|
||||||
|
HASH_ADD_INT(type->values, value, pv);
|
||||||
|
|
||||||
|
type->nvalues++;
|
||||||
|
|
||||||
|
return pv;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Writes the defined event and values to the PCF file. */
|
||||||
|
void
|
||||||
|
pcf_write(struct pcf_file *pcf)
|
||||||
|
{
|
||||||
|
write_header(pcf->f);
|
||||||
|
write_colors(pcf->f, pcf_palette, pcf_palette_len);
|
||||||
|
write_types(pcf);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
pcf_close(struct pcf_file *pcf)
|
||||||
|
{
|
||||||
|
fclose(pcf->f);
|
||||||
}
|
}
|
||||||
|
46
pcf.h
46
pcf.h
@ -19,9 +19,49 @@
|
|||||||
#define OVNI_PCF_H
|
#define OVNI_PCF_H
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "emu.h"
|
#include "uthash.h"
|
||||||
|
|
||||||
int
|
#define MAX_PCF_LABEL 512
|
||||||
pcf_write(FILE *f, struct ovni_emu *emu);
|
|
||||||
|
struct pcf_value;
|
||||||
|
struct pcf_type;
|
||||||
|
|
||||||
|
struct pcf_value {
|
||||||
|
int value;
|
||||||
|
char label[MAX_PCF_LABEL];
|
||||||
|
|
||||||
|
UT_hash_handle hh;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct pcf_type {
|
||||||
|
int id;
|
||||||
|
char label[MAX_PCF_LABEL];
|
||||||
|
|
||||||
|
int nvalues;
|
||||||
|
struct pcf_value *values;
|
||||||
|
|
||||||
|
UT_hash_handle hh;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct pcf_file {
|
||||||
|
FILE *f;
|
||||||
|
int chantype;
|
||||||
|
int pcf_ntypes;
|
||||||
|
struct pcf_type *types;
|
||||||
|
};
|
||||||
|
|
||||||
|
void pcf_open(struct pcf_file *pcf, char *path, int chantype);
|
||||||
|
|
||||||
|
void pcf_write(struct pcf_file *pcf);
|
||||||
|
|
||||||
|
void pcf_close(struct pcf_file *pcf);
|
||||||
|
|
||||||
|
struct pcf_type *pcf_find_type(struct pcf_file *pcf, int type_id);
|
||||||
|
|
||||||
|
struct pcf_type *pcf_add_type(struct pcf_file *pcf, int type_id,
|
||||||
|
const char *label);
|
||||||
|
|
||||||
|
struct pcf_value *pcf_add_value(struct pcf_type *type, int value,
|
||||||
|
const char *label);
|
||||||
|
|
||||||
#endif /* OVNI_PCF_H */
|
#endif /* OVNI_PCF_H */
|
||||||
|
Loading…
Reference in New Issue
Block a user