📄 hist.c
字号:
/* Histogram handling stuff for states in Upshot Ed Karrels Argonne National Laboratory*/#if !defined(HAVE_STDLIB_H)#include <stdlib.h>#else#if HAVE_STDLIB_H#include <stdlib.h>#endif#endif#include <stdio.h>#include <string.h>#include "tcl.h"#include "log.h"#include "cvt_args.h"#include "str_dup.h"#include "tclptr.h"#include "states.h"#include "stats.h"#include "tcl_callargv.h"#include "hist.h"#ifdef NEEDS_STDLIB_PROTOTYPES#include "protofix.h"#endifstatic int HistCmd ANSI_ARGS(( ClientData data, Tcl_Interp *interp, int argc, char *argv[] )); /* Sort the state lengths, return pointer to hist info */static stateHist *State_HistInit ANSI_ARGS(( stateData *state, int def_no, int *procs, int nprocs )); /* fill the given array with the number of states in each bin */ /* return the number of states included in all the bins */static int State_HistBins ANSI_ARGS(( stateHist *hist, double shortLen, double longLen, int *bins, int nbins ));static int PointlistCmd ANSI_ARGS(( Tcl_Interp *interp, stateHist *hist, int argc, char *argv[] ));static int Pointlist ANSI_ARGS(( stateHist *hist, int *point_list ));static int Draw ANSI_ARGS(( Tcl_Interp *intepr, stateHist *hist, int argc, char *argv[] ));static int ScrollCmd ANSI_ARGS(( Tcl_Interp *interp, stateHist *hist, int argc, char *argv[] ));static int XviewCmd ANSI_ARGS(( Tcl_Interp *interp, stateHist *hist, int argc, char *argv[] ));static int BinsCmd ANSI_ARGS(( Tcl_Interp *interp, stateHist *hist, int argc, char *argv[] ));static int LinkVars ANSI_ARGS(( Tcl_Interp *interp, stateHist *hist ));static int UnlinkVars ANSI_ARGS(( Tcl_Interp *interp, stateHist *hist )); /* close this hist instance */static int State_HistClose ANSI_ARGS(( stateHist *hist ));static stateHist *HistToken2Ptr ANSI_ARGS(( Tcl_Interp *interp, char *token ));static int CompareLen ANSI_ARGS(( const void *va, const void *vb ));static int Bsearch ANSI_ARGS(( stateHist *hist, double x, int top, int bottom ));/*static int BsearchLE ANSI_ARGS(( stateHist *hist, double x, int top, int bottom ));*/static int BsearchGE ANSI_ARGS(( stateHist *hist, double x, int top, int bottom ));int Hist_Init( interp )Tcl_Interp *interp;{ Tcl_CreateCommand( interp, "hist", HistCmd, (ClientData) 0, (Tcl_CmdDeleteProc*) 0 ); return 0;}static int HistCmd( data, interp, argc, argv )ClientData data;Tcl_Interp *interp;int argc;char *argv[];{ char *logCmd=0, *array_name=0, *idx_prefix=0; int state_no; stateHist *hist; logFile *log; if (argc == 1) { Tcl_AppendResult( interp, "missing command for 'hist'", (char*)0 ); return TCL_ERROR; } if (!strcmp( argv[1], "open" )) { if (TCL_OK != ConvertArgs( interp, "hist open <log> <state_no> <array_name> <idx_prefix>", "2 sdss", argc, argv, &logCmd, &state_no, &array_name, &idx_prefix )) { return TCL_ERROR; } /* get pointer to log data */ log = LogCmd2Ptr( interp, logCmd ); if (!log) return TCL_ERROR; /* open the histogram data */ hist = State_HistInit( log->states, state_no, (int*)0, -1 ); hist->interp = interp; /* Tcl array and index prefix to link variables to */ hist->array_name = STRDUP( array_name ); hist->idx_prefix = STRDUP( idx_prefix ); /* link certain members of my hist structure to variables int the given Tcl array */ LinkVars( interp, hist ); /* return a pointer to my data structure */ sprintf( interp->result, "hist%d", AllocTclPtr( (void*)hist ) ); return TCL_OK; } else { if (!(hist = HistToken2Ptr( interp, argv[1] ))) return TCL_ERROR; if (!strcmp( argv[2], "bins" )) { return BinsCmd( interp, hist, argc, argv ); } else if (!strcmp( argv[2], "pointlist" )) { return PointlistCmd( interp, hist, argc, argv ); } else if (!strcmp( argv[2], "draw" )) { return Draw( interp, hist, argc, argv ); } else if (!strcmp( argv[2], "setscroll" )) { return ScrollCmd( interp, hist, argc, argv ); } else if (!strcmp( argv[2], "xview" )) { return XviewCmd( interp, hist, argc, argv ); } else if (!strcmp( argv[2], "close" )) { State_HistClose( hist ); return TCL_OK; } else { Tcl_AppendResult( interp, argv[2], " -- unrecognized histogram command. Either 'bins', or 'close'.", (char *)0 ); return TCL_ERROR; } }}static stateHist *State_HistInit( state, def_no, procs, nprocs )stateData *state;int def_no;int *procs;int nprocs;{ stateHist *hist = 0; stateInfo *state_info = 0; int *idx_ptr; int n, i, nstates_this_proc, proc_no, proc_no_idx, state_no; statData *stats; n = ListSize( state->list, stateInfo ); /* initially allocate space for all the states; worst-case scenario */ if ( !(hist = (stateHist*)malloc( sizeof( stateHist ) )) || !(hist->lens = (double*)malloc( sizeof(double) * n )) ) { fprintf( stderr, "Out of memory in State_HistInit\n" ); return 0; } if (!(stats = Stats_Create())) return 0; hist->state = state; hist->state_no = def_no; hist->sum = 0; hist->n = 0; hist->last_bins = 0; hist->window = hist->canvas = hist->xscrollcommand = 0; hist->time_lbl = hist->xscrollbar = 0; hist->color = hist->bitmap = hist->outlineColor = 0; hist->scan_time = hist->rclick_time = hist->lclick_time = hist->yclick = 0; hist->sum = hist->average = hist->std_dev = 0; hist->shortest = hist->longest = 0; hist->vis_sum = hist->vis_average = hist->vis_std_dev = 0; hist->vis_shortest = hist->vis_longest = 0; hist->shortLen = hist->longLen = -1; hist->firstIdx = hist->lastIdx = -1; if (nprocs != -1) { /* add states from only a few process */ /* for each process given, */ for (proc_no_idx=0; proc_no_idx<nprocs; proc_no_idx++) { /* get the process number */ proc_no = procs[proc_no_idx]; /* traverse the list of states on this process */ idx_ptr = ListHeadPtr( state->idx_proc_start[proc_no], int ); nstates_this_proc = ListSize( state->idx_proc_start[proc_no], int ); for (state_no=0; state_no < nstates_this_proc; state_no++) { /* finally, a pointer to the state we want */ state_info = ListHeadPtr( state->list, stateInfo ) + idx_ptr[state_no]; /* if the state matches the type we're looking for */ if (state_info->type == def_no) { /* add this length to the list */ Stats_Add( stats, hist->lens[hist->n++] = state_info->endTime - state_info->startTime ); } } } } else { /* add all states */ state_info = ListHeadPtr( state->list, stateInfo ); for (i=0; i<n; i++,state_info++) { /* if the state matches the type we're looking for */ if (state_info->type == def_no) { /* add this length to the list */ Stats_Add( stats, hist->lens[hist->n++] = state_info->endTime - state_info->startTime ); } } } hist->sum = Stats_Sum ( stats ); hist->average = Stats_Av ( stats ); hist->std_dev = Stats_StdDev( stats ); hist->shortest = Stats_Min( stats ); hist->longest = Stats_Max( stats ); Stats_Close( stats ); /* reallocate to fit only the number of slots used */ hist->lens = (double*) realloc( (void*)hist->lens, sizeof(double) * hist->n ); qsort( hist->lens, hist->n, sizeof(double), CompareLen ); /* used each time the data is split into bins */ hist->vis_stats = Stats_Create(); /* { int i; for (i=0; i<hist->n; i++) { fprintf( stderr, "%d. %f\n", i, hist->lens[i] ); } } */ return hist;}#define LINK_ELEMENT( str_name, name, type ) \ sprintf( tmp, "%s(%s,%s)", hist->array_name, hist->idx_prefix, str_name ); \ Tcl_LinkVar( interp, tmp, (char*)&hist->name, type );/* fprintf( stderr, "Linking hist->%s at address %p.\n", \ str_name, (char*)&hist->name );*/static int LinkVars( interp, hist )Tcl_Interp *interp;stateHist *hist;{ char *tmp; int i = TCL_LINK_INT; int f = TCL_LINK_DOUBLE; int s = TCL_LINK_STRING; /* tmp will get filled with something like "timeline(.win.0,stuff)", or ("%s(%s,%s)", array_name, idx_prefix, element_name ), to be exact. */ int max_element_len = 14; /* "xscrollcommand" */ tmp = malloc( strlen(hist->array_name) + 1 + strlen(hist->idx_prefix) + 1 + max_element_len + 1 + 1 ); LINK_ELEMENT( "window", window, s ); LINK_ELEMENT( "canvas", canvas, s ); LINK_ELEMENT( "time_lbl", time_lbl, s ); LINK_ELEMENT( "xscrollbar", xscrollbar, s ); LINK_ELEMENT( "xscrollcommand", xscrollcommand, s ); LINK_ELEMENT( "color", color, s ); LINK_ELEMENT( "bitmap", bitmap, s ); LINK_ELEMENT( "outlineColor", outlineColor, s ); LINK_ELEMENT( "bw", bw, i ); LINK_ELEMENT( "state_no", state_no, i ); LINK_ELEMENT( "nbins", nbins, i ); LINK_ELEMENT( "maxbin", maxbin, f ); LINK_ELEMENT( "start", start, f ); LINK_ELEMENT( "end", end, f ); LINK_ELEMENT( "left", left, f ); LINK_ELEMENT( "right", right, f ); LINK_ELEMENT( "width", width, i ); LINK_ELEMENT( "height", height, i ); LINK_ELEMENT( "scan_time", scan_time, f ); LINK_ELEMENT( "rclick_time", rclick_time, f ); LINK_ELEMENT( "lclick_time", lclick_time, f ); LINK_ELEMENT( "yclick", yclick, f ); LINK_ELEMENT( "n", n, i ); LINK_ELEMENT( "sum", sum, f ); LINK_ELEMENT( "average", average, f ); LINK_ELEMENT( "std_dev", std_dev, f ); LINK_ELEMENT( "shortest", shortest, f ); LINK_ELEMENT( "longest", longest, f ); LINK_ELEMENT( "vis_n", vis_n, i ); LINK_ELEMENT( "vis_sum", vis_sum, f ); LINK_ELEMENT( "vis_average", vis_average, f ); LINK_ELEMENT( "vis_std_dev", vis_std_dev, f ); LINK_ELEMENT( "vis_shortest", vis_shortest, f ); LINK_ELEMENT( "vis_longest", vis_longest, f ); free( tmp ); return 0;}#define UNLINK_ELEMENT( str_name ) \ sprintf( tmp, "%s(%s,%s)", hist->array_name, hist->idx_prefix, str_name ); \ Tcl_UnlinkVar( interp, tmp );static int UnlinkVars( interp, hist )Tcl_Interp *interp;stateHist *hist;{ char *tmp; /* tmp will get filled with something like "timeline(.win.0,stuff)", or ("%s(%s,%s)", hist->array_name, hist->idx_prefix, element_name ), to be exact. */ int max_element_len = 14; /* "xscrollcommand" */ tmp = malloc( strlen(hist->array_name) + 1 + strlen(hist->idx_prefix) + 1 + max_element_len + 1 + 1 ); UNLINK_ELEMENT( "window" ); UNLINK_ELEMENT( "canvas" ); UNLINK_ELEMENT( "time_lbl" ); UNLINK_ELEMENT( "xscrollbar" ); UNLINK_ELEMENT( "xscrollcommand" ); UNLINK_ELEMENT( "color" ); UNLINK_ELEMENT( "bitmap" ); UNLINK_ELEMENT( "outlineColor" ); UNLINK_ELEMENT( "bw" ); UNLINK_ELEMENT( "state_no" ); UNLINK_ELEMENT( "nbins" ); UNLINK_ELEMENT( "maxbin" ); UNLINK_ELEMENT( "start" ); UNLINK_ELEMENT( "end" ); UNLINK_ELEMENT( "left" ); UNLINK_ELEMENT( "right" ); UNLINK_ELEMENT( "width" ); UNLINK_ELEMENT( "height" ); UNLINK_ELEMENT( "scan_time" ); UNLINK_ELEMENT( "rclick_time" ); UNLINK_ELEMENT( "lclick_time" ); UNLINK_ELEMENT( "yclick" ); UNLINK_ELEMENT( "n" ); UNLINK_ELEMENT( "sum" ); UNLINK_ELEMENT( "average" ); UNLINK_ELEMENT( "std_dev" ); UNLINK_ELEMENT( "shortest" ); UNLINK_ELEMENT( "longest" ); UNLINK_ELEMENT( "vis_n" ); UNLINK_ELEMENT( "vis_sum" ); UNLINK_ELEMENT( "vis_average" ); UNLINK_ELEMENT( "vis_std_dev" ); UNLINK_ELEMENT( "vis_shortest" ); UNLINK_ELEMENT( "vis_longest" ); free( tmp ); return 0;}static int BinsCmd( interp, hist, argc, argv )Tcl_Interp *interp;stateHist *hist;int argc;char *argv[];{ char print_int[50], *tallest_bin_var; int nbins, *bins, i, tallest; double startTime, endTime; if (TCL_OK != ConvertArgs( interp, "hist <hist_token> bins <# of bins> <start_time> <end_time> <tallest_bin_var>", "3 dffs", argc, argv, &nbins, &startTime, &endTime, &tallest_bin_var )) { return TCL_ERROR; } /* create array for all the bin sizes */ bins = (int*)malloc( sizeof(int) * nbins ); /* split the data into the bins */ State_HistBins( hist, startTime, endTime, bins, nbins ); tallest = bins[0]; /* create a list of the the sizes of each bin */ for (i=0; i<nbins; i++) { sprintf( print_int, "%d ", bins[i] ); Tcl_AppendResult( interp, print_int, (char*)0 ); if (bins[i] > tallest) tallest = bins[i]; } /* free the array */ free( (char*)bins ); sprintf( print_int, "%d", tallest ); if (!Tcl_SetVar2( interp, tallest_bin_var, (char*)0, print_int, 0 )) { return TCL_ERROR; } return TCL_OK;}static int PointlistCmd( interp, hist, argc, argv )Tcl_Interp *interp;stateHist *hist;int argc;char *argv[];{ char tmp_str[200], *listVarName; int *point_array; int nbins, width, height, i; double startTime, endTime; Tcl_DString point_list; if (TCL_OK != ConvertArgs( interp, "hist <hist_token> pointlist <list_var> <# of bins> <start_time> <end_time> <width> <height>", "3 sdffdd", argc, argv, &listVarName, &nbins, &startTime, &endTime, &width, &height )) { return TCL_ERROR; } /* zero bins could mess stuff up */ if (!nbins) return TCL_OK; point_array = (int*)malloc( sizeof(int) * 4 * (nbins + 1) ); /* fill the array with point coordinates */ Pointlist( hist, point_array ); Tcl_DStringInit( &point_list ); for (i=0; i<nbins; i++) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -