From e6e976023d3e49092911562584ea11af31a3ab1b Mon Sep 17 00:00:00 2001 From: Rodrigo Arias Mallo Date: Tue, 3 Aug 2021 19:56:31 +0200 Subject: [PATCH] Implement the clock offset correction --- dump.c | 10 --- emu.c | 208 +++++++++++++++++++++++++++++++++++++++++++---------- emu.h | 13 ++-- emu_ovni.c | 4 +- ovni.c | 23 +----- 5 files changed, 183 insertions(+), 75 deletions(-) diff --git a/dump.c b/dump.c index 2fcc349..f8caf2a 100644 --- a/dump.c +++ b/dump.c @@ -12,16 +12,6 @@ #include "ovni_trace.h" #include "emu.h" -#define ENABLE_DEBUG - -#ifdef ENABLE_DEBUG -#define dbg(...) fprintf(stderr, __VA_ARGS__); -#else -#define dbg(...) -#endif - -#define err(...) fprintf(stderr, __VA_ARGS__); - static void hexdump(uint8_t *buf, size_t size) diff --git a/emu.c b/emu.c index 8d25efc..52606b6 100644 --- a/emu.c +++ b/emu.c @@ -8,12 +8,20 @@ #include #include #include +#include #include "ovni.h" #include "ovni_trace.h" #include "emu.h" #include "prv.h" +/* Obtains the corrected clock of the given event */ +int64_t +evclock(struct ovni_stream *stream, struct ovni_ev *ev) +{ + return (int64_t) ovni_ev_get_clock(ev) + stream->clock_offset; +} + static void emit_ev(struct ovni_stream *stream, struct ovni_ev *ev) { @@ -24,7 +32,7 @@ emit_ev(struct ovni_stream *stream, struct ovni_ev *ev) //dbg("sizeof(*ev) = %d\n", sizeof(*ev)); //hexdump((uint8_t *) ev, sizeof(*ev)); - clock = ovni_ev_get_clock(ev); + clock = evclock(stream, ev); delta = clock - stream->lastclock; @@ -126,7 +134,8 @@ next_event(struct ovni_emu *emu) struct ovni_ev *ev; struct ovni_stream *stream; struct ovni_trace *trace; - static int64_t t0 = -1; + + static int done_first = 0; trace = &emu->trace; @@ -144,10 +153,10 @@ next_event(struct ovni_emu *emu) continue; ev = stream->cur_ev; - if(f < 0 || ovni_ev_get_clock(ev) < minclock) + if(f < 0 || evclock(stream, ev) < minclock) { f = i; - minclock = ovni_ev_get_clock(ev); + minclock = evclock(stream, ev); } } @@ -159,18 +168,21 @@ next_event(struct ovni_emu *emu) set_current(emu, stream); - if(emu->lastclock > ovni_ev_get_clock(stream->cur_ev)) + if(emu->lastclock > evclock(stream, stream->cur_ev)) { fprintf(stdout, "warning: backwards jump in time %lu -> %lu\n", - emu->lastclock, ovni_ev_get_clock(stream->cur_ev)); + emu->lastclock, evclock(stream, stream->cur_ev)); } - emu->lastclock = ovni_ev_get_clock(stream->cur_ev); + emu->lastclock = evclock(stream, stream->cur_ev); - if(t0 < 0) - t0 = emu->lastclock; + if(!done_first) + { + done_first = 1; + emu->firstclock = emu->lastclock; + } - emu->delta_time = emu->lastclock - t0; + emu->delta_time = emu->lastclock - emu->firstclock; return 0; } @@ -376,44 +388,162 @@ close_prvs(struct ovni_emu *emu) fclose(emu->prv_cpu); } +static void +usage(int argc, char *argv[]) +{ + err("Usage: emu [-c offsetfile] tracedir\n"); + err("\n"); + err("Options:\n"); + err(" -c offsetfile Use the given offset file to correct\n"); + err(" the clocks among nodes. It can be\n"); + err(" generated by the ovnisync program\n"); + err("\n"); + err(" tracedir The output trace dir generated by ovni.\n"); + err("\n"); + err("The output PRV files are placed in the tracedir directory.\n"); + + exit(EXIT_FAILURE); +} + +static void +parse_args(struct ovni_emu *emu, int argc, char *argv[]) +{ + int opt; + + while((opt = getopt(argc, argv, "c:")) != -1) + { + switch(opt) + { + case 'c': + emu->clock_offset_file = optarg; + break; + default: /* '?' */ + usage(argc, argv); + } + } + + if(optind >= argc) + { + err("missing tracedir\n"); + usage(argc, argv); + } + + emu->tracedir = argv[optind]; +} + +static struct ovni_loom * +find_loom_by_hostname(struct ovni_emu *emu, char *host) +{ + int i; + struct ovni_loom *loom; + + for(i=0; itrace.nlooms; i++) + { + loom = &emu->trace.loom[i]; + + if(strcmp(loom->hostname, host) == 0) + return loom; + } + + return NULL; +} + +static void +load_clock_offsets(struct ovni_emu *emu) +{ + FILE *f; + char buf[1024]; + int i, rank; + double offset, std; + char host[HOST_NAME_MAX]; + struct ovni_loom *loom; + struct ovni_trace *trace; + struct ovni_stream *stream; + + f = fopen(emu->clock_offset_file, "r"); + + if(f == NULL) + { + perror("fopen clock offset file failed\n"); + abort(); + } + + /* Ignore header line */ + fgets(buf, 1024, f); + + while(fscanf(f, "%d %s %lf %lf", &rank, host, &offset, &std) == 4) + { + loom = find_loom_by_hostname(emu, host); + + if(loom == NULL) + { + err("No loom has hostname %s\n", host); + abort(); + } + + if(loom->clock_offset != 0) + { + err("warning: loom at host %s already has a clock offset\n", + host); + } + + loom->clock_offset = (int64_t) offset; + } + + /* Then populate the stream offsets */ + + trace = &emu->trace; + + for(i=0; instreams; i++) + { + stream = &trace->stream[i]; + loom = &trace->loom[stream->loom]; + stream->clock_offset = loom->clock_offset; + } + + fclose(f); +} + +static void +emu_init(struct ovni_emu *emu, int argc, char *argv[]) +{ + memset(emu, 0, sizeof(emu)); + + parse_args(emu, argc, argv); + + if(ovni_load_trace(&emu->trace, emu->tracedir)) + abort(); + + if(ovni_load_streams(&emu->trace)) + abort(); + + if(load_metadata(emu) != 0) + abort(); + + if(emu->clock_offset_file != NULL) + load_clock_offsets(emu); + + open_prvs(emu, emu->tracedir); +} + +static void +emu_destroy(struct ovni_emu *emu) +{ + close_prvs(emu); + destroy_metadata(emu); + ovni_free_streams(&emu->trace); +} int main(int argc, char *argv[]) { - char *tracedir; struct ovni_emu emu; - if(argc != 2) - { - fprintf(stderr, "missing tracedir\n"); - exit(EXIT_FAILURE); - } - - tracedir = argv[1]; - - memset(&emu, 0, sizeof(emu)); - - if(ovni_load_trace(&emu.trace, tracedir)) - abort(); - - if(ovni_load_streams(&emu.trace)) - abort(); - - if(load_metadata(&emu) != 0) - abort(); - - open_prvs(&emu, tracedir); - - printf("#Paraver (19/01/38 at 03:14):00000000000000000000_ns:0:1:1(%d:1)\n", emu.total_cpus); + emu_init(&emu, argc, argv); emulate(&emu); - close_prvs(&emu); - - destroy_metadata(&emu); - - ovni_free_streams(&emu.trace); - + emu_destroy(&emu); return 0; } diff --git a/emu.h b/emu.h index 38e8acf..02f3b43 100644 --- a/emu.h +++ b/emu.h @@ -8,8 +8,6 @@ /* Debug macros */ -#define ENABLE_DEBUG - #ifdef ENABLE_DEBUG # define dbg(...) fprintf(stderr, __VA_ARGS__); #else @@ -140,13 +138,15 @@ struct ovni_cpu { /* State of each loom on post-process */ struct ovni_loom { size_t nprocs; - char name[HOST_NAME_MAX]; + char hostname[HOST_NAME_MAX]; int max_ncpus; int max_phyid; int ncpus; struct ovni_cpu cpu[OVNI_MAX_CPU]; + int64_t clock_offset; + /* Virtual CPU */ struct ovni_cpu vcpu; @@ -173,6 +173,7 @@ struct ovni_stream { int active; struct ovni_ev *cur_ev; uint64_t lastclock; + int64_t clock_offset; }; struct ovni_emu { @@ -187,12 +188,16 @@ struct ovni_emu { struct nosv_task *cur_task; - uint64_t lastclock; + int64_t firstclock; + int64_t lastclock; int64_t delta_time; FILE *prv_thread; FILE *prv_cpu; + char *clock_offset_file; + char *tracedir; + /* Total counters */ int total_thread; int total_proc; diff --git a/emu_ovni.c b/emu_ovni.c index 17b82ed..3d7e776 100644 --- a/emu_ovni.c +++ b/emu_ovni.c @@ -252,7 +252,9 @@ hook_pre_ovni(struct ovni_emu *emu) { case 'H': ev_thread(emu); break; case 'A': ev_affinity(emu); break; - case 'B': dbg("burst %c\n", emu->cur_ev->header.value); break; + case 'B': + //dbg("burst %c\n", emu->cur_ev->header.value); + break; default: dbg("unknown ovni event class %c\n", emu->cur_ev->header.class); diff --git a/ovni.c b/ovni.c index 0501c72..4a15169 100644 --- a/ovni.c +++ b/ovni.c @@ -21,16 +21,6 @@ #include "ovni_trace.h" #include "parson.h" -#define ENABLE_DEBUG - -#ifdef ENABLE_DEBUG -#define dbg(...) fprintf(stderr, __VA_ARGS__); -#else -#define dbg(...) -#endif - -#define err(...) fprintf(stderr, __VA_ARGS__); - //#define ENABLE_SLOW_CHECKS //#define USE_RDTSC @@ -661,11 +651,7 @@ load_proc(struct ovni_eproc *proc, int index, int pid, char *procdir) while((dirent = readdir(dir)) != NULL) { if(find_dir_prefix_int(dirent, "thread", &tid) != 0) - { - err("warning: ignoring bogus directory entry %s\n", - dirent->d_name); continue; - } sprintf(path, "%s/%s", procdir, dirent->d_name); @@ -710,11 +696,7 @@ load_loom(struct ovni_loom *loom, int loomid, char *loomdir) while((dirent = readdir(dir)) != NULL) { if(find_dir_prefix_int(dirent, "proc", &pid) != 0) - { - err("warning: ignoring bogus directory entry %s\n", - dirent->d_name); continue; - } sprintf(path, "%s/%s", loomdir, dirent->d_name); @@ -777,7 +759,7 @@ ovni_load_trace(struct ovni_trace *trace, char *tracedir) loom = &trace->loom[i]; /* FIXME: Unsafe */ - strcpy(loom->name, loom_name); + strcpy(loom->hostname, loom_name); sprintf(path, "%s/%s", tracedir, dirent->d_name); @@ -861,7 +843,7 @@ ovni_load_streams(struct ovni_trace *trace) return -1; } - fprintf(stderr, "loaded %d streams\n", trace->nstreams); + err("loaded %d streams\n", trace->nstreams); for(s=0, i=0; inlooms; i++) { @@ -918,7 +900,6 @@ ovni_load_next_event(struct ovni_stream *stream) { stream->cur_ev = (struct ovni_ev *) stream->buf; stream->offset = 0; - dbg("first event\n"); goto out; }