From 1da0f1a0967514f87ea8e5bdea52ef661ccbb8d3 Mon Sep 17 00:00:00 2001 From: Rodrigo Arias Mallo Date: Tue, 3 Aug 2021 20:47:02 +0200 Subject: [PATCH] Generate PCF and ROW files --- Makefile | 2 +- emu.c | 82 ++++++++++++++++++++++++ emu.h | 2 + pcf.c | 189 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ pcf.h | 9 +++ prv.h | 4 ++ 6 files changed, 287 insertions(+), 1 deletion(-) create mode 100644 pcf.c create mode 100644 pcf.h diff --git a/Makefile b/Makefile index 2e00da5..ffaccdd 100644 --- a/Makefile +++ b/Makefile @@ -21,7 +21,7 @@ dump: ovni.o dump.o parson.o test_speed: test_speed.c ovni.o parson.o -emu: emu.o emu_ovni.o emu_nosv.o ovni.o prv.o parson.o +emu: emu.o emu_ovni.o emu_nosv.o ovni.o prv.o pcf.o parson.o libovni.so: ovni.o parson.o $(LINK.c) -shared $^ -o $@ diff --git a/emu.c b/emu.c index 52606b6..3c23d70 100644 --- a/emu.c +++ b/emu.c @@ -14,6 +14,7 @@ #include "ovni_trace.h" #include "emu.h" #include "prv.h" +#include "pcf.h" /* Obtains the corrected clock of the given event */ int64_t @@ -381,6 +382,26 @@ open_prvs(struct ovni_emu *emu, char *tracedir) prv_header(emu->prv_cpu, emu->total_cpus + 1); } +static void +open_pcfs(struct ovni_emu *emu, char *tracedir) +{ + char path[PATH_MAX]; + + sprintf(path, "%s/%s", tracedir, "thread.pcf"); + + emu->pcf_thread = fopen(path, "w"); + + if(emu->pcf_thread == NULL) + abort(); + + sprintf(path, "%s/%s", tracedir, "cpu.pcf"); + + emu->pcf_cpu = fopen(path, "w"); + + if(emu->pcf_cpu == NULL) + abort(); +} + static void close_prvs(struct ovni_emu *emu) { @@ -388,6 +409,13 @@ close_prvs(struct ovni_emu *emu) fclose(emu->prv_cpu); } +static void +close_pcfs(struct ovni_emu *emu) +{ + fclose(emu->pcf_thread); + fclose(emu->pcf_cpu); +} + static void usage(int argc, char *argv[]) { @@ -504,6 +532,47 @@ load_clock_offsets(struct ovni_emu *emu) fclose(f); } +static void +write_row_cpu(struct ovni_emu *emu) +{ + FILE *f; + int i, j; + char path[PATH_MAX]; + struct ovni_loom *loom; + struct ovni_cpu *cpu; + + sprintf(path, "%s/%s", emu->tracedir, "cpu.row"); + + f = fopen(path, "w"); + + if(f == NULL) + { + perror("cannot open row file"); + exit(EXIT_FAILURE); + } + + fprintf(f, "LEVEL NODE SIZE 1\n"); + fprintf(f, "hostname\n"); + fprintf(f, "\n"); + + /* Add an extra row for the virtual CPU */ + fprintf(f, "LEVEL THREAD SIZE %d\n", emu->total_cpus + 1); + + for(i=0; itrace.nlooms; i++) + { + loom = &emu->trace.loom[i]; + for(j=0; jncpus; j++) + { + cpu = &loom->cpu[j]; + fprintf(f, "CPU %d.%d\n", i, cpu->i); + } + } + + fprintf(f, "UNSET\n"); + + fclose(f); +} + static void emu_init(struct ovni_emu *emu, int argc, char *argv[]) { @@ -524,6 +593,17 @@ emu_init(struct ovni_emu *emu, int argc, char *argv[]) load_clock_offsets(emu); open_prvs(emu, emu->tracedir); + open_pcfs(emu, emu->tracedir); +} + +static void +emu_post(struct ovni_emu *emu) +{ + /* Write the PCF files */ + pcf_write(emu->pcf_thread); + pcf_write(emu->pcf_cpu); + + write_row_cpu(emu); } static void @@ -543,6 +623,8 @@ main(int argc, char *argv[]) emulate(&emu); + emu_post(&emu); + emu_destroy(&emu); return 0; diff --git a/emu.h b/emu.h index 02f3b43..7cf49c3 100644 --- a/emu.h +++ b/emu.h @@ -194,6 +194,8 @@ struct ovni_emu { FILE *prv_thread; FILE *prv_cpu; + FILE *pcf_thread; + FILE *pcf_cpu; char *clock_offset_file; char *tracedir; diff --git a/pcf.c b/pcf.c new file mode 100644 index 0000000..02774a5 --- /dev/null +++ b/pcf.c @@ -0,0 +1,189 @@ +#include "pcf.h" +#include "prv.h" +#include "emu.h" + +#include +#include + +const char *pcf_def_header = + "DEFAULT_OPTIONS\n" + "\n" + "LEVEL THREAD\n" + "UNITS NANOSEC\n" + "LOOK_BACK 100\n" + "SPEED 1\n" + "FLAG_ICONS ENABLED\n" + "NUM_OF_STATE_COLORS 1000\n" + "YMAX_SCALE 37\n" + "\n" + "\n" + "DEFAULT_SEMANTIC\n" + "\n" + "THREAD_FUNC State As Is\n"; + +#define RGB(r, g, b) (r<<16 | g<<8 | b) +#define ARRAY_LEN(x) (sizeof(x) / sizeof((x)[0])) + +/* Define colors for the trace */ +#define DEEPBLUE RGB( 0, 0, 255) +#define LIGHTGREY RGB(217, 217, 217) +#define RED RGB(230, 25, 75) +#define GREEN RGB(60, 180, 75) +#define YELLOW RGB(255, 225, 25) +#define ORANGE RGB(245, 130, 48) +#define PURPLE RGB(145, 30, 180) +#define CYAN RGB( 70, 240, 240) +#define MAGENTA RGB(240, 50, 230) +#define LIME RGB(210, 245, 60) +#define PINK RGB(250, 190, 212) +#define TEAL RGB( 0, 128, 128) +#define LAVENDER RGB(220, 190, 255) +#define BROWN RGB(170, 110, 40) +#define BEIGE RGB(255, 250, 200) +#define MAROON RGB(128, 0, 0) +#define MINT RGB(170, 255, 195) +#define OLIVE RGB(128, 128, 0) +#define APRICOT RGB(255, 215, 180) +#define NAVY RGB( 0, 0, 128) +#define BLUE RGB( 0, 130, 200) +#define GREY RGB(128, 128, 128) +#define BLACK RGB( 0, 0, 0) + +const uint32_t pcf_def_palette[] = { + BLACK, /* (never shown anyways) */ + BLUE, /* runtime */ + LIGHTGREY, /* busy wait */ + RED, /* task */ + GREEN, + YELLOW, + ORANGE, + PURPLE, + CYAN, + MAGENTA, + LIME, + PINK, + TEAL, + GREY, + LAVENDER, + BROWN, + BEIGE, + MAROON, + MINT, + OLIVE, + APRICOT, + NAVY, + DEEPBLUE +}; + +const uint32_t *pcf_palette = pcf_def_palette; +const int pcf_palette_len = ARRAY_LEN(pcf_def_palette); + +struct event_value { + int value; + const char *label; +}; + +struct event_type { + int index; + int type; + const char *label; + struct event_value *values; +}; + +struct event_value thread_state_values[] = { + { TH_ST_UNKNOWN, "Unknown" }, + { TH_ST_RUNNING, "Running" }, + { TH_ST_PAUSED, "Paused" }, + { TH_ST_DEAD, "Dead" }, + { -1, NULL }, +}; + +struct event_type thread_state = { + 0, PTT_THREAD_STATE, "Thread: State", + thread_state_values +}; + +struct event_value thread_tid_values[] = { + { 0, "None" }, + { 1, "Multiple threads" }, + { -1, NULL }, +}; + +struct event_type thread_tid = { + 0, PTC_THREAD_TID, "CPU: Thread TID", + thread_tid_values +}; + +static void +decompose_rgb(uint32_t col, uint8_t *r, uint8_t *g, uint8_t *b) +{ + *r = (col>>16) & 0xff; + *g = (col>>8) & 0xff; + *b = (col>>0) & 0xff; +} + +static void +write_header(FILE *f) +{ + fprintf(f, "%s", pcf_def_header); +} + +static void +write_colors(FILE *f, const uint32_t *palette, int n) +{ + int i; + uint32_t col; + uint8_t r, g, b; + + fprintf(f, "\n\n"); + fprintf(f, "STATES_COLOR\n"); + + for(i=0; iindex, ev->type, ev->label); + + fprintf(f, "VALUES\n"); + + for(i=0; ev->values[i].label; i++) + { + fprintf(f, "%-4d %s\n", + ev->values[i].value, + ev->values[i].label); + } +} + +static void +write_events(FILE *f) +{ + write_event_type(f, &thread_state); + write_event_type(f, &thread_tid); +} + +int +pcf_write(FILE *f) +{ + write_header(f); + write_colors(f, pcf_palette, pcf_palette_len); + write_events(f); + + return 0; +} diff --git a/pcf.h b/pcf.h new file mode 100644 index 0000000..a66ffb5 --- /dev/null +++ b/pcf.h @@ -0,0 +1,9 @@ +#ifndef OVNI_PCF_H +#define OVNI_PCF_H + +#include + +int +pcf_write(FILE *f); + +#endif /* OVNI_PCF_H */ diff --git a/prv.h b/prv.h index 40d8b3a..16e622e 100644 --- a/prv.h +++ b/prv.h @@ -1,6 +1,10 @@ #ifndef OVNI_PRV_H #define OVNI_PRV_H +#include +#include "ovni.h" +#include "emu.h" + /* All PRV event types */ enum prv_type { /* Rows are CPUs */