Add ovnitop command

This commit is contained in:
Rodrigo Arias 2023-05-29 13:22:00 +02:00 committed by Rodrigo Arias Mallo
parent f8a15df1b9
commit 553d0a1c62
2 changed files with 161 additions and 1 deletions

View File

@ -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
View 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;
}