Read clock offsets in emu_system

This commit is contained in:
Rodrigo Arias 2023-01-20 15:43:10 +01:00 committed by Rodrigo Arias Mallo
parent 183df35459
commit e1880e09f6
2 changed files with 173 additions and 19 deletions

View File

@ -176,6 +176,21 @@ find_loom(struct emu_system *sys, const char *name)
return NULL; return NULL;
} }
static void
set_loom_hostname(char host[PATH_MAX], const char loom_name[PATH_MAX])
{
/* Copy until dot or end */
int i;
for (i = 0; i < PATH_MAX - 1; i++) {
if (loom_name[i] == '.' || loom_name[i] == '\0')
break;
host[i] = loom_name[i];
}
host[i] = '\0';
}
static struct emu_loom * static struct emu_loom *
new_loom(const char *tracedir, const char *name) new_loom(const char *tracedir, const char *name)
{ {
@ -193,6 +208,8 @@ new_loom(const char *tracedir, const char *name)
if (snprintf(loom->path, PATH_MAX, "%s/%s", tracedir, loom->relpath) >= PATH_MAX) if (snprintf(loom->path, PATH_MAX, "%s/%s", tracedir, loom->relpath) >= PATH_MAX)
die("new_loom: path too long: %s/%s\n", tracedir, loom->relpath); die("new_loom: path too long: %s/%s\n", tracedir, loom->relpath);
set_loom_hostname(loom->hostname, loom->name);
err("new loom '%s'\n", loom->name); err("new loom '%s'\n", loom->name);
return loom; return loom;
@ -212,7 +229,7 @@ create_loom(struct emu_system *sys, const char *tracedir, const char *relpath)
relpath); relpath);
return NULL; return NULL;
} }
struct emu_loom *loom = find_loom(sys, name); struct emu_loom *loom = find_loom(sys, name);
if (loom == NULL) { if (loom == NULL) {
@ -225,7 +242,7 @@ create_loom(struct emu_system *sys, const char *tracedir, const char *relpath)
} }
static int static int
create_system(struct emu_system *sys, struct emu_trace *trace) create_lpt(struct emu_system *sys, struct emu_trace *trace)
{ {
const char *dir = trace->tracedir; const char *dir = trace->tracedir;
for (struct emu_stream *s = trace->streams; s ; s = s->next) { for (struct emu_stream *s = trace->streams; s ; s = s->next) {
@ -237,20 +254,20 @@ create_system(struct emu_system *sys, struct emu_trace *trace)
struct emu_loom *loom = create_loom(sys, dir, s->relpath); struct emu_loom *loom = create_loom(sys, dir, s->relpath);
if (loom == NULL) { if (loom == NULL) {
err("create_system: create_loom failed\n"); err("create_lpt: create_loom failed\n");
return -1; return -1;
} }
struct emu_proc *proc = create_proc(loom, dir, s->relpath); struct emu_proc *proc = create_proc(loom, dir, s->relpath);
if (proc == NULL) { if (proc == NULL) {
err("create_system: create_proc failed\n"); err("create_lpt: create_proc failed\n");
return -1; return -1;
} }
/* The thread sets the stream */ /* The thread sets the stream */
struct emu_thread *thread = create_thread(proc, dir, s); struct emu_thread *thread = create_thread(proc, dir, s);
if (thread == NULL) { if (thread == NULL) {
err("create_system: create_thread failed\n"); err("create_lpt: create_thread failed\n");
return -1; return -1;
} }
} }
@ -292,7 +309,7 @@ cmp_loom(struct emu_loom *a, struct emu_loom *b)
} }
static void static void
sort_system(struct emu_system *sys) sort_lpt(struct emu_system *sys)
{ {
DL_SORT(sys->looms, cmp_loom); DL_SORT(sys->looms, cmp_loom);
@ -724,30 +741,148 @@ link_streams_to_threads(struct emu_system *sys)
emu_stream_data_set(th->stream, th); emu_stream_data_set(th->stream, th);
} }
int static int
emu_system_load(struct emu_system *sys, struct emu_trace *trace) load_clock_offsets(struct clkoff *clkoff, struct emu_args *args)
{ {
/* Parse the emu_trace and create the looms, procs and threads */ const char *tracedir = args->tracedir;
if (create_system(sys, trace) != 0) { char def_file[PATH_MAX];
err("emu_system_load: create system failed\n"); char def_name[] = "clock-offsets.txt";
clkoff_init(clkoff);
if (snprintf(def_file, PATH_MAX, "%s/%s",
tracedir, def_name) >= PATH_MAX) {
err("load_clock_offsets: path too long\n");
return -1;
}
const char *offset_file = args->clock_offset_file;
int is_optional = 0;
/* Use the default path if not given */
if (offset_file == NULL) {
offset_file = def_file;
is_optional = 1;
}
FILE *f = fopen(offset_file, "r");
if (f == NULL) {
if (is_optional) {
return 0;
}
err("load_clock_offsets: fopen %s failed: %s\n",
offset_file, strerror(errno));
return -1;
}
if (clkoff_load(clkoff, f) != 0) {
err("load_clock_offsets: clkoff_load failed\n");
}
err("loaded clock offset table from '%s' with %d entries\n",
offset_file, clkoff_count(clkoff));
fclose(f);
return 0;
}
static int
parse_clkoff_entry(struct emu_loom *looms, struct clkoff_entry *entry)
{
size_t matches = 0;
/* Use the median as the offset */
size_t offset = entry->median;
const char *host = entry->name;
struct emu_loom *loom;
DL_FOREACH(looms, loom) {
/* Match the hostname exactly */
if (strcmp(loom->hostname, host) != 0)
continue;
if (loom->clock_offset != 0) {
err("parse_clkoff_entry: loom %s already has a clock offset\n",
loom->name);
return -1;
}
loom->clock_offset = offset;
matches++;
}
if (matches == 0) {
err("parse_clkoff_entry: cannot find any loom with hostname '%s'\n",
host);
return -1;
}
return 0;
}
static int
init_offsets(struct emu_system *sys)
{
struct clkoff *table = &sys->clkoff;
int n = clkoff_count(table);
/* If we have more than one hostname and no offset table has been found,
* we won't be able to synchronize the clocks */
if (n == 0 && sys->nlooms > 1) {
err("warning: no clock offset file loaded with %ld looms\n",
sys->nlooms);
if (sys->args->linter_mode)
abort();
}
for (int i = 0; i < n; i++) {
struct clkoff_entry *entry = clkoff_get(table, i);
if (parse_clkoff_entry(sys->looms, entry) != 0) {
err("init_offsets: cannot parse clock offset entry %d\n", i);
return -1;
}
}
/* Set the stream clock offsets too */
struct emu_thread *thread;
DL_FOREACH2(sys->threads, thread, gnext) {
struct emu_loom *loom = thread->proc->loom;
emu_stream_clkoff(thread->stream, loom->clock_offset);
}
return 0;
}
int
emu_system_init(struct emu_system *sys, struct emu_args *args, struct emu_trace *trace)
{
memset(sys, 0, sizeof(struct emu_system));
sys->args = args;
/* Parse the trace and create the looms, procs and threads */
if (create_lpt(sys, trace) != 0) {
err("emu_system_init: create system failed\n");
return -1; return -1;
} }
/* Ensure they are sorted so they are easier to read */ /* Ensure they are sorted so they are easier to read */
sort_system(sys); sort_lpt(sys);
/* Init global lists build after sorting */ /* Init global lists after sorting */
init_global_lpt_lists(sys); init_global_lpt_lists(sys);
/* Now load all process metadata and set attributes */ /* Now load all process metadata and set attributes */
if (load_metadata(sys) != 0) { if (load_metadata(sys) != 0) {
err("emu_system_load: load_metadata() failed\n"); err("emu_system_init: load_metadata() failed\n");
return -1; return -1;
} }
/* From the metadata extract the CPUs too */ /* From the metadata extract the CPUs too */
if (init_cpus(sys) != 0) { if (init_cpus(sys) != 0) {
err("emu_system_load: load_cpus() failed\n"); err("emu_system_init: load_cpus() failed\n");
return -1; return -1;
} }
@ -756,13 +891,27 @@ emu_system_load(struct emu_system *sys, struct emu_trace *trace)
/* Now that we have loaded all resources, populate the indices */ /* Now that we have loaded all resources, populate the indices */
init_global_indices(sys); init_global_indices(sys);
/* Set CPU names like "CPU 1.34" */
if (init_cpu_names(sys) != 0) { if (init_cpu_names(sys) != 0) {
err("emu_system_load: init_cpu_names() failed\n"); err("emu_system_init: init_cpu_names() failed\n");
return -1; return -1;
} }
/* We need to retrieve the thread from the stream too */
link_streams_to_threads(sys); link_streams_to_threads(sys);
/* Load the clock offsets table */
if (load_clock_offsets(&sys->clkoff, args) != 0) {
err("emu_system_init: load_clock_offsets() failed\n");
return -1;
}
/* Set the offsets of the looms and streams */
if (init_offsets(sys) != 0) {
err("emu_system_init: init_offsets() failed\n");
return -1;
}
/* Finaly dump the system */ /* Finaly dump the system */
print_system(sys); print_system(sys);

View File

@ -4,9 +4,12 @@
#ifndef EMU_SYSTEM_H #ifndef EMU_SYSTEM_H
#define EMU_SYSTEM_H #define EMU_SYSTEM_H
#include "emu_args.h"
#include "emu_trace.h" #include "emu_trace.h"
#include "emu_stream.h"
#include "parson.h" #include "parson.h"
#include "ovni.h" #include "ovni.h"
#include "clkoff.h"
#include <stddef.h> #include <stddef.h>
#define MAX_CPU_NAME 32 #define MAX_CPU_NAME 32
@ -146,8 +149,7 @@ struct emu_loom {
char name[PATH_MAX]; /* Loom directory name */ char name[PATH_MAX]; /* Loom directory name */
char path[PATH_MAX]; char path[PATH_MAX];
char relpath[PATH_MAX]; /* Relative to tracedir */ char relpath[PATH_MAX]; /* Relative to tracedir */
char hostname[PATH_MAX];
char hostname[OVNI_MAX_HOSTNAME];
size_t max_ncpus; size_t max_ncpus;
size_t max_phyid; size_t max_phyid;
@ -189,10 +191,13 @@ struct emu_system {
struct emu_proc *cur_proc; struct emu_proc *cur_proc;
struct emu_thread *cur_thread; struct emu_thread *cur_thread;
struct clkoff clkoff;
struct emu_args *args;
struct model_ctx ctx; struct model_ctx ctx;
}; };
int emu_system_load(struct emu_system *system, struct emu_trace *trace); int emu_system_init(struct emu_system *sys, struct emu_args *args, struct emu_trace *trace);
int model_ctx_set(struct model_ctx *ctx, int model, void *data); int model_ctx_set(struct model_ctx *ctx, int model, void *data);
int model_ctx_get(struct model_ctx *ctx, int model, void *data); int model_ctx_get(struct model_ctx *ctx, int model, void *data);