Port ovnidump using the trace and player modules
The -t option is now dropped as only the binary streams found in the specified directory are dumped. A single binary stream can be also dumped in the same way. The relative path is prefixed, so we avoid the collision problem when filtering TIDs from multiple nodes.
This commit is contained in:
parent
1ac276a220
commit
09f58610ec
@ -56,8 +56,8 @@ add_library(emu STATIC
|
|||||||
add_executable(ovniemu ovniemu.c)
|
add_executable(ovniemu ovniemu.c)
|
||||||
target_link_libraries(ovniemu emu parson-static ovni-static)
|
target_link_libraries(ovniemu emu parson-static ovni-static)
|
||||||
|
|
||||||
#add_executable(ovnidump ovnidump.c)
|
add_executable(ovnidump ovnidump.c)
|
||||||
#target_link_libraries(ovnidump emu trace)
|
target_link_libraries(ovnidump emu parson-static ovni-static)
|
||||||
#
|
#
|
||||||
#add_executable(ovnisort ovnisort.c)
|
#add_executable(ovnisort ovnisort.c)
|
||||||
#target_link_libraries(ovnisort emu trace)
|
#target_link_libraries(ovnisort emu trace)
|
||||||
|
@ -1,124 +1,54 @@
|
|||||||
/* Copyright (c) 2021 Barcelona Supercomputing Center (BSC)
|
/* Copyright (c) 2021-2023 Barcelona Supercomputing Center (BSC)
|
||||||
* SPDX-License-Identifier: GPL-3.0-or-later */
|
* SPDX-License-Identifier: GPL-3.0-or-later */
|
||||||
|
|
||||||
#define _GNU_SOURCE
|
#define _GNU_SOURCE
|
||||||
|
|
||||||
#include <dirent.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <linux/limits.h>
|
|
||||||
#include <stdatomic.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "emu.h"
|
#include "player.h"
|
||||||
#include "ovni.h"
|
|
||||||
#include "trace.h"
|
#include "trace.h"
|
||||||
|
|
||||||
int filter_tid = -1;
|
|
||||||
char *tracedir;
|
char *tracedir;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
emit(struct ovni_stream *stream, struct ovni_ev *ev)
|
emit(struct player *player)
|
||||||
{
|
{
|
||||||
uint64_t clock = ovni_ev_get_clock(ev);
|
static int64_t c = 0;
|
||||||
|
|
||||||
printf("%s.%d.%d %ld %c%c%c",
|
struct emu_ev *ev = player_ev(player);
|
||||||
stream->loom->hostname,
|
struct stream *stream = player_stream(player);
|
||||||
stream->proc->pid,
|
|
||||||
stream->thread->tid,
|
|
||||||
clock,
|
|
||||||
ev->header.model,
|
|
||||||
ev->header.category,
|
|
||||||
ev->header.value);
|
|
||||||
|
|
||||||
int payloadsize = ovni_payload_size(ev);
|
/* Use raw clock in the ovni event */
|
||||||
if (payloadsize > 0) {
|
int64_t rel = ev->rclock - c;
|
||||||
|
c = ev->rclock;
|
||||||
|
|
||||||
|
printf("%s %10ld %+10ld %c%c%c",
|
||||||
|
stream->relpath,
|
||||||
|
c,
|
||||||
|
rel,
|
||||||
|
ev->m,
|
||||||
|
ev->c,
|
||||||
|
ev->v);
|
||||||
|
|
||||||
|
if (ev->has_payload) {
|
||||||
printf(" ");
|
printf(" ");
|
||||||
for (int i = 0; i < payloadsize; i++)
|
for (size_t i = 0; i < ev->payload_size; i++)
|
||||||
printf(":%02x", ev->payload.u8[i]);
|
printf(":%02x", ev->payload->u8[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
||||||
stream->lastclock = clock;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
dump_events(struct ovni_trace *trace)
|
|
||||||
{
|
|
||||||
/* Load events */
|
|
||||||
for (size_t i = 0; i < trace->nstreams; i++) {
|
|
||||||
struct ovni_stream *stream = &trace->stream[i];
|
|
||||||
|
|
||||||
/* It can be inactive if it has been disabled by the
|
|
||||||
* thread TID filter */
|
|
||||||
if (stream->active)
|
|
||||||
ovni_load_next_event(stream);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64_t lastclock = 0;
|
|
||||||
|
|
||||||
while (1) {
|
|
||||||
ssize_t f = -1;
|
|
||||||
uint64_t minclock = 0;
|
|
||||||
struct ovni_stream *stream = NULL;
|
|
||||||
|
|
||||||
/* Select next event based on the clock */
|
|
||||||
for (size_t i = 0; i < trace->nstreams; i++) {
|
|
||||||
stream = &trace->stream[i];
|
|
||||||
|
|
||||||
if (!stream->active)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
struct ovni_ev *ev = stream->cur_ev;
|
|
||||||
if (f < 0 || ovni_ev_get_clock(ev) < minclock) {
|
|
||||||
f = i;
|
|
||||||
minclock = ovni_ev_get_clock(ev);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// fprintf(stderr, "f=%d minclock=%u\n", f, minclock);
|
|
||||||
|
|
||||||
if (f < 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
stream = &trace->stream[f];
|
|
||||||
|
|
||||||
if (lastclock > ovni_ev_get_clock(stream->cur_ev)) {
|
|
||||||
fprintf(stdout, "warning: backwards jump in time %lu -> %lu\n",
|
|
||||||
lastclock, ovni_ev_get_clock(stream->cur_ev));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Emit current event */
|
|
||||||
emit(stream, stream->cur_ev);
|
|
||||||
|
|
||||||
lastclock = ovni_ev_get_clock(stream->cur_ev);
|
|
||||||
|
|
||||||
/* Read the next one */
|
|
||||||
ovni_load_next_event(stream);
|
|
||||||
|
|
||||||
/* Unset the index */
|
|
||||||
f = -1;
|
|
||||||
minclock = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
usage(void)
|
usage(void)
|
||||||
{
|
{
|
||||||
err("Usage: ovnidump [-t TID] tracedir\n");
|
rerr("Usage: ovnidump DIR\n");
|
||||||
err("\n");
|
rerr("\n");
|
||||||
err("Dumps the events of the trace to the standard output.\n");
|
rerr("Dumps the events of the trace to the standard output.\n");
|
||||||
err("\n");
|
rerr("\n");
|
||||||
err("Options:\n");
|
rerr(" DIR Directory containing ovni traces (%s) or single stream.\n",
|
||||||
err(" -t TID Only events from the given TID are shown\n");
|
OVNI_STREAM_EXT);
|
||||||
err("\n");
|
rerr("\n");
|
||||||
err(" tracedir The trace directory generated by ovni.\n");
|
|
||||||
err("\n");
|
|
||||||
|
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
@ -128,18 +58,16 @@ parse_args(int argc, char *argv[])
|
|||||||
{
|
{
|
||||||
int opt;
|
int opt;
|
||||||
|
|
||||||
while ((opt = getopt(argc, argv, "t:")) != -1) {
|
while ((opt = getopt(argc, argv, "h")) != -1) {
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
case 't':
|
case 'h':
|
||||||
filter_tid = atoi(optarg);
|
|
||||||
break;
|
|
||||||
default: /* '?' */
|
default: /* '?' */
|
||||||
usage();
|
usage();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (optind >= argc) {
|
if (optind >= argc) {
|
||||||
err("missing tracedir\n");
|
err("bad usage: missing directory\n");
|
||||||
usage();
|
usage();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -149,30 +77,47 @@ parse_args(int argc, char *argv[])
|
|||||||
int
|
int
|
||||||
main(int argc, char *argv[])
|
main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
progname_set("ovnidump");
|
||||||
|
|
||||||
parse_args(argc, argv);
|
parse_args(argc, argv);
|
||||||
|
|
||||||
struct ovni_trace *trace = calloc(1, sizeof(struct ovni_trace));
|
struct trace *trace = calloc(1, sizeof(struct trace));
|
||||||
|
|
||||||
if (ovni_load_trace(trace, tracedir))
|
if (trace == NULL) {
|
||||||
|
err("calloc failed:");
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
if (ovni_load_streams(trace))
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
if (filter_tid != -1) {
|
|
||||||
for (size_t i = 0; i < trace->nstreams; i++) {
|
|
||||||
struct ovni_stream *stream;
|
|
||||||
stream = &trace->stream[i];
|
|
||||||
if (stream->tid != filter_tid)
|
|
||||||
stream->active = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dump_events(trace);
|
if (trace_load(trace, tracedir) != 0) {
|
||||||
|
err("failed to load trace: %s", tracedir);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
ovni_free_streams(trace);
|
struct player *player = calloc(1, sizeof(struct player));
|
||||||
|
if (player == NULL) {
|
||||||
|
err("calloc failed:");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (player_init(player, trace) != 0) {
|
||||||
|
err("player_init failed");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
while ((ret = player_step(player)) == 0) {
|
||||||
|
emit(player);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Error happened */
|
||||||
|
if (ret < 0) {
|
||||||
|
err("player_step failed");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
free(trace);
|
free(trace);
|
||||||
|
free(player);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user