# To unbundle, sh this file echo README 1>&2 cat >README <<'End of README' To use the graphic display of sched trace files you need to: - Give the shell command, suntools . - Execute trace.sched . NOTE: The program is setup to only look for trace files whose filenames start with the string "trace" . Jack Dongarra, Jim Patterson, and Danny Sorensen End of README echo makefile 1>&2 cat >makefile <<'End of makefile' sched.trace: sched.trace.o cc -o sched.trace sched.trace.o -lsuntool -lsunwindow -lpixrect .c.o: $*.c cc -c -g $*.c End of makefile echo newt.h 1>&2 cat >newt.h <<'End of newt.h' #include #include #include #define PIX_SCR (0xC << 1) #define MAXDEPTH 10 #define MAXNODES 60 /* indices for the node array */ #define ID 0 #define NCH 1 #define NPNT 2 #define XNODE 4 #define YNODE 5 #define LVIX 6 #define RUNNING 7 /* event types */ #define STATICNODE 0 #define STARTSTATIC 1 #define STOPSTATIC 2 #define DYNAMICNODE 3 #define STARTDYN 4 #define STOPDYN 5 #define MAXLVLS 50 /* max # of levels */ #define MAXLVL 20 /* max # of nodes at each level */ #define C_RADIUS 10 /* size of nodes */ #define SYS -1 /* top nodes's parent */ /* move these to newt.h */ #define XSVAL pw->pw_prretained->pr_size.x #define YSVAL pw->pw_prretained->pr_size.y #define HOLLOW 0 #define SOLID 1 #define PLOP 0 #define XOR 1 #define WHITE 0 #define BLACK 1 /* globals */ int XOFFSET = 20; int YOFFSET = 50; int XS,YS; int fd; int NODRAW = 0; int HW; int SEEBUILD =0; int HINOD = 0; int HILVL = 0; int XSIZE = 40; int YSIZE = 20; /* */ int CURRENT_NODE; int DEPTH; int DYNZONE = 60; int DYNDOWN = 0; int ACTIVEPROCS =0; int MOSTPROCS = 0; /* arrays */ int NODE[MAXDEPTH][MAXNODES][8]; int DYNNODE[MAXNODES][11][2]; int LVLS[MAXDEPTH][MAXLVLS]; int PARENT[MAXNODES][10][2]; struct x_y_pt { int x; int y; } pts[1000]; /* used to creat histogram of parallelism */ int pt_count; /* count of pts to be plotted */ int linecount; /* count of events processed */ int total_events; /* total number of lines in file*/ int size_factor; /* allows one to expand or contract graph */ int time_factor; /* allows one to expand or contract graph */ int scale; /* contols update frequency of slider*/ int nodraw; /* do not draw, do everything else */ int start_draw_mark; /* start drawing when linecount gets here */ int dt_index; /* offset into cd table below */ /* to get name of directory */ char *directory_table[128]; /* table of filenames notice hard coded max */ int ft_index; /* offset into dir table below */ /* to get name of trace file*/ char *file_table[128]; /* table of filenames notice hard coded max */ int done, go, sunny, filepresent; int speed; int pending; FILE *fp; /* trace file */ End of newt.h echo sched.trace.c 1>&2 cat >sched.trace.c <<'End of sched.trace.c' #include #include #include #include #include #include #include #include #include #include "newt.h" /* Comments to: */ /* Jack Dongarra, Jim Patterson, and Danny Sorensen */ /* Argonne National Laboratory */ extern Notify_error notify_dispatch(); extern int errno; void load_notify_proc(), go_notify_proc(), full_notify_proc(), stop_notify_proc(), quit_notify_proc(), speed_notify_proc(), step_notify_proc(), timing_notify_proc(), subtree_notify_proc(), prdata_notify_proc(), redraw_notify_proc(), count_notify_proc(), directory_notify_proc(), handle_event(), plot_active(), file_notify_proc(); int x_pos = 0; int y_pos = 0; Frame frame; Panel panel; Canvas canvas; Textsw textsw; Tty ttysw; Panel_item title, filetext, msgtext, nodetext, go_button, stop_button, load_button, quit_button, file_choice, directory_choice, timing_button,subtree_button,full_button, step_button, prdata_button, redraw_button,histogram_button, speed_slider, cw_slider, hw_slider, count_slider; Pixwin *pw; main(argc,argv) int argc; char **argv; { int id,ETYPE,len,i; if (argc == 1) { filepresent = 0; printf("sun graphics\n"); window_init(); newt_init(); window_set(frame,WIN_SHOW,TRUE,0); go = 0; /* write text on canvas */ pw_text(pw,125,150,PIX_SCR,0,"Hello, to start load file and click GO or STEP."); /* initialize tree */ } else { printf("no graphics\n"); exit(1); } done = 0; sunloop(); } sunloop() { int rc; while (!done) { rc = 0; if (go && (rc != -1)) rc = proc_event(); notify_dispatch(); } } window_init() { int i; struct pixfont *title_font; frame = window_create(NULL,FRAME, WIN_ROWS, 45, WIN_COLUMNS, 85, 0); panel = window_create(frame,PANEL, WIN_PERCENT_HEIGHT, 30, 0); title_font = pf_open("/usr/lib/fonts/fixedwidthfonts/gallant.r.19"); title = panel_create_item(panel, PANEL_MESSAGE, PANEL_ITEM_X, ATTR_COL(31), PANEL_ITEM_Y, ATTR_ROW(0), PANEL_LABEL_STRING, "Schedule Tracing Facility", PANEL_LABEL_FONT, title_font, 0); directory_choice = panel_create_item(panel, PANEL_CHOICE, PANEL_ITEM_X, ATTR_COL(1), PANEL_ITEM_Y, ATTR_ROW(1), PANEL_LABEL_STRING, "Directory: ", PANEL_DISPLAY_LEVEL, PANEL_NONE, PANEL_NOTIFY_PROC, directory_notify_proc, 0); file_choice = panel_create_item(panel, PANEL_CHOICE, PANEL_ITEM_X, ATTR_COL(1), PANEL_ITEM_Y, ATTR_ROW(2), PANEL_LABEL_STRING, "Trace file: ", PANEL_DISPLAY_LEVEL, PANEL_CURRENT, PANEL_NOTIFY_PROC, file_notify_proc, 0); file_table[0] = NULL; directory_table[0] = NULL; load_directory_table(); /* filetext = panel_create_item(panel, PANEL_TEXT, PANEL_ITEM_X, ATTR_COL(1), PANEL_ITEM_Y, ATTR_ROW(1), PANEL_LABEL_STRING, "Name of trace file: ", PANEL_LABEL_DISPLAY_LENGTH, 20, 0); */ nodetext = panel_create_item(panel, PANEL_TEXT, PANEL_ITEM_X, ATTR_COL(42), PANEL_ITEM_Y, ATTR_ROW(9), PANEL_LABEL_STRING, "Current node ", PANEL_LABEL_DISPLAY_LENGTH, 20, 0); msgtext = panel_create_item(panel, PANEL_TEXT, PANEL_ITEM_X, ATTR_COL(60), PANEL_ITEM_Y, ATTR_ROW(1), PANEL_LABEL_STRING, "No active file", PANEL_LABEL_DISPLAY_LENGTH, 35, 0); count_slider = panel_create_item(panel, PANEL_SLIDER, PANEL_ITEM_X, ATTR_COL(5), PANEL_ITEM_Y, ATTR_ROW(3), PANEL_VALUE, 100, PANEL_MIN_VALUE, 0, PANEL_MAX_VALUE, 100, PANEL_SLIDER_WIDTH, 400, PANEL_SHOW_RANGE, TRUE, PANEL_SHOW_VALUE, TRUE, PANEL_LABEL_STRING, "Events ", PANEL_NOTIFY_PROC, count_notify_proc, 0); cw_slider = panel_create_item(panel, PANEL_SLIDER, PANEL_ITEM_X, ATTR_COL(5), PANEL_ITEM_Y, ATTR_ROW(4), PANEL_VALUE, 0, PANEL_MIN_VALUE, 0, PANEL_MAX_VALUE, 25, PANEL_SLIDER_WIDTH, 400, PANEL_SHOW_RANGE, FALSE, PANEL_SHOW_VALUE, TRUE, PANEL_LABEL_STRING, "Active Processes", 0); hw_slider = panel_create_item(panel, PANEL_SLIDER, PANEL_ITEM_X, ATTR_COL(5), PANEL_ITEM_Y, ATTR_ROW(5), PANEL_VALUE, 0, PANEL_MIN_VALUE, 0, PANEL_MAX_VALUE, 25, PANEL_SLIDER_WIDTH, 400, PANEL_SHOW_RANGE, FALSE, PANEL_SHOW_VALUE, TRUE, PANEL_LABEL_STRING, "High Water Mark ", 0); speed_slider = panel_create_item(panel, PANEL_SLIDER, PANEL_ITEM_X, ATTR_COL(5), PANEL_ITEM_Y, ATTR_ROW(6), PANEL_VALUE, 100, PANEL_MIN_VALUE, 0, PANEL_MAX_VALUE, 100, PANEL_SLIDER_WIDTH, 400, PANEL_SHOW_RANGE, TRUE, PANEL_SHOW_VALUE, TRUE, PANEL_LABEL_STRING, "Speed ", PANEL_NOTIFY_PROC, speed_notify_proc, 0); go_button = panel_create_item(panel, PANEL_BUTTON, PANEL_ITEM_X, ATTR_COL(5), PANEL_ITEM_Y, ATTR_ROW(7), PANEL_LABEL_IMAGE, panel_button_image(panel,"Go",0,NULL), PANEL_NOTIFY_PROC, go_notify_proc, 0); stop_button = panel_create_item(panel, PANEL_BUTTON, PANEL_ITEM_Y, ATTR_ROW(7), PANEL_ITEM_X, ATTR_COL(9), PANEL_LABEL_IMAGE, panel_button_image(panel,"Stop",0,NULL), PANEL_NOTIFY_PROC, stop_notify_proc, 0); load_button = panel_create_item(panel, PANEL_BUTTON, PANEL_ITEM_Y, ATTR_ROW(7), PANEL_ITEM_X, ATTR_COL(15), PANEL_LABEL_IMAGE, panel_button_image(panel,"Load",0,NULL), PANEL_NOTIFY_PROC, load_notify_proc, 0); quit_button = panel_create_item(panel, PANEL_BUTTON, PANEL_ITEM_Y, ATTR_ROW(7), PANEL_ITEM_X, ATTR_COL(21), PANEL_LABEL_IMAGE, panel_button_image(panel,"Quit",0,NULL), PANEL_NOTIFY_PROC, quit_notify_proc, 0); full_button = panel_create_item(panel, PANEL_BUTTON, PANEL_ITEM_Y, ATTR_ROW(7), PANEL_ITEM_X, ATTR_COL(27), PANEL_LABEL_IMAGE, panel_button_image(panel,"Full",0,NULL), PANEL_NOTIFY_PROC, full_notify_proc, 0); prdata_button = panel_create_item(panel, PANEL_BUTTON, PANEL_ITEM_Y, ATTR_ROW(7), PANEL_ITEM_X, ATTR_COL(33), PANEL_LABEL_IMAGE, panel_button_image(panel,"Prdata",0,NULL), PANEL_NOTIFY_PROC, prdata_notify_proc, 0); timing_button = panel_create_item(panel, PANEL_BUTTON, PANEL_ITEM_Y, ATTR_ROW(7), PANEL_ITEM_X, ATTR_COL(41), PANEL_LABEL_IMAGE, panel_button_image(panel,"Timing",0,NULL), PANEL_NOTIFY_PROC, timing_notify_proc, 0); subtree_button = panel_create_item(panel, PANEL_BUTTON, PANEL_ITEM_Y, ATTR_ROW(7), PANEL_ITEM_X, ATTR_COL(49), PANEL_LABEL_IMAGE, panel_button_image(panel,"Subtree",0,NULL), PANEL_NOTIFY_PROC, subtree_notify_proc, 0); step_button = panel_create_item(panel, PANEL_BUTTON, PANEL_ITEM_Y, ATTR_ROW(7), PANEL_ITEM_X, ATTR_COL(58), PANEL_LABEL_IMAGE, panel_button_image(panel,"Step",0,NULL), PANEL_NOTIFY_PROC, step_notify_proc, 0); redraw_button = panel_create_item(panel, PANEL_BUTTON, PANEL_ITEM_Y, ATTR_ROW(7), PANEL_ITEM_X, ATTR_COL(64), PANEL_LABEL_IMAGE, panel_button_image(panel,"Redraw",0,NULL), PANEL_NOTIFY_PROC, redraw_notify_proc, 0); histogram_button = panel_create_item(panel, PANEL_BUTTON, PANEL_ITEM_Y, ATTR_ROW(7), PANEL_ITEM_X, ATTR_COL(72), PANEL_LABEL_IMAGE, panel_button_image(panel,"Histogram",0,NULL), PANEL_NOTIFY_PROC, plot_active, 0); /* window_fit(panel); */ canvas = window_create(frame,CANVAS, CANVAS_WIDTH, 1000, CANVAS_HEIGHT, 1000, WIN_PERCENT_HEIGHT, 70, CANVAS_AUTO_SHRINK, FALSE, WIN_VERTICAL_SCROLLBAR, scrollbar_create(0), WIN_HORIZONTAL_SCROLLBAR, scrollbar_create(0), WIN_EVENT_PROC, handle_event, 0); pw = canvas_pixwin(canvas); /* ttysw = window_create(frame,TTY, WIN_PERCENT_HEIGHT, 10, 0); window_fit(frame); */ } void handle_event(canvas, event, arg) Canvas canvas; Event *event; caddr_t arg; { int x,y; char str[20]; x = event_x(event); y = event_y(event); switch (event_id(event)) { case MS_LEFT: printf("Left mouse x %d y %d \n",x,y); if ( (CURRENT_NODE = NODESEARCH(x,y)) != -1 ) { sprintf(str,"Current node is %d",CURRENT_NODE); display_node(str); }; break; case MS_MIDDLE: /* printf("Middle mouse x %d y %d \n",x,y); */ if ( (CURRENT_NODE = NODESEARCH(x,y)) != -1 ) { sprintf(str,"Current node is %d",CURRENT_NODE); display_node(str); }; break; case MS_RIGHT: /* printf("Right mouse x %d y %d \n",x,y); */ if ( (CURRENT_NODE = NODESEARCH(x,y)) != -1 ) { sprintf(str,"Current node is %d",CURRENT_NODE); display_node(str); }; break; default: break; } } load_file_table(s) char *s; { struct direct *d; DIR *dp; int i; i=0; while (file_table[i] != NULL) free(file_table[i++]); i = 0; if ((dp = opendir(s)) == NULL) { printf("Cannot open directory .\n"); exit(); } while ((d = readdir(dp)) != NULL && i < 127) { if (d->d_namlen > 4 && d->d_name[0] == 't' && d->d_name[1] == 'r' && d->d_name[2] == 'a' && d->d_name[3] == 'c' && d->d_name[4] == 'e') { file_table[i] = (char *) malloc(d->d_namlen+1); if (file_table[i] == NULL) { printf("No memory for directory\n"); exit(); } strcpy(file_table[i++],d->d_name); } } closedir(dp); if (i == 127) { printf("Too many file entries\n"); } file_table[i] = NULL; panel_set(file_choice,PANEL_CHOICE_STRINGS, "", 0, 0); panel_free(file_choice); file_choice = panel_create_item(panel, PANEL_CHOICE, PANEL_ITEM_X, ATTR_COL(1), PANEL_ITEM_Y, ATTR_ROW(2), PANEL_LABEL_STRING, "Trace file: ", PANEL_DISPLAY_LEVEL, PANEL_CURRENT, PANEL_NOTIFY_PROC, file_notify_proc, 0); for ( i=0; file_table[i] != NULL;i++) panel_set(file_choice,PANEL_CHOICE_STRING, i,file_table[i], 0); } load_directory_table() { struct direct *d; DIR *dp; int i; struct stat stbuf; static char current_dir[150]; i = 0; while (directory_table[i] != NULL) free(directory_table[i++]); i = 0; if ((dp = opendir(".")) == NULL) { printf("Cannot open directory .\n"); exit(); } while ((d = readdir(dp)) != NULL && i < 127) { if (stat(d->d_name,&stbuf) == -1) { printf("Stat failed on %s\n",d->d_name); exit(); } if ((stbuf.st_mode & S_IFMT) == S_IFDIR) { directory_table[i] = (char *) malloc(d->d_namlen+1); if (directory_table[i] == NULL) { printf("No memory for directory\n"); exit(); } strcpy(directory_table[i++],d->d_name); } } closedir(dp); if (i == 127) { printf("Too many directory entries\n"); } directory_table[i] = NULL; panel_set(directory_choice,PANEL_CHOICE_STRINGS, "", 0, 0); panel_free(directory_choice); strcpy(current_dir,"Directory: "); getwd(current_dir + 11); directory_choice = panel_create_item(panel, PANEL_CHOICE, PANEL_ITEM_X, ATTR_COL(1), PANEL_ITEM_Y, ATTR_ROW(1), PANEL_LABEL_STRING, current_dir, PANEL_DISPLAY_LEVEL, PANEL_NONE, PANEL_NOTIFY_PROC, directory_notify_proc, 0); for ( i=0; directory_table[i] != NULL;i++) panel_set(directory_choice,PANEL_CHOICE_STRING, i,directory_table[i], 0); load_file_table("."); } newt_init() { int i,j,k; /* initialize tree */ SEEBUILD = 0; ACTIVEPROCS = 0; CURRENT_NODE = 0; DEPTH = 0; HINOD = 0; HILVL = 0; HW = 0; for (i=0;i 2 ) size_factor = 1; proc_event(); } void timing_notify_proc(item,event) Panel_item item; Event *event; { time_factor+ = 50; if ( time_factor > 200 ) time_factor = 100; proc_event(); } void subtree_notify_proc(item,event) Panel_item item; Event *event; { if ( CURRENT_NODE != -1 ) { ++DEPTH; draw_subtree(); }; } void step_notify_proc(item,event) Panel_item item; Event *event; { go = 0; proc_event(); } void prdata_notify_proc(item,event) Panel_item item; Event *event; { prdata(); } void redraw_notify_proc(item,event) Panel_item item; Event *event; { redraw_all(); } void speed_notify_proc(item,value,event) Panel_item item; int value; Event *event; { speed = value; } void count_notify_proc(item,value,event) Panel_item item; int value; Event *event; { if (value < linecount) { display_message("can't go backwards yet"); } else { nodraw = 1; /* turn off drawing */ start_draw_mark = value; /* start again here */ } } void file_notify_proc(item,value,event) Panel_item item; int value; Event *event; { ft_index = value; } void directory_notify_proc(item,value,event) Panel_item item; int value; Event *event; { if (chdir(directory_table[value]) == -1) printf("chdir failed with error number %d\n", errno); else { load_directory_table(); } } void plot_active() { int i,hw,op; char index_str[3]; clearscreen(); op = PIX_SRC; sprintf(index_str,"%d",HW); pw_vector(pw,100,100 - HW*5,100,100,op,1); pw_vector(pw,100,100 - HW*5,95,100 - HW*5,op,1); pw_text(pw,15,90,PIX_SCR,0,"Processes"); pw_text(pw,185,140,PIX_SCR,0,"Events"); pw_text(pw,85,100 - HW*5,PIX_SCR,0,index_str); pw_vector(pw,100,100,100 + 3*linecount,100,op,1); for (i=0;i hw) { panel_set(hw_slider, PANEL_VALUE, cw,0); HW = cw; } } proc_event() { int i,ETYPE; for ( i = (100-speed) * 5000; i > 0; i--); /* wait */ if (nodraw && (linecount == start_draw_mark)) { nodraw = 0; go = 0; redraw_all(); display_message("select Go to continue"); panel_set(count_slider, PANEL_VALUE, linecount, 0); }; if (fscanf(fp,"%d",&ETYPE) == EOF) { display_message("end of tracefile"); fclose(fp); go = 0; return(0); } else { if ((++linecount % scale) == 0) panel_set(count_slider,PANEL_VALUE,linecount,0); /* printf("proc_event got value etype %d\n",ETYPE); */ if (ETYPE == STATICNODE) DOSTATIC(); else if (ETYPE == STARTSTATIC) DOSTARTSTATIC(); else if (ETYPE == STOPSTATIC) DOSTOPSTATIC(); else if (ETYPE == DYNAMICNODE) DODYNNODE(); else if (ETYPE == STARTDYN) DOSTARTDYN(); else if (ETYPE == STOPDYN) DOSTOPDYN(); else { printf("I don't know this type %d\n",ETYPE); return(0); }; }; return(ETYPE); } redraw_all() { REBUILD(); } draw_subtree() { int nix,current_lvl,yincr,lvl,a,yvalue,xincr; /* assign levels relative current node and number of parents */ nix = 0; current_lvl = NODE[0][CURRENT_NODE][LVIX] + 1; while ( nix < HINOD ) { if ( PATH(nix,CURRENT_NODE) == -1 ) { NODE[DEPTH][nix][NPNT] = -1; NODE[DEPTH][nix][LVIX] = -1; } else { NODE[DEPTH][nix][LVIX] = NODE[0][nix][LVIX]; NODE[DEPTH][nix][NPNT] = NODE[0][nix][NPNT]; }; nix++; }; NODE[DEPTH][CURRENT_NODE][LVIX] = current_lvl - 1; NODE[DEPTH][CURRENT_NODE][NPNT] = 0; /* prepare to assign x and y coordinates to subtree */ lvl = 0; while (lvl < HILVL) { LVLS[DEPTH][lvl] = 0; lvl++; }; nix = 0; while ( nix < HINOD ) { if ( NODE[DEPTH][nix][LVIX] != -1 ) LVLS[DEPTH][NODE[DEPTH][nix][LVIX]]++; nix++; }; ASSIGNXY(current_lvl); /* draw levels of subtree */ clearscreen(); lvl = 0; while (lvl <= current_lvl) { DRAWLEVEL(lvl); lvl++; }; } PATH(n,c) int n,c; /* to establish a path from n ( index in NODE array of node in question) to c (index in NODE array of current node) we need to trace ancestory of n */ { int a[MAXLVLS][MAXNODES]; int i,j,gen,k,sum; sum = 0; for (i=0;i 0 ) { for (i=0;i < gen;i++) for (j=0;j (xdisp * xdisp + ydsqr) - radsqr); if(fil == 2 && xdisp-1!=ydisp) reflect_fill(x,y,xdisp-1,ydisp,color,xormode); ydisp--; /* move down one pixel */ ydsqr = ydisp * ydisp; } while (xdisp <= ydisp); if ( fill == 1) { radius--; xdisp = 0; ydisp = radius; radsqr = radius * radius; /* speedup suggested by irv */ ydsqr = radsqr; /* scan until crossing 45 degree line (xdisp=ydisp) */ do { /* Scan right until off circle by pythagorean theorem */ do { reflect_fill(x,y,ydisp,xdisp,color,xormode); xdisp++; /* move right */ xdisp++; /* move right */ } while (radius > (xdisp * xdisp + ydsqr) - radsqr); if( xdisp-1!=ydisp) reflect_fill(x,y,xdisp-1,ydisp,color,xormode); ydisp--; /* move down one pixel */ ydisp--; /* move down one pixel */ ydsqr = ydisp * ydisp; } while (xdisp <= ydisp); } pw_text(pw,x+C_RADIUS+1,y+C_RADIUS+1,PIX_SCR,0,index_str); } /* * Routine CREFLECT takes advantage of the 8-fold symmetry in a circle. * It could also be used like the reflect function of Deluxe Paint, * since it will make 8 reflections of distance (xdisp,ydisp) from (x,y). * creflect(x1,y1,(x2-x1),(y2-y1)) will reflect (x2,y2) about (x1,y1). */ creflect(x, y, xdisp, ydisp,color,xormode) int x, y, xdisp, ydisp,color,xormode; { point(x+xdisp, y+ydisp, color, xormode); point(x+xdisp, y-ydisp, color, xormode); if(xdisp!=0) { point(x-xdisp, y+ydisp, color, xormode); point(x-xdisp, y-ydisp, color, xormode); } if(xdisp!=ydisp) { point(x+ydisp, y+xdisp, color, xormode); point(x-ydisp, y+xdisp, color, xormode); if(xdisp!=0) { point(x+ydisp, y-xdisp, color, xormode); point(x-ydisp, y-xdisp, color, xormode); } } } /* * REFLECT_FILL takes advantage of te same 8-fold symmetry that CREFLECT does, * except it draws horizontal and vertical stripes instead of only points. Notice that * the end points are the same as the pixels in CREFLECT. */ reflect_fill(x, y, xdisp, ydisp,color,xormode) int x, y, xdisp, ydisp,color,xormode; { horline(x-xdisp,y+ydisp,xdisp<<1,color,xormode); /* change for each graphics board */ if(ydisp) horline(x-xdisp,y-ydisp,xdisp<<1,color,xormode); } point(x,y,color,xormode) int x,y,color,xormode; { int op; if (xormode == XOR) pw_rop(pw,x,y,1,1, PIX_SRC ^ PIX_DST | PIX_COLOR(color), NULL,0,0); /* write a pixel */ else pw_put(pw,x,y,color); } horline(x,y,xdistance,color,xormode) int x,y,xdistance,color,xormode; { int op; op = PIX_SRC; if (xormode == XOR) op ^= PIX_DST; pw_vector(pw,x,y,x+xdistance,y,op,color); } clearscreen() { /* clear screen */ pw_writebackground(pw,0,0, XSVAL, YSVAL, PIX_CLR); } prdata() /* print data structures */ { /* */ dump_node_array(); dump_dynnode_array(); dump_parent_array(); dump_pts_array(); } dump_pts_array() { int i,j; printf("PTS array\n"); printf("i\tx\ty\n"); for ( i=0;i 0; k--); /* wait */ printf("i=%d\t",i); for (j=0;j<8;j++) printf("%d\t",NODE[DEPTH][i][j]); printf("\n"); }; } dump_dynnode_array() { int i,j,k; printf("DYNNODE ARRAY\n"); printf("[1]\t[2]\t[3]\t[4]\t[5]\t[6]\t[7]\t[8]\t[9]\t[10]\t"); printf("\n"); for ( i=0;i 0; k--); /* wait */ printf("i=%d\t",i); for (j=0;j<9;j++) printf("%d\t",DYNNODE[i][j][0]); printf("\n"); for (j=0;j<9;j++) printf("%d\t",DYNNODE[i][j][1]); printf("\n"); printf("\n"); }; } dump_parent_array() { int i,j,k; printf("PARENTS ARRAY\n"); printf("[1]\t[2]\t[3]\t[4]\t[5]\t[6]\t[7]\t[8]\t[9]\t[10]\t"); printf("\n"); for ( i=0;i 0; k--); /* wait */ printf("i=%d\n",i); for (j=0;j<9;j++) printf("%d\t",PARENT[i][j][0]); printf("\n"); for (j=0;j<9;j++) printf("%d\t",PARENT[i][j][1]); printf("\n"); printf("\n"); }; } display_node(text) char *text; { panel_set(nodetext, PANEL_LABEL_STRING, text, 0); } display_message(text) char *text; { panel_set(msgtext, PANEL_LABEL_STRING, text, 0); } open_tracefile(filename) char *filename; { int c; if ((fp = fopen(filename,"r")) == NULL) { display_message(strcat("couldn't open file ",filename)); } else { display_message("loading..."); filepresent = 1; /* * count lines in the file for event slider */ total_events = 0; while((c=getc(fp)) != EOF) if (c == '\n') total_events++; rewind(fp); /* reposition file */ panel_set(count_slider, PANEL_MAX_VALUE, total_events, PANEL_VALUE, 0, 0); scale = total_events/100; if ( scale == 0 ) scale = 1; display_message("select Go to begin"); newt_init(); } } FINDPNTS() { int nix,pix; /* printf("FINDPNTS \n"); */ nix = 0; while ( nix < HINOD ) { pix = 0; while ( pix < NODE[0][nix][NPNT] ) { PARENT[nix][pix][1] = SEARCH(PARENT[nix][pix][0]); pix++; }; nix++; }; } BLDLEVELS() { int parents,currlevel; int nix,pix,lvl; /* */ parents = 1; currlevel = 0; while ( parents ) { parents = 0; nix = 0; /* */ printf("Working on level %d \n",currlevel); while ( (nix = ATLEVEL(nix,currlevel)) != -1 ) { pix = 0; while ( pix < NODE[0][nix][NPNT]) { if (PARENT[nix][pix][1] != -1) { parents = 1; NODE[0][PARENT[nix][pix][1]][LVIX]= currlevel + 1; }; pix++; }; nix++; }; currlevel++; }; HILVL = currlevel; lvl = 0; while (lvl < HILVL) { LVLS[DEPTH][lvl] = 0; lvl++; }; nix = 0; while ( nix < HINOD ) { LVLS[DEPTH][NODE[0][nix][LVIX]]++; nix++; }; } ZEROLEVELS() { /* printf("ZEROLEVELS \n"); */ } ATLEVEL(nix,level) int nix,level; { /* printf("ATLEVEL \n"); */ while ( nix < HINOD ) { if (NODE[DEPTH][nix][LVIX] == level) return(nix); nix++; }; return(-1); } NODESEARCH(x,y) int x,y; { int r,nix; r = C_RADIUS*C_RADIUS; nix = -1; while (nix++ <= HINOD) if ( ((NODE[DEPTH][nix][XNODE] - x)*(NODE[DEPTH][nix][XNODE] - x) < r) && ((NODE[DEPTH][nix][YNODE] - y)*(NODE[DEPTH][nix][YNODE] - y) < r) ) return(nix); if (nix > HINOD) return(-1) ; } SEARCH(id) int id; { int nix; for (nix=0;(nix != HINOD) && (NODE[0][nix][ID] != id);nix++); if (nix == HINOD) return(-1) ; return(nix); } DYNSRCH(nix,did) int nix,did; { int i,j; j = DYNNODE[nix][0][0]; i = 1; while (i < j) { if ( DYNNODE[nix][i][0] == did ) return(i); i++; }; return (-1); } REBUILD() { int lv; /* printf("REBUILD \n"); */ DEPTH = 0; FINDPNTS(); BLDLEVELS(); ASSIGNXY(HILVL); lv = 0; clearscreen(); /* */ while (lv < HILVL) { DRAWLEVEL(lv); /* */ lv++; }; } ASSIGNXY(max_lvl) int max_lvl; { int i,yincr,lvl,nix,a,yvalue,xincr; /* printf("ASSIGNXY %d\n",max_lvl); */ for (i=0;i 0; i--); /* wait */ /* TEXT(x-5,y+3,1,4,NODE(ix,ID)) */ NODE[0][ix][RUNNING] = 2; drawcircle(x=NODE[DEPTH][ix][XNODE],y=NODE[DEPTH][ix][YNODE],C_RADIUS,1,0,NODE[0][ix][RUNNING],ix); ACTIVEPROCS-- ; DISPLAYACTIVE(); return(1); } DODYNNODE() { int nix,nid,did,dix; fscanf(fp,"%d %d",&nid,&did); if ( (nix = SEARCH(nid)) == -1) { printf("DODYNODE: cannot find node %d\n",nid); exit(1); }; if ( (dix = DYNNODE[nix][0][0]) == 11) { printf("DODYNNODE: no room for dyn node %d in %d \n",did,nid); exit(1); }; DYNNODE[nix][dix][0] = did; DYNNODE[nix][dix][1] = 0; DYNNODE[nix][0][0] = dix + 1; DRAW1DYN(nix,dix); } DOSTARTDYN() { int nid,did,dix,nix; fscanf(fp,"%d %d",&nid,&did); if ( (nix = SEARCH(nid)) == -1) { printf("DOSTARTDYN: cannot find node %d\n",nid); exit(1); }; if ( (dix = DYNSRCH(nix,did)) == -1) { printf("DOSTARTDYN: cannot find dyn node %d in %d \n",nid,did); exit(1); }; ACTIVEPROCS++; DISPLAYACTIVE(); DYNNODE[nix][dix][1] = 1; DRAW1DYN(nix,dix); } DOSTOPDYN() { int i,nid,did,dix,timing,nix; fscanf(fp,"%d %d %d",&nid,&did,&timing); if ( (nix = SEARCH(nid)) == -1) { printf("DOSTOPDYN: cannot find node %d\n",nid); exit(1); }; if ( (dix = DYNSRCH(nix,did)) == -1) { printf("DOSTOPDYN: cannot find dyn node %d in %d \n",nid,did); exit(1); }; for ( i = (time_factor-speed) * timing; i > 0; i--); /* wait */ ACTIVEPROCS--; DISPLAYACTIVE(); DYNNODE[nix][dix][1] = 2; DRAW1DYN(nix,dix); } End of sched.trace.c echo trace.DC 1>&2 cat >trace.DC <<'End of trace.DC' 0 23 0 1 15 0 22 0 1 14 0 21 0 1 13 0 20 0 1 12 0 19 0 1 11 0 18 0 1 10 0 17 0 1 9 0 16 0 1 8 0 15 1 1 7 0 14 1 1 7 0 13 1 1 6 0 12 1 1 6 0 11 1 1 5 0 10 1 1 5 0 9 1 1 4 0 8 1 1 4 0 7 2 1 3 0 6 2 1 3 0 5 2 1 2 0 4 2 1 2 0 3 2 1 1 0 2 2 1 1 0 1 2 0 1 23 1 20 1 22 1 21 1 19 1 18 2 20 1103 1 17 2 23 3774 2 22 6628 2 21 1147 1 12 1 16 1 15 2 19 2035 2 18 3688 1 14 1 13 2 17 1508 2 12 4862 1 11 1 10 2 16 1062 1 9 2 15 2678 1 8 2 13 1801 2 14 8367 1 6 1 7 2 11 5953 2 9 7904 3 6 523 3 7 524 3 6 525 4 6 523 2 10 1575 3 7 526 4 7 524 4 6 525 2 8 4084 1 5 5 6 523 2781 4 7 526 5 6 525 5474 5 7 524 8990 1 4 3 4 527 4 4 527 3 4 528 2 6 9952 4 4 528 2 5 6185 5 7 526 7886 1 7 2 7 4847 1 3 5 4 527 1308 5 4 528 2821 3 3 529 4 3 529 3 3 530 4 3 530 3 3 531 4 3 531 3 3 532 4 3 532 3 3 533 3 3 534 2 4 0 4 3 533 5 3 530 7866 4 3 534 5 3 529 5851 1 2 5 3 532 5288 5 3 533 8321 5 3 531 9367 3 2 535 4 2 535 3 2 536 4 2 536 3 2 537 4 2 537 3 2 538 3 2 539 3 2 540 4 2 538 5 3 534 2548 4 2 539 5 2 535 9159 4 2 540 5 2 537 6639 1 3 2 3 1542 5 2 536 2381 5 2 538 3428 5 2 539 2876 5 2 540 1928 1 2 2 2 2387 1 1 3 1 541 4 1 541 3 1 542 4 1 542 3 1 543 4 1 543 3 1 544 4 1 544 3 1 545 4 1 545 3 1 546 5 1 543 2983 4 1 546 5 1 541 8769 5 1 545 3498 5 1 542 9876 5 1 544 1223 5 1 546 8676 1 1 2 1 3648 End of trace.DC echo trace.PASCAL 1>&2 cat >trace.PASCAL <<'End of trace.PASCAL' 0 1 0 0 0 2 0 1 5 0 3 0 1 5 0 4 0 1 8 0 6 0 1 9 0 5 2 2 8 9 0 7 0 1 12 0 10 0 1 14 0 8 2 2 12 13 0 9 2 2 13 14 0 11 0 1 17 0 15 0 1 20 0 12 2 2 17 18 0 13 2 2 18 19 0 14 2 2 19 20 0 16 0 1 23 0 21 0 1 27 0 17 2 2 23 24 0 18 2 2 24 25 0 19 2 2 25 26 0 20 2 2 26 27 0 22 0 1 30 0 28 0 1 35 0 23 2 2 30 31 0 24 2 2 31 32 0 25 2 2 32 33 0 26 2 2 33 34 0 27 2 2 34 35 0 29 0 1 38 0 36 0 1 44 0 30 2 2 38 39 0 31 2 2 39 40 0 32 2 2 40 41 0 33 2 2 41 42 0 34 2 2 42 43 0 35 2 2 43 44 0 37 0 1 47 0 45 0 1 54 0 38 2 2 47 48 0 39 2 2 48 49 0 40 2 2 49 50 0 41 2 2 50 51 0 42 2 2 51 52 0 43 2 2 52 53 0 44 2 2 53 54 0 46 0 0 0 55 0 0 0 47 2 0 0 48 2 0 0 49 2 0 0 50 2 0 0 51 2 0 0 52 2 0 0 53 2 0 0 54 2 0 1 1 1 4 1 3 1 2 2 1 0 2 3 0 1 6 2 4 0 2 2 0 1 10 2 6 0 1 7 1 15 1 11 2 10 0 2 15 0 1 16 1 21 2 11 0 2 7 0 2 21 0 2 16 0 1 22 1 36 1 28 2 22 0 1 29 2 36 0 2 28 0 2 29 0 1 45 1 55 1 37 1 46 2 45 0 2 55 0 1 5 2 46 0 2 37 0 2 5 0 1 8 2 8 0 1 9 2 9 0 1 12 2 12 0 1 13 2 13 0 1 14 2 14 0 1 17 2 17 0 1 18 2 18 0 1 19 2 19 0 1 20 2 20 0 1 23 2 23 0 1 24 2 24 0 1 25 2 25 0 1 26 2 26 0 1 27 2 27 0 1 30 2 30 0 1 31 2 31 0 1 32 2 32 0 1 33 2 33 0 1 34 2 34 0 1 35 2 35 0 1 38 2 38 0 1 39 2 39 0 1 40 2 40 0 1 41 2 41 0 1 42 2 42 0 1 43 2 43 0 1 44 2 44 0 1 47 2 47 0 1 48 2 48 0 1 49 2 49 0 1 50 2 50 0 1 51 2 51 0 1 52 2 52 0 1 53 2 53 0 1 54 2 54 0 End of trace.PASCAL echo trace.SG 1>&2 cat >trace.SG <<'End of trace.SG' 0 1 6 0 0 4 0 5 1 5 6 2 3 0 5 1 2 1 7 0 6 1 2 1 7 0 7 2 1 1 0 2 1 1 1 0 3 1 1 1 1 4 3 4 500 4 4 500 3 4 501 4 4 501 3 4 502 4 4 502 3 4 503 4 4 503 3 4 504 4 4 504 3 4 505 4 4 505 3 4 506 4 4 506 3 4 507 4 4 507 5 4 500 0 5 4 504 0 5 4 505 0 5 4 502 0 5 4 501 0 5 4 506 0 5 4 507 0 5 4 503 0 1 4 2 4 0 1 5 1 6 1 3 1 2 3 3 508 4 3 508 3 3 509 3 3 510 3 2 511 4 3 510 3 2 513 4 3 509 3 3 512 4 2 511 3 2 514 3 3 515 3 2 516 3 3 517 3 2 518 3 3 519 3 2 520 3 3 521 3 2 522 4 2 513 3 2 523 4 3 512 2 6 0 4 2 514 5 3 512 0 4 3 515 5 3 510 0 4 2 516 5 3 509 0 4 3 517 5 3 508 0 4 2 518 5 2 511 0 5 2 513 0 4 3 519 4 2 520 5 2 514 0 4 3 521 5 3 517 0 4 2 522 5 3 515 0 4 2 523 5 3 521 0 2 5 0 1 7 5 3 519 0 1 3 3 3 524 4 3 524 3 3 525 4 3 525 5 3 525 0 5 3 524 0 1 3 2 3 0 5 2 518 0 5 2 516 0 5 2 520 0 5 2 523 0 5 2 522 0 1 2 3 2 526 4 2 526 3 2 527 4 2 527 5 2 526 0 5 2 527 0 1 2 2 2 0 2 7 0 1 1 2 1 0 End of trace.SG echo trace.SOLVE 1>&2 cat >trace.SOLVE <<'End of trace.SOLVE' 0 1 0 7 2 3 4 5 6 7 8 0 2 1 1 9 0 3 1 1 16 0 4 1 1 22 0 5 1 1 27 0 6 1 1 31 0 7 1 1 34 0 8 1 1 36 0 9 1 6 10 11 12 13 14 15 0 10 1 1 16 0 11 1 1 22 0 12 1 1 27 0 13 1 1 31 0 14 1 1 34 0 15 1 1 36 0 16 2 5 17 18 19 20 21 0 17 1 1 22 0 18 1 1 27 0 19 1 1 31 0 20 1 1 34 0 21 1 1 36 0 22 3 4 23 24 25 26 0 23 1 1 27 0 24 1 1 31 0 25 1 1 34 0 26 1 1 36 0 27 4 3 28 29 30 0 28 1 1 31 0 29 1 1 34 0 30 1 1 36 0 31 5 2 32 33 0 32 1 1 34 0 33 1 1 36 0 34 6 1 35 0 35 1 1 36 0 36 7 0 1 1 2 1 0 1 2 1 5 1 4 2 2 0 2 5 0 1 6 1 3 2 4 0 2 6 0 1 8 1 9 2 3 0 1 7 2 8 0 2 9 0 2 7 0 1 11 1 13 1 10 2 11 0 1 12 1 14 2 13 0 2 10 0 2 14 0 2 12 0 1 16 1 15 2 16 0 2 15 0 1 17 1 18 1 19 2 17 0 1 20 2 19 0 1 21 2 18 0 2 20 0 1 22 2 21 0 2 22 0 1 23 1 24 1 25 2 23 0 1 26 2 24 0 1 27 2 25 0 2 26 0 2 27 0 1 28 1 30 1 29 2 28 0 2 30 0 2 29 0 1 31 2 31 0 1 32 1 33 2 32 0 2 33 0 1 34 2 34 0 1 35 2 35 0 1 36 2 36 0 End of trace.SOLVE .