Add ovnitop command
This commit is contained in:
parent
f8a15df1b9
commit
553d0a1c62
@ -66,6 +66,9 @@ target_link_libraries(ovnidump emu parson-static ovni-static)
|
|||||||
add_executable(ovnisort ovnisort.c)
|
add_executable(ovnisort ovnisort.c)
|
||||||
target_link_libraries(ovnisort emu parson-static ovni-static)
|
target_link_libraries(ovnisort emu parson-static ovni-static)
|
||||||
|
|
||||||
|
add_executable(ovnitop ovnitop.c)
|
||||||
|
target_link_libraries(ovnitop emu parson-static ovni-static)
|
||||||
|
|
||||||
set(USE_MPI ON CACHE BOOL "Use MPI (required by ovnisync)")
|
set(USE_MPI ON CACHE BOOL "Use MPI (required by ovnisync)")
|
||||||
if(USE_MPI)
|
if(USE_MPI)
|
||||||
# Use <PackageName>_ROOT variables if available, commonly used by MPI
|
# Use <PackageName>_ROOT variables if available, commonly used by MPI
|
||||||
@ -81,4 +84,4 @@ else()
|
|||||||
message(STATUS "Disabling ovnisync as MPI is disabled")
|
message(STATUS "Disabling ovnisync as MPI is disabled")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
install(TARGETS ovniemu ovnidump ovnisort RUNTIME DESTINATION bin)
|
install(TARGETS ovniemu ovnidump ovnisort ovnitop RUNTIME DESTINATION bin)
|
||||||
|
157
src/emu/ovnitop.c
Normal file
157
src/emu/ovnitop.c
Normal file
@ -0,0 +1,157 @@
|
|||||||
|
/* Copyright (c) 2023 Barcelona Supercomputing Center (BSC)
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later */
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include "common.h"
|
||||||
|
#include "emu_ev.h"
|
||||||
|
#include "emu_stat.h"
|
||||||
|
#include "ovni.h"
|
||||||
|
#include "player.h"
|
||||||
|
#include "trace.h"
|
||||||
|
#include "uthash.h"
|
||||||
|
|
||||||
|
struct entry {
|
||||||
|
char mcv[4];
|
||||||
|
long count;
|
||||||
|
UT_hash_handle hh;
|
||||||
|
};
|
||||||
|
|
||||||
|
char *tracedir;
|
||||||
|
struct entry *table = NULL;
|
||||||
|
|
||||||
|
static void
|
||||||
|
accum(struct player *player)
|
||||||
|
{
|
||||||
|
struct emu_ev *ev = player_ev(player);
|
||||||
|
struct entry *e = NULL;
|
||||||
|
HASH_FIND_STR(table, ev->mcv, e);
|
||||||
|
|
||||||
|
if (e == NULL) {
|
||||||
|
e = calloc(1, sizeof(struct entry));
|
||||||
|
if (e == NULL)
|
||||||
|
die("calloc failed:");
|
||||||
|
|
||||||
|
strcpy(e->mcv, ev->mcv);
|
||||||
|
e->count = 1;
|
||||||
|
HASH_ADD_STR(table, mcv, e);
|
||||||
|
} else {
|
||||||
|
e->count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
by_count(struct entry *a, struct entry *b)
|
||||||
|
{
|
||||||
|
if (a->count < b->count)
|
||||||
|
return +1;
|
||||||
|
if (a->count > b->count)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* Otherwise they have the same count, sort by mcv */
|
||||||
|
return strcmp(a->mcv, b->mcv);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
report(void)
|
||||||
|
{
|
||||||
|
HASH_SORT(table, by_count);
|
||||||
|
|
||||||
|
for (struct entry *e = table; e; e = e->hh.next)
|
||||||
|
printf("%s %10ld\n", e->mcv, e->count);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
usage(void)
|
||||||
|
{
|
||||||
|
rerr("Usage: ovnitop DIR\n");
|
||||||
|
rerr("\n");
|
||||||
|
rerr("Show most common events in a trace.\n");
|
||||||
|
rerr("\n");
|
||||||
|
rerr(" DIR Directory containing ovni traces (%s) or single stream.\n",
|
||||||
|
OVNI_STREAM_EXT);
|
||||||
|
rerr("\n");
|
||||||
|
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
parse_args(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
int opt;
|
||||||
|
|
||||||
|
while ((opt = getopt(argc, argv, "h")) != -1) {
|
||||||
|
switch (opt) {
|
||||||
|
case 'h':
|
||||||
|
default: /* '?' */
|
||||||
|
usage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (optind >= argc) {
|
||||||
|
err("bad usage: missing directory");
|
||||||
|
usage();
|
||||||
|
}
|
||||||
|
|
||||||
|
tracedir = argv[optind];
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
progname_set("ovnitop");
|
||||||
|
|
||||||
|
parse_args(argc, argv);
|
||||||
|
|
||||||
|
struct trace *trace = calloc(1, sizeof(struct trace));
|
||||||
|
|
||||||
|
if (trace == NULL) {
|
||||||
|
err("calloc failed:");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (trace_load(trace, tracedir) != 0) {
|
||||||
|
err("failed to load trace: %s", tracedir);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct player *player = calloc(1, sizeof(struct player));
|
||||||
|
if (player == NULL) {
|
||||||
|
err("calloc failed:");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (player_init(player, trace, 1) != 0) {
|
||||||
|
err("player_init failed");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
struct emu_stat stat;
|
||||||
|
|
||||||
|
emu_stat_init(&stat);
|
||||||
|
|
||||||
|
while ((ret = player_step(player)) == 0) {
|
||||||
|
accum(player);
|
||||||
|
emu_stat_update(&stat, player);
|
||||||
|
}
|
||||||
|
|
||||||
|
emu_stat_report(&stat, player, 1);
|
||||||
|
|
||||||
|
/* Report events */
|
||||||
|
report();
|
||||||
|
|
||||||
|
/* Error happened */
|
||||||
|
if (ret < 0) {
|
||||||
|
err("player_step failed");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(trace);
|
||||||
|
free(player);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user