⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dbug_ana.c

📁 MySQL的ODBC接口程序源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Analyze the profile file (cmon.out) written out by the dbug * routines with profiling enabled. * * Copyright June 1987, Binayak Banerjee * All rights reserved. * * This program may be freely distributed under the same terms and * conditions as Fred Fish's Dbug package. * * Compile with -- cc -O -s -o %s analyze.c * * Analyze will read an trace file created by the dbug package * (when run with traceing enabled).  It will then produce a * summary on standard output listing the name of each traced * function, the number of times it was called, the percentage * of total calls, the time spent executing the function, the * proportion of the total time and the 'importance'.  The last * is a metric which is obtained by multiplying the proportions * of calls and the proportions of time for each function.  The * greater the importance, the more likely it is that a speedup * could be obtained by reducing the time taken by that function. * * Note that the timing values that you obtain are only rough * measures.  The overhead of the dbug package is included * within.  However, there is no need to link in special profiled * libraries and the like. * * CHANGES: * *	2-Mar-89: fnf *	Changes to support tracking of stack usage.  This required *	reordering the fields in the profile log file to make *	parsing of different record types easier.  Corresponding *	changes made in dbug runtime library.  Also used this *	opportunity to reformat the code more to my liking (my *	apologies to Binayak Banerjee for "uglifying" his code). * *	24-Jul-87: fnf *	Because I tend to use functions names like *	"ExternalFunctionDoingSomething", I've rearranged the *	printout to put the function name last in each line, so *	long names don't screw up the formatting unless they are *	*very* long and wrap around the screen width... * *	24-Jul-87: fnf *	Modified to put out table very similar to Unix profiler *	by default, but also puts out original verbose table *	if invoked with -v flag. */#include <global.h>static char *my_name;static int verbose;/* * Structure of the stack. */#define PRO_FILE	"dbugmon.out"	/* Default output file name */#define STACKSIZ	100		/* Maximum function nesting */#define MAXPROCS	10000		/* Maximum number of function calls */# ifdef BSD#	include <sysexits.h># else#	define EX_SOFTWARE 1#	define EX_DATAERR 1#	define EX_USAGE 1#	define EX_OSERR 1#	define EX_IOERR 1#	define EX_OK 0# endif#define __MERF_OO_ "%s: Malloc Failed in %s: %d\n"#define MALLOC(Ptr,Num,Typ) do	/* Malloc w/error checking & exit */ \	if (!(Ptr = (Typ *)malloc((Num)*(sizeof(Typ))))) \		{fprintf(stderr,__MERF_OO_,my_name,__FILE__,__LINE__);\		exit(EX_OSERR);} while(0)#define Malloc(Ptr,Num,Typ) do	/* Weaker version of above */\	if (!(Ptr = (Typ *)malloc((Num)*(sizeof(Typ))))) \		fprintf(stderr,__MERF_OO_,my_name,__FILE__,__LINE__);\		 while(0)#define FILEOPEN(Fp,Fn,Mod) do	/* File open with error exit */ \	if (!(Fp = fopen(Fn,Mod)))\		{fprintf(stderr,"%s: Couldn't open %s\n",my_name,Fn);\		exit(EX_IOERR);} while(0)#define Fileopen(Fp,Fn,Mod) do	/* Weaker version of above */ \	if(!(Fp = fopen(Fn,Mod))) \		fprintf(stderr,"%s: Couldn't open %s\n",my_name,Fn);\	while(0)struct stack_t {    unsigned int pos;			/* which function? */    unsigned long time;			/* Time that this was entered */    unsigned long children;		/* Time spent in called funcs */};static struct stack_t fn_stack[STACKSIZ+1];static unsigned int stacktop = 0;	/* Lowest stack position is a dummy */static unsigned long tot_time = 0;static unsigned long tot_calls = 0;static unsigned long highstack = 0;static unsigned long lowstack = (ulong) ~0;/* * top() returns a pointer to the top item on the stack. * (was a function, now a macro) */#define top()	&fn_stack[stacktop]/* * Push - Push the given record on the stack. */void push (name_pos, time_entered)register unsigned int name_pos;register unsigned long time_entered;{    register struct stack_t *t;    DBUG_ENTER("push");    if (++stacktop > STACKSIZ) {	fprintf (DBUG_FILE,"%s: stack overflow (%s:%d)\n",		my_name, __FILE__, __LINE__);	exit (EX_SOFTWARE);    }    DBUG_PRINT ("push", ("%d %ld",name_pos,time_entered));    t = &fn_stack[stacktop];    t -> pos = name_pos;    t -> time = time_entered;    t -> children = 0;    DBUG_VOID_RETURN;}/* * Pop - pop the top item off the stack, assigning the field values * to the arguments. Returns 0 on stack underflow, or on popping first * item off stack. */unsigned int pop (name_pos, time_entered, child_time)register unsigned int *name_pos;register unsigned long *time_entered;register unsigned long *child_time;{    register struct stack_t *temp;    register unsigned int rtnval;    DBUG_ENTER ("pop");    if (stacktop < 1) {	rtnval = 0;    } else {	temp =  &fn_stack[stacktop];	*name_pos = temp->pos;	*time_entered = temp->time;	*child_time = temp->children;	DBUG_PRINT ("pop", ("%d %d %d",*name_pos,*time_entered,*child_time));	rtnval = stacktop--;    }    DBUG_RETURN (rtnval);}/* * We keep the function info in another array (serves as a simple * symbol table) */struct module_t {    char *name;    unsigned long m_time;    unsigned long m_calls;    unsigned long m_stkuse;};static struct module_t modules[MAXPROCS];/* * We keep a binary search tree in order to look up function names * quickly (and sort them at the end. */struct bnode {    unsigned int lchild;	/* Index of left subtree */    unsigned int rchild;	/* Index of right subtree */    unsigned int pos;		/* Index of module_name entry */};static struct bnode s_table[MAXPROCS];static unsigned int n_items = 0;	/* No. of items in the array so far *//* * Need a function to allocate space for a string and squirrel it away. */char *strsave (s)char *s;{    register char *retval;    register unsigned int len;    DBUG_ENTER ("strsave");    DBUG_PRINT ("strsave", ("%s",s));    if (!s || (len = strlen (s)) == 0) {	DBUG_RETURN (0);    }    MALLOC (retval, ++len, char);    strcpy (retval, s);    DBUG_RETURN (retval);}/* * add() - adds m_name to the table (if not already there), and returns * the index of its location in the table.  Checks s_table (which is a * binary search tree) to see whether or not it should be added. */unsigned int add (m_name)char *m_name;{    register unsigned int ind = 0;    register int cmp;    DBUG_ENTER ("add");    if (n_items == 0) {		/* First item to be added */	s_table[0].pos = ind;	s_table[0].lchild = s_table[0].rchild = MAXPROCS;	addit:	modules[n_items].name = strsave (m_name);	modules[n_items].m_time = 0;	modules[n_items].m_calls = 0;	modules[n_items].m_stkuse = 0;	DBUG_RETURN (n_items++);    }    while (cmp = strcmp (m_name,modules[ind].name)) {	if (cmp < 0) {	/* In left subtree */	    if (s_table[ind].lchild == MAXPROCS) {		/* Add as left child */		if (n_items >= MAXPROCS) {		    fprintf (DBUG_FILE,			    "%s: Too many functions being profiled\n",			     my_name);		    exit (EX_SOFTWARE);		}		s_table[n_items].pos = s_table[ind].lchild = n_items;		s_table[n_items].lchild = s_table[n_items].rchild = MAXPROCS;#ifdef notdef		modules[n_items].name = strsave (m_name);		modules[n_items].m_time = modules[n_items].m_calls = 0;		DBUG_RETURN (n_items++);#else		goto addit;#endif	    }	    ind = s_table[ind].lchild; /* else traverse l-tree */	} else {	    if (s_table[ind].rchild == MAXPROCS) {		/* Add as right child */		if (n_items >= MAXPROCS) {		    fprintf (DBUG_FILE,			     "%s: Too many functions being profiled\n",			     my_name);		    exit (EX_SOFTWARE);		}		s_table[n_items].pos = s_table[ind].rchild = n_items;		s_table[n_items].lchild = s_table[n_items].rchild = MAXPROCS;#ifdef notdef		modules[n_items].name = strsave (m_name);		modules[n_items].m_time = modules[n_items].m_calls = 0;		DBUG_RETURN (n_items++);#else		goto addit;#endif	    }	    ind = s_table[ind].rchild; /* else traverse r-tree */	}    }    DBUG_RETURN (ind);}/* * process() - process the input file, filling in the modules table. */void process (inf)FILE *inf;{  char buf[BUFSIZ];  char fn_name[64];		/* Max length of fn_name */  unsigned long fn_time;  unsigned long fn_sbot;  unsigned long fn_ssz;  unsigned long lastuse;  unsigned int pos;  unsigned long time;  unsigned int oldpos;  unsigned long oldtime;  unsigned long oldchild;  struct stack_t *t;  DBUG_ENTER ("process");  while (fgets (buf,BUFSIZ,inf) != NULL) {    switch (buf[0]) {    case 'E':      sscanf (buf+2, "%ld %64s", &fn_time, fn_name);      DBUG_PRINT ("erec", ("%ld %s", fn_time, fn_name));      pos = add (fn_name);      push (pos, fn_time);      break;    case 'X':      sscanf (buf+2, "%ld %64s", &fn_time, fn_name);      DBUG_PRINT ("xrec", ("%ld %s", fn_time, fn_name));      pos = add (fn_name);      /*       * An exited function implies that all stacked       * functions are also exited, until the matching       * function is found on the stack.       */      while (pop (&oldpos, &oldtime, &oldchild)) {	DBUG_PRINT ("popped", ("%d %d", oldtime, oldchild));	time = fn_time - oldtime;	t = top ();	t -> children += time;	DBUG_PRINT ("update", ("%s", modules[t -> pos].name));	DBUG_PRINT ("update", ("%d", t -> children));	time -= oldchild;	modules[oldpos].m_time += time;	modules[oldpos].m_calls++;	tot_time += time;	tot_calls++;	if (pos == oldpos) {	  goto next_line;	/* Should be a break2 */	}      }      /*       * Assume that item seen started at time 0.       * (True for function main).  But initialize       * it so that it works the next time too.       */      t = top ();      time = fn_time - t -> time - t -> children;      t -> time = fn_time; t -> children = 0;      modules[pos].m_time += time;      modules[pos].m_calls++;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -