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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user