52 #include <my_global.h>
54 #include <my_pthread.h>
63 #define PRO_FILE "dbugmon.out"
65 #define MAXPROCS 10000
68 # include <sysexits.h>
70 # define EX_SOFTWARE 1
80 #define __MERF_OO_ "%s: Malloc Failed in %s: %d\n"
82 #define MALLOC(Ptr,Num,Typ) do \
83 if (!(Ptr = (Typ *)malloc((Num)*(sizeof(Typ))))) \
84 {fprintf(stderr,__MERF_OO_,my_name,__FILE__,__LINE__);\
85 exit(EX_OSERR);} while(0)
87 #define Malloc(Ptr,Num,Typ) do \
88 if (!(Ptr = (Typ *)malloc((Num)*(sizeof(Typ))))) \
89 fprintf(stderr,__MERF_OO_,my_name,__FILE__,__LINE__);\
92 #define FILEOPEN(Fp,Fn,Mod) do \
93 if (!(Fp = fopen(Fn,Mod)))\
94 {fprintf(stderr,"%s: Couldn't open %s\n",my_name,Fn);\
95 exit(EX_IOERR);} while(0)
97 #define Fileopen(Fp,Fn,Mod) do \
98 if(!(Fp = fopen(Fn,Mod))) \
99 fprintf(stderr,"%s: Couldn't open %s\n",my_name,Fn);\
106 unsigned long children;
109 static struct stack_t fn_stack[STACKSIZ+1];
111 static unsigned int stacktop = 0;
113 static unsigned long tot_time = 0;
114 static unsigned long tot_calls = 0;
115 static unsigned long highstack = 0;
116 static unsigned long lowstack = (ulong) ~0;
123 #define top() &fn_stack[stacktop]
129 void push (name_pos, time_entered)
130 register
unsigned int name_pos;
131 register
unsigned long time_entered;
136 if (++stacktop > STACKSIZ) {
137 fprintf (DBUG_FILE,
"%s: stack overflow (%s:%d)\n",
138 my_name, __FILE__, __LINE__);
141 DBUG_PRINT (
"push", (
"%d %ld",name_pos,time_entered));
142 t = &fn_stack[stacktop];
144 t -> time = time_entered;
155 unsigned int pop (name_pos, time_entered, child_time)
156 register
unsigned int *name_pos;
157 register
unsigned long *time_entered;
158 register
unsigned long *child_time;
161 register unsigned int rtnval;
168 temp = &fn_stack[stacktop];
169 *name_pos = temp->pos;
170 *time_entered = temp->time;
171 *child_time = temp->children;
172 DBUG_PRINT (
"pop", (
"%d %lu %lu",*name_pos,*time_entered,*child_time));
175 DBUG_RETURN (rtnval);
185 unsigned long m_time;
186 unsigned long m_calls;
187 unsigned long m_stkuse;
190 static struct module_t modules[MAXPROCS];
203 static struct bnode s_table[MAXPROCS];
205 static unsigned int n_items = 0;
214 register char *retval;
215 register unsigned int len;
217 DBUG_ENTER (
"strsave");
218 DBUG_PRINT (
"strsave", (
"%s",s));
219 if (!s || (len = strlen (s)) == 0) {
222 MALLOC (retval, ++len,
char);
224 DBUG_RETURN (retval);
233 unsigned int add (m_name)
236 register unsigned int ind = 0;
241 s_table[0].pos = ind;
242 s_table[0].lchild = s_table[0].rchild = MAXPROCS;
244 modules[n_items].name = strsave (m_name);
245 modules[n_items].m_time = 0;
246 modules[n_items].m_calls = 0;
247 modules[n_items].m_stkuse = 0;
248 DBUG_RETURN (n_items++);
250 while ((cmp = strcmp (m_name,modules[ind].
name))) {
252 if (s_table[ind].lchild == MAXPROCS) {
254 if (n_items >= MAXPROCS) {
256 "%s: Too many functions being profiled\n",
260 s_table[n_items].pos = s_table[ind].lchild = n_items;
261 s_table[n_items].lchild = s_table[n_items].rchild = MAXPROCS;
263 modules[n_items].name = strsave (m_name);
264 modules[n_items].m_time = modules[n_items].m_calls = 0;
265 DBUG_RETURN (n_items++);
271 ind = s_table[ind].lchild;
273 if (s_table[ind].rchild == MAXPROCS) {
275 if (n_items >= MAXPROCS) {
277 "%s: Too many functions being profiled\n",
281 s_table[n_items].pos = s_table[ind].rchild = n_items;
282 s_table[n_items].lchild = s_table[n_items].rchild = MAXPROCS;
284 modules[n_items].name = strsave (m_name);
285 modules[n_items].m_time = modules[n_items].m_calls = 0;
286 DBUG_RETURN (n_items++);
292 ind = s_table[ind].rchild;
307 unsigned long fn_time;
308 unsigned long fn_sbot;
309 unsigned long fn_ssz;
310 unsigned long lastuse;
312 unsigned long local_time;
314 unsigned long oldtime;
315 unsigned long oldchild;
318 DBUG_ENTER (
"process");
319 while (fgets (buf,BUFSIZ,inf) != NULL) {
322 sscanf (buf+2,
"%ld %64s", &fn_time, fn_name);
323 DBUG_PRINT (
"erec", (
"%ld %s", fn_time, fn_name));
328 sscanf (buf+2,
"%ld %64s", &fn_time, fn_name);
329 DBUG_PRINT (
"xrec", (
"%ld %s", fn_time, fn_name));
336 while (pop (&oldpos, &oldtime, &oldchild)) {
337 DBUG_PRINT (
"popped", (
"%lu %lu", oldtime, oldchild));
338 local_time = fn_time - oldtime;
340 t -> children += local_time;
341 DBUG_PRINT (
"update", (
"%s", modules[t -> pos].name));
342 DBUG_PRINT (
"update", (
"%lu", t -> children));
343 local_time -= oldchild;
344 modules[oldpos].m_time += local_time;
345 modules[oldpos].m_calls++;
346 tot_time += local_time;
358 local_time = fn_time - t -> time - t -> children;
359 t -> time = fn_time; t -> children = 0;
360 modules[pos].m_time += local_time;
361 modules[pos].m_calls++;
362 tot_time += local_time;
366 sscanf (buf+2,
"%lx %lx %64s", &fn_sbot, &fn_ssz, fn_name);
367 DBUG_PRINT (
"srec", (
"%lx %lx %s", fn_sbot, fn_ssz, fn_name));
369 lastuse = modules[pos].m_stkuse;
380 if (lastuse > 0 && lastuse != fn_ssz) {
382 "warning - %s stack use changed (%lx to %lx)\n",
383 fn_name, lastuse, fn_ssz);
386 if (fn_ssz > lastuse) {
387 modules[pos].m_stkuse = fn_ssz;
389 if (fn_sbot > highstack) {
391 }
else if (fn_sbot < lowstack) {
396 fprintf (stderr,
"unknown record type '%c'\n", buf[0]);
407 while (pop (&oldpos,&oldtime,&oldchild)) {
408 local_time = fn_time - oldtime;
410 t -> children += local_time;
411 local_time -= oldchild;
412 modules[oldpos].m_time += local_time;
413 modules[oldpos].m_calls++;
414 tot_time += local_time;
424 void out_header (outf)
427 DBUG_ENTER (
"out_header");
429 fprintf (outf,
"Profile of Execution\n");
430 fprintf (outf,
"Execution times are in milliseconds\n\n");
431 fprintf (outf,
" Calls\t\t\t Time\n");
432 fprintf (outf,
" -----\t\t\t ----\n");
433 fprintf (outf,
"Times\tPercentage\tTime Spent\tPercentage\n");
434 fprintf (outf,
"Called\tof total\tin Function\tof total Importance\tFunction\n");
435 fprintf (outf,
"======\t==========\t===========\t========== ==========\t========\t\n");
437 fprintf (outf,
"%ld bytes of stack used, from %lx down to %lx\n\n",
438 highstack - lowstack, highstack, lowstack);
440 " %%time sec #call ms/call %%calls weight stack name\n");
449 void out_trailer (outf,sum_calls,sum_time)
451 unsigned long int sum_calls, sum_time;
453 DBUG_ENTER (
"out_trailer");
456 fprintf(outf,
"======\t==========\t===========\t==========\t========\n");
457 fprintf(outf,
"%6ld\t%10.2f\t%11ld\t%10.2f\t\t%-15s\n",
458 sum_calls, 100.0, sum_time, 100.0,
"Totals");
468 void out_item (outf, m,called,timed)
471 unsigned long int *called, *timed;
473 char *name = m ->
name;
474 register unsigned int calls = m -> m_calls;
475 register unsigned long local_time = m -> m_time;
476 register unsigned long stkuse = m -> m_stkuse;
478 double per_time = 0.0;
479 double per_calls = 0.0;
480 double ms_per_call, local_ftime;
482 DBUG_ENTER (
"out_item");
485 per_time = (double) (local_time * 100) / (double) tot_time;
488 per_calls = (double) (calls * 100) / (double) tot_calls;
490 import = (
unsigned int) (per_time * per_calls);
493 fprintf (outf,
"%6d\t%10.2f\t%11ld\t%10.2f %10d\t%-15s\n",
494 calls, per_calls, local_time, per_time,
import, name);
496 ms_per_call = local_time;
497 ms_per_call /= calls;
498 local_ftime = local_time;
500 fprintf(outf,
"%8.2f%8.3f%8u%8.3f%8.2f%8u%8lu %-s\n",
501 per_time, local_ftime, calls, ms_per_call, per_calls,
import,
515 void out_body (outf, root,s_calls,s_time)
517 register
unsigned int root;
518 register
unsigned long int *s_calls, *s_time;
520 unsigned long int calls, local_time;
522 DBUG_ENTER (
"out_body");
523 DBUG_PRINT (
"out_body", (
"%lu,%lu",*s_calls,*s_time));
524 if (root == MAXPROCS) {
525 DBUG_PRINT (
"out_body", (
"%lu,%lu",*s_calls,*s_time));
527 while (root != MAXPROCS) {
528 out_body (outf, s_table[root].lchild,s_calls,s_time);
529 out_item (outf, &modules[s_table[root].pos],&calls,&local_time);
530 DBUG_PRINT (
"out_body", (
"-- %lu -- %lu --", calls, local_time));
532 *s_time += local_time;
533 root = s_table[root].rchild;
535 DBUG_PRINT (
"out_body", (
"%lu,%lu", *s_calls, *s_time));
547 unsigned long int sum_calls = 0;
548 unsigned long int sum_time = 0;
550 DBUG_ENTER (
"output");
552 fprintf (outf,
"%s: No functions to trace\n", my_name);
556 out_body (outf, 0,&sum_calls,&sum_time);
557 out_trailer (outf, sum_calls,sum_time);
562 #define usage() fprintf (DBUG_FILE,"Usage: %s [-v] [prof-file]\n",my_name)
567 int main (
int argc,
char **argv)
572 FILE *outfile = {stdout};
574 my_thread_global_init();
577 DBUG_PROCESS (argv[0]);
579 while ((c = getopt (argc,argv,
"#:v")) != EOF) {
594 DBUG_RETURN (EX_USAGE);
597 FILEOPEN (infile, argv[optind],
"r");
599 FILEOPEN (infile, PRO_FILE,
"r");