📄 mtn.c
字号:
/* Mountain-range view for Upshot rf Lsttr;d Rf Ow554pe #e Iq443ow Ed Karrels Sthpmmr Msyopms; :snptsyptu Argonne National LaboratoryThis display show how many of the processes are in a given stateat a given time. For example, if there are three states, '.', 'X',and '*', it would look something like this: Processes 10| | | | .......... ... | ...................... ...... 5| ......**********.***................ | .....**********************...******.... | ..*********XXXXXXX*XXXXXXXX***XXXXXX**... | ..********XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX**.... 1| ..*****XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX... --------------------------------------------------- 1 sec 2 sec 3 sec 4 sec 5 secOnly in color or with a stipple pattern.*/#include <stdio.h>#if !defined(HAVE_STDLIB_H)#include <stdlib.h>#else#if HAVE_STDLIB_H#include <stdlib.h>#endif#endif#include "tcl.h"#include "log.h"#include "str_dup.h"#include "cvt_args.h"#include "heapsort.h"#include "tcl_callargv.h"#include "mtn.h" /* length to use for temporary Tcl commands */#define TMP_CMD_LEN 200/* The function that is called by the tcl routine "mtn_c_init". Widget creation command. mtn_c_init <cmd_name> <log> <canvas> <array name> <array index prefix> cmd_name - command to create log - command for the logfile this is attached to canvas - name of the canvas to draw the mountain ranges on array name - name of the array to link to array index prefix - prefix of the elements in the array to use set mtn($w,cmd) ${w}_c_cmd mtn_c_init $mtn($w,cmd) $log mtn $w */static int Init ANSI_ARGS(( ClientData, Tcl_Interp *, int argc, char **argv ));/* Close the mountain record.*/static int Close ANSI_ARGS(( mtnInfo* ));/* Used by min-heap routines to compare events and sort them.*/static int Mtn_EvtCompare ANSI_ARGS(( mtnEvt *evt_a, mtnEvt *evt_b ));/* Called on each state. data is mtnInfo*.*//*static int GrabState ANSI_ARGS(( void *data, int idx, int type, int proc, double startTime, double endTime, int parent, int firstChild, int overlapLevel ));*//* Called to draw the whole thing.*/static int Draw ANSI_ARGS(( mtnInfo* mtn ));/* Called to use 'xview' and 'yview' commands to simply slide the display into position when redrawing isn't necessary.*/static int Slide ANSI_ARGS(( mtnInfo* mtn ));/* Make sure the data in the minheap has been copied to a sorted array.*/static int InitRead ANSI_ARGS(( mtnInfo *mtn ));/* Used by Draw()*/static int NextTimeStep ANSI_ARGS(( mtnInfo *mtn, int *ht_diffs, int nstates, double interval, int *idx_ptr, double *time_ptr ));/* The widget command that is created for each invocation.*/static int Cmd ANSI_ARGS(( ClientData, Tcl_Interp *, int argc, char **argv ));/* Copy existing log data into the minheap.*/static int CopyLogData ANSI_ARGS(( mtnInfo *mtn ));/* Link my structure to Tcl array.*/static int LinkVars ANSI_ARGS(( mtnInfo *mtn ));/* Unlink my structure from Tcl array.*/static int UnlinkVars ANSI_ARGS(( mtnInfo *mtn ));/* Register the 'mtn_c_init' command.*/int Mtn_Init( interp )Tcl_Interp *interp;{ Tcl_CreateCommand( interp, "mtn_c_init", Init, (ClientData)0, (Tcl_CmdDeleteProc*)0 ); return TCL_OK;}static int Init( clientData, interp, argc, argv )ClientData clientData;Tcl_Interp *interp;int argc;char *argv[];{ char *array_name, *idx_prefix; char *cmd_name, *log_cmd; char *canvas_name; mtnInfo *mtn; if (TCL_OK != ConvertArgs( interp, "mtn_c_init <cmd_name> <log> <canvas> <array name> <array index prefix>", "1 sssss", argc, argv, &cmd_name, &log_cmd, &canvas_name, &array_name, &idx_prefix )) { return TCL_ERROR; } if (!(mtn = (mtnInfo*)malloc( sizeof(mtnInfo) ))) { Tcl_AppendResult( interp, "Out of memory create mountain range", (char*)0 ); return TCL_ERROR; } /* convert log%d string to logfile token */ mtn->interp = interp; if (!(mtn->log = LogCmd2Ptr( interp, log_cmd ))) { return TCL_ERROR; } mtn->canvasName = STRDUP( canvas_name ); /* clear any string members */ mtn->bg = 0; mtn->outline = 0; mtn->bw = 0; /* Tcl side will set bg, outline, and bw */ /* get name of the Tcl array and array prefix I should link with */ mtn->array_name = STRDUP( array_name ); mtn->idx_prefix = STRDUP( idx_prefix ); /* link members of my structure to a Tcl array *//* fprintf( stderr, "&mtn->startTime = %p, &mtn->endTime = %p\n", (void*)&mtn->startTime, &mtn->endTime );*/ mtn->startTime = Log_StartTime( mtn->log ); mtn->endTime = Log_EndTime( mtn->log ); mtn->totalTime = mtn->endTime - mtn->startTime; mtn->np = Log_Np( mtn->log ); /* mark with invalid initial values */ mtn->width = mtn->height = -1; mtn->visWidth = mtn->visHeight = mtn->lastVisWidth = mtn->lastVisHeight = -1; mtn->xleft = mtn->xspan = mtn->lastXspan = -1; mtn->ytop = mtn->yspan = mtn->lastYspan = -1; LinkVars( mtn ); /* minheap used to gather all the states, when needed, they are pulled out into the array mtn->evtList */ HeapCreate( mtn->evtHeap, mtnEvt, 100, Mtn_EvtCompare ); mtn->evtList = 0; /* get all the data present in the logfile data structures, putting it in mtn->evtHeap, it will be copied into mtn->evtList and mtn->nevents when needed. (actually, this function should put it straight into mtn->evtList, using a private heap if necessary) */ CopyLogData( mtn ); /* create a command by which the functions int mtn.tcl can call me directly (more convenient to put mtnInfo* in ClientData than in some TclPtr) */ Tcl_CreateCommand( interp, cmd_name, Cmd, (ClientData)mtn, (Tcl_CmdDeleteProc*)0 ); return TCL_OK;}static int Cmd( clientData, interp, argc, argv )ClientData clientData;Tcl_Interp *interp;int argc;char *argv[];{ mtnInfo *mtn; mtn = (mtnInfo*)clientData; if (argc==1) { argv[1] = "(none)"; goto cmdErr; } if (!strcmp( argv[1], "draw" )) { return Draw( mtn ); } if (!strcmp( argv[1], "close" )) { return Close( mtn ); } cmdErr: Tcl_AppendResult( interp, "Unrecognized command for ", argv[0], ": ", argv[1], ". Must be one of isloaded or draw.", (char*)0 ); return TCL_ERROR;}/* Compare two event times, used to keep heap sorted.*/static int Mtn_EvtCompare( evt_a, evt_b )mtnEvt *evt_a, *evt_b;{ if (evt_a->time < evt_b->time) { return -1; } else if (evt_a->time == evt_b->time) { return 0; } else { return 1; }}/* Not used anymore *//* Callback for gathering state info.*/#if 0static int GrabState( data, idx, type, proc, startTime, endTime, parent, firstChild, overlapLevel )void *data;int idx, type, proc, parent, firstChild, overlapLevel;double startTime, endTime;{ mtnInfo *mtn; mtnEvt evt; mtn = (mtnInfo*)data; /* if this is the last state, draw the stuff */ if (idx == -1) return Draw( mtn ); /* add the start and end times of this state to the minheap */ evt.time = startTime; evt.isStartEvt = 1; evt.stateNo = type; HeapAdd( mtn->evtHeap, mtnEvt, evt ); evt.time = endTime; evt.isStartEvt = 0; HeapAdd( mtn->evtHeap, mtnEvt, evt ); return TCL_OK;}#endif/* Add any states already gathered to the minheap.*/static int CopyLogData( mtn )mtnInfo *mtn;{ int i, n; int proc, parent, firstChild, overlapLevel; mtnEvt start, end; start.isStartEvt = 1; end.isStartEvt = 0; n = Log_Nstates( mtn->log ); for (i=0; i<n; i++) { Log_GetState( mtn->log, i, &start.stateNo, &proc, &start.time, &end.time, &parent, &firstChild, &overlapLevel ); end.stateNo = start.stateNo; HeapAdd( mtn->evtHeap, mtnEvt, start ); HeapAdd( mtn->evtHeap, mtnEvt, end ); } return 0;}/* Convert time to x coordinate*/static double Time2X( mtn, time )mtnInfo *mtn;double time;{ return (time - mtn->startTime) * mtn->width / mtn->totalTime;}/* Convert height factor to y coordinate*/static double Ht2Y( mtn, ht )mtnInfo *mtn;int ht;{ return mtn->height - (ht * mtn->height / Log_Np( mtn->log ));}/* Draw the mountain range*/static int Draw( mtn )mtnInfo *mtn;{ xpandList *coordLists; /* one list of coords for each state type */ int nstates, i; int *ht; /* current height of each state; number */ /* of processes in this state */ int *ht_diffs; /* change in height of each state at this */ /* timestep */ typedef char dblstr[25]; dblstr *coordStr; /* array of doubles converted to strings */ char **argv; /* for calling the canvas command manually */ int max_n_coords; /* most number of coordinates any state has */ char tags[25]; /* tags string (color_%d) */ Tcl_CmdInfo cmd_info; /* command info (for calling manually) */ double time; /* time of current timestep */ double interval; /* interval between timesteps */ int evt_idx; /* index of the next event to read */ char *cmd; /* temporary string for building Tcl command */ if (mtn->visWidth == -1 || mtn->visHeight == -1 || mtn->xspan == -1 || mtn->yspan == -1) { /* Cannot draw--no dimensions yet */ return TCL_OK; } /* If the display hasn't been stretched or shrunk or anything, just slide it a bit. */ if (mtn->visWidth == mtn->lastVisWidth && mtn->visHeight == mtn->lastVisHeight && mtn->xspan == mtn->lastXspan && mtn->yspan == mtn->lastYspan) { return Slide( mtn ); } mtn->lastVisWidth = mtn->visWidth; mtn->lastVisHeight = mtn->visHeight; mtn->lastXspan = mtn->xspan; mtn->lastYspan = mtn->yspan; mtn->width = mtn->visWidth * mtn->totalTime / mtn->xspan;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -