/************************************************/ /* UtilHist.c - Simple utility for extracting */ /* the processor element (PE) utilitizations */ /* results from the summaries.dat file to make */ /* a bar-chart histogram plot-file. */ /* */ /* Assumes you are in the directory where you */ /* ran a simulation. To use, run this utilhist */ /* utility. It reads your "netinfo" file to */ /* find the name-ID-numbers of your PE's, and */ /* then it reads your summaries.dat file to */ /* produce a plot-file called, "utils.dat". */ /* Then run XGRAPH on utils.dat. */ /* Example: */ /* utilhist */ /* xgraph utils.dat */ /* */ /* To compile this program: */ /* gcc utilhist.c -o utilhist */ /************************************************/ #include #include FILE *infile, *outfile; /**********************************************/ /* Data structure to hold PE name-ID's. */ /**********************************************/ struct wordpair { char *name, *value; struct wordpair *nxt; } *nameIDs=0; /**********************************************/ /* Routine to get a new line from input file. */ /**********************************************/ void read_line( char *line ) { int i=0; do line[i++] = getc(infile); while ((!feof(infile)) && (line[i-1]!=10)); line[i-1] = '\0'; } /**************************************************/ /* Routine to add a name-value pair to word-list. */ /**************************************************/ void add_word( char *name, char *value ) { struct wordpair *tmppt; tmppt = (struct wordpair *)malloc(sizeof(struct wordpair)); tmppt->name = strdup(name); tmppt->value = strdup(value); tmppt->nxt = nameIDs; nameIDs = tmppt; } /**************************************************/ /* Routine to find a named value. */ /**************************************************/ char *find_entry( char *name ) { struct wordpair *tmppt; tmppt = nameIDs; while ((tmppt!=0) && (strcmp(tmppt->name,name)!=0)) tmppt = tmppt->nxt; if (tmppt==0) return 0; else return tmppt->value; } /*....................................................................... . NEXT_WORD - accepts a line of text, and returns with the . . next word in that text in the second parameter, the original line . . is shortened from the beginning so that the word is removed. . . If the line encountered is empty, then the word returned will be . . empty. NEXTWORD parses on arbitrary delimiters. . .......................................................................*/ void Next_Word( char *line, char *word, char *delim ) { int i=0, j=0, k=0, m=0, flag=1; /* Eat away preceding garbage */ while ((line[i]!='\0') && (flag)) { j = 0; while ((delim[j]!='\0') && (line[i]!=delim[j])) j = j + 1; if (line[i]==delim[j]) { k = k + 1; i = i + 1; } else flag = 0; } /* Copy the word until the next delimiter. */ while ((line[i]!='\0') && (!flag)) { word[m] = line[i]; m = m + 1; i = i + 1; if (line[i]!='\0') { j = 0; while ((delim[j]!='\0') && (line[i]!=delim[j])) j = j + 1; if (line[i]==delim[j]) flag = 1; } } /* Shorten line. */ j = 0; while (line[i]!='\0') { line[j] = line[i]; j = j + 1; i = i + 1; } /* Terminate the char-strings. */ line[j] = '\0'; word[m] = '\0'; } /********************************************************/ /* Main - Open files, scan them, and produce output. */ /********************************************************/ main() { char line[1000], word[500], name[500], *ID; int flag=0, NPEs=0; /* First get the processor name - ID numbers. */ infile = fopen("netinfo","r"); if (infile == 0) {printf("ERROR: Cannot open netinfo.\n"); exit(0);} /* Scan the netinfo file for name-ID numbers. */ read_line( line ); while ((!feof(infile)) && (flag<2)) { Next_Word( line, word, " "); if (strcmp(word,"Sim>")==0) flag++; else if (strlen(word)>0) { Next_Word( line, name, " "); add_word( name, word ); NPEs++; } read_line( line ); } fclose(infile); /* Now scan summaries.dat for processor utilizations. */ infile = fopen("summaries.dat","r"); if (infile == 0) {printf("ERROR: Cannot open summaries.dat.\n"); exit(0);} /* Open output file and write graph titles, etc.. */ outfile = fopen("utils.dat","w"); if (infile == 0) {printf("ERROR: Cannot open utils.dat for writing.\n"); exit(0);} /* Bar graph. Set bar thickness. */ fprintf(outfile,"thickness=%f\n", 25.0 / (1.0 + 0.1 * (float)NPEs) ); fprintf(outfile,"title = Processor Utilizations\n"); fprintf(outfile,"title_x = Processor Element\n"); fprintf(outfile,"title_y = Utilization (%c)\n", 37); /*******************************************************/ /* Expect summaries.dat to have the following format: */ /* /pe2: Utilization = 0.06 % */ /* /pe4: Utilization = 0.06 % */ /* Or, an older alternate format: */ /* ----- Summary from PE 1 --------- */ /* PE Utilization = 60.0 % */ /*******************************************************/ read_line( line ); while (!feof(infile)) { if ((strstr(line,"Utilization =")!=0) && (strstr(line,"Avg. Processor Utilization")==0)) { Next_Word( line, name, " :"); Next_Word( line, word, " :="); Next_Word( line, word, " :="); /* Find the entry. */ ID = find_entry( name ); if (ID==0) printf("ERROR: Could not find device '%s'\n", name); else { fprintf(outfile,"%s 0\n", ID); fprintf(outfile,"%s %s\n", ID, word); fprintf(outfile,"next\n"); } } else if (strstr(line,"-------------- Summary from PE")!=0) { Next_Word( line, name, " -"); /* Summary */ Next_Word( line, name, " "); /* from */ Next_Word( line, name, " "); /* PE */ Next_Word( line, name, " -"); read_line( line ); Next_Word( line, word, " "); /* PE */ Next_Word( line, word, " ="); /* Utilization */ Next_Word( line, word, " ="); fprintf(outfile,"%s 0\n", name); fprintf(outfile,"%s %s\n", name, word); fprintf(outfile,"next\n"); } read_line( line ); } fclose(infile); fclose(outfile); printf("\nTo plot PE-Utilizations:\n xgraph utils.dat\n\n"); }