mirror of
https://github.com/MariaDB/server.git
synced 2025-01-18 13:02:28 +01:00
f00257ddd0
- Removed not used variables and functions - Added #ifdef around code that is not used - Renamed variables and functions to avoid conflicts - Removed some not used arguments Fixed some class/struct warnings in ndb Added define IS_LONGDATA() to simplify code in libmysql.c I did run gcov on the changes and added 'purecov' comments on almost all lines that was not just variable name changes BUILD/SETUP.sh: Added printing of unused functions and variables. Made it easy to test compiling with -Wshadow BUILD/compile-pentium-gcov: Added warnings Mark binary with -gcov client/mysql.cc: Fixed warnings found with gcc -Wshadow client/mysql_upgrade.c: Fixed warnings found with gcc -Wshadow client/mysqlbinlog.cc: Fixed warnings found with gcc -Wshadow client/mysqldump.c: Fixed warnings found with gcc -Wshadow client/mysqltest.c: Fixed warnings found with gcc -Wshadow client/sql_string.cc: Fixed warnings found with gcc -Wshadow Merged with sql/sql_string.cc client/sql_string.h: Fixed warnings found with gcc -Wshadow Merged with sql/sql_string.h cmd-line-utils/readline/display.c: Fixed compiler warning cmd-line-utils/readline/histexpand.c: Fixed warnings found with gcc -Wshadow cmd-line-utils/readline/input.c: Fixed warnings found with gcc -Wshadow cmd-line-utils/readline/text.c: Fixed warnings found with gcc -Wshadow cmd-line-utils/readline/vi_mode.c: Fixed warnings found with gcc -Wshadow dbug/dbug_analyze.c: Fixed warnings found with gcc -Wshadow extra/my_print_defaults.c: Prefixed defaults_extra_file and defaults_group_suffix with 'my' to avoid conflicts with similar named local variables extra/yassl/include/buffer.hpp: Fixed compiler warnings extra/yassl/include/crypto_wrapper.hpp: Fixed compiler warnings extra/yassl/include/yassl_imp.hpp: Fixed compiler warnings extra/yassl/include/yassl_int.hpp: Fixed compiler warnings extra/yassl/src/crypto_wrapper.cpp: Fixed compiler warnings extra/yassl/taocrypt/benchmark/benchmark.cpp: Fixed warnings found with gcc -Wshadow extra/yassl/taocrypt/include/algebra.hpp: Fixed compiler warnings extra/yassl/taocrypt/include/des.hpp: Fixed compiler warnings extra/yassl/taocrypt/include/hash.hpp: Fixed compiler warnings extra/yassl/taocrypt/include/hmac.hpp: Fixed compiler warnings extra/yassl/taocrypt/include/modarith.hpp: Fixed compiler warnings extra/yassl/taocrypt/include/modes.hpp: Fixed compiler warnings extra/yassl/taocrypt/include/rsa.hpp: Fixed compiler warnings extra/yassl/taocrypt/mySTL/list.hpp: Fixed compiler warnings extra/yassl/taocrypt/src/aes.cpp: Fixed compiler warnings extra/yassl/taocrypt/src/algebra.cpp: Fixed compiler warnings extra/yassl/taocrypt/src/asn.cpp: Fixed compiler warnings extra/yassl/taocrypt/test/test.cpp: Fixed compiler warnings extra/yassl/testsuite/testsuite.cpp: Fixed compiler warnings include/m_ctype.h: Fixed warnings found with gcc -Wshadow include/my_pthread.h: Fixed warnings found with gcc -Wshadow include/my_sys.h: Fixed warnings found with gcc -Wshadow include/my_time.h: Fixed warnings found with gcc -Wshadow include/mysql.h: Fixed warnings found with gcc -Wshadow Added define IS_LONGDATA() to simplify code in libmysql.c libmysql/libmysql.c: Fixed warnings found with gcc -Wshadow (Mostly replaced bind -> my_bind and time -> my_time) libmysqld/lib_sql.cc: Removed not used variables and labels myisam/ft_boolean_search.c: Fixed warnings found with gcc -Wshadow myisam/mi_open.c: Fixed warnings found with gcc -Wshadow myisam/mi_search.c: Fixed warnings found with gcc -Wshadow myisam/mi_unique.c: Fixed compiler warning myisam/myisampack.c: Fixed warnings found with gcc -Wshadow myisam/rt_index.c: Remove not used variables myisam/sort.c: Fixed warnings found with gcc -Wshadow mysql-test/r/mysqlcheck.result: Remove databases and tables possible left by previous test mysql-test/r/mysqltest.result: New test results mysql-test/t/mysql.test: Coverage tests mysql-test/t/mysqlbinlog.test: Coverage tests mysql-test/t/mysqlcheck.test: Remove databases and tables possible left by previous test mysql-test/t/mysqltest.test: Coverage tests mysys/default.c: Prefixed defaults_file, defaults_group_suffix and defaults_extra_file with 'my' to avoid conflicts with local variables in some functions mysys/mf_iocache2.c: Fixed warnings found with gcc -Wshadow mysys/mf_keycache.c: Fixed warnings found with gcc -Wshadow mysys/my_bitmap.c: Fixed warnings found with gcc -Wshadow mysys/sha1.c: Fixed warnings found with gcc -Wshadow ndb/include/kernel/signaldata/ArbitSignalData.hpp: Fixed compiler warning ndb/include/kernel/signaldata/DictTabInfo.hpp: Fixed compiler warnings ndb/include/ndbapi/NdbReceiver.hpp: Fixed warnings found with gcc -Wshadow ndb/include/transporter/TransporterDefinitions.hpp: Fixed compiler warning ndb/include/util/InputStream.hpp: Fixed compiler warning ndb/include/util/OutputStream.hpp: Fixed compiler warning ndb/include/util/SimpleProperties.hpp: Fixed compiler warning ndb/include/util/SocketAuthenticator.hpp: Fixed compiler warning ndb/include/util/SocketServer.hpp: Fixed compiler warning ndb/src/common/mgmcommon/ConfigRetriever.cpp: Fixed warnings found with gcc -Wshadow ndb/src/common/portlib/NdbTick.c: Fixed warnings found with gcc -Wshadow ndb/src/common/transporter/SHM_Transporter.cpp: Fixed warnings found with gcc -Wshadow ndb/src/common/transporter/TCP_Transporter.cpp: Fixed warnings found with gcc -Wshadow ndb/src/common/transporter/TCP_Transporter.hpp: Fixed compiler warning ndb/src/common/transporter/Transporter.cpp: Removed not used variable ndb/src/common/transporter/TransporterRegistry.cpp: Removed not used variable ndb/src/common/util/Bitmask.cpp: Moved function to avoid warnings of not used function ndb/src/common/util/ConfigValues.cpp: Fixed warnings found with gcc -Wshadow ndb/src/common/util/File.cpp: Fixed warnings found with gcc -Wshadow ndb/src/common/util/Properties.cpp: Fixed warnings found with gcc -Wshadow ndb/src/common/util/SocketClient.cpp: Fixed wrong return value ndb/src/common/util/random.c: Fixed warnings found with gcc -Wshadow ndb/src/common/util/socket_io.cpp: Fixed warnings found with gcc -Wshadow ndb/src/cw/cpcd/APIService.cpp: Removed not used variable ndb/src/cw/cpcd/main.cpp: Removed not used variables ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp: Fixed compiler warnings ndb/src/kernel/blocks/dbdict/Dbdict.cpp: Removed not used variables ndb/src/kernel/blocks/dbdict/Dbdict.hpp: Fixed compiler warnings ndb/src/kernel/blocks/dbdih/Dbdih.hpp: Fixed compiler warnings ndb/src/kernel/blocks/dblqh/Dblqh.hpp: Fixed compiler warnings ndb/src/kernel/blocks/dblqh/DblqhMain.cpp: Removed not used variables ndb/src/kernel/blocks/dbtc/Dbtc.hpp: Fixed compiler warnings ndb/src/kernel/blocks/dbtup/Dbtup.hpp: Fixed compiler warnings ndb/src/kernel/blocks/dbtup/DbtupScan.cpp: Removed not used variable ndb/src/kernel/blocks/dbtux/DbtuxNode.cpp: Removed not used variables ndb/src/kernel/blocks/dbtux/DbtuxScan.cpp: Removed not used variables ndb/src/kernel/blocks/dbtux/DbtuxTree.cpp: Removed not used variables ndb/src/kernel/blocks/ndbcntr/Ndbcntr.hpp: Fixed compiler warnings ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp: Removed not used variables ndb/src/kernel/blocks/ndbfs/AsyncFile.hpp: Fixed compiler warnings ndb/src/kernel/blocks/qmgr/Qmgr.hpp: Fixed compiler warnings ndb/src/kernel/blocks/qmgr/QmgrMain.cpp: Removed not used variables ndb/src/kernel/blocks/suma/Suma.cpp: Removed not used variables ndb/src/kernel/blocks/suma/Suma.hpp: Fixed compiler warnings ndb/src/kernel/vm/MetaData.hpp: Fixed compiler warnings ndb/src/mgmapi/LocalConfig.cpp: Fixed warnings found with gcc -Wshadow ndb/src/mgmapi/mgmapi.cpp: Fixed warnings found with gcc -Wshadow ndb/src/mgmclient/CommandInterpreter.cpp: Removed not used variables ndb/src/mgmsrv/ConfigInfo.cpp: Fixed warnings found with gcc -Wshadow Removed not used variables ndb/src/mgmsrv/ConfigInfo.hpp: Fixed warnings found with gcc -Wshadow ndb/src/mgmsrv/InitConfigFileParser.cpp: Prefixed defaults_file, defaults_group_suffix and defaults_extra_file with 'my' to avoid conflicts with local variables in some functions ndb/src/mgmsrv/MgmtSrvr.cpp: Removed not used variables and functions ndb/src/mgmsrv/MgmtSrvr.hpp: Fixed compiler warnings ndb/src/mgmsrv/Services.cpp: Removed not used variables and functions ndb/src/mgmsrv/main.cpp: Removed not used variable ndb/src/ndbapi/ClusterMgr.hpp: Fixed compiler warnings ndb/src/ndbapi/Ndb.cpp: Removed not used variables ndb/src/ndbapi/NdbBlob.cpp: Removed not used variables ndb/src/ndbapi/NdbDictionaryImpl.cpp: Removed not used variables ndb/src/ndbapi/NdbIndexOperation.cpp: Removed not used variables ndb/src/ndbapi/NdbOperationDefine.cpp: Removed not used variables ndb/src/ndbapi/NdbOperationExec.cpp: Removed not used variables ndb/src/ndbapi/NdbOperationSearch.cpp: Removed not used variables ndb/src/ndbapi/NdbScanFilter.cpp: Fixed compiler warning ndb/src/ndbapi/NdbScanOperation.cpp: Removed not used variables ndb/src/ndbapi/SignalSender.cpp: Removed not used variables ndb/src/ndbapi/ndb_cluster_connection.cpp: Removed not used variable ndb/tools/delete_all.cpp: Removed not used variable ndb/tools/desc.cpp: Removed not used variable ndb/tools/drop_index.cpp: Removed not used variable ndb/tools/drop_tab.cpp: Removed not used variable ndb/tools/listTables.cpp: Removed not used variable ndb/tools/ndb_config.cpp: Fixed warnings found with gcc -Wshadow Added missing puts(desc) ndb/tools/restore/Restore.hpp: Changed delimiter to define instead of static variable, as the static variable caused a LOT of compiler warnings Fixed compiler warning ndb/tools/restore/consumer.hpp: Fixed compiler warning ndb/tools/restore/restore_main.cpp: Fixed compiler warnings ndb/tools/select_all.cpp: Removed not used variables ndb/tools/select_count.cpp: Removed not used variable server-tools/instance-manager/commands.h: Fixed compiler warnings server-tools/instance-manager/guardian.cc: Fixed compiler warnings server-tools/instance-manager/instance_options.cc: Removed not used variables server-tools/instance-manager/mysql_connection.cc: Fixed compiler warnings server-tools/instance-manager/options.cc: Fixed compiler warnings server-tools/instance-manager/options.h: Fixed compiler warnings server-tools/instance-manager/parse.cc: Removed not used variable server-tools/instance-manager/user_map.cc: Fixed compiler warnings server-tools/instance-manager/user_map.h: Fixed compiler warnings sql/field.cc: Fixed compiler warnings sql/field.h: Fixed compiler warnings sql/filesort.cc: Fixed compiler warnings sql/ha_archive.cc: Removed table and share arguments from get_share() / free_share() to get rid of compiler warnings sql/ha_archive.h: Removed table and share arguments from get_share() / free_share() to get rid of compiler warnings sql/ha_federated.cc: Fixed compiler warnings sql/ha_heap.cc: Fixed compiler warnings sql/ha_myisam.cc: Fixed compiler warnings sql/ha_myisammrg.cc: Fixed compiler warnings sql/ha_ndbcluster.cc: Fixed compiler warnings sql/handler.cc: Fixed compiler warnings sql/item.cc: Fixed compiler warnings sql/item.h: Fixed compiler warnings new_item() -> clone_item(), to avoid a lot of warnings with variable 'new_item' el() -> element_index() sql/item_cmpfunc.cc: Fixed compiler warnings sql/item_cmpfunc.h: Fixed compiler warnings sql/item_func.cc: Fixed compiler warnings sql/item_geofunc.cc: Fixed compiler warnings sql/item_row.h: Fixed compiler warnings sql/item_strfunc.cc: Fixed compiler warnings sql/item_subselect.cc: Fixed compiler warnings sql/item_subselect.h: Fixed compiler warnings sql/item_sum.cc: Fixed compiler warnings sql/item_timefunc.cc: Fixed compiler warnings sql/log.cc: Fixed compiler warnings More comments Added #ifdef HAVE_REPLICATION sql/log_event.cc: Fixed compiler warnings sql/log_event.h: Fixed compiler warnings sql/mysql_priv.h: query_id -> global_query_id, to avoid a lot of clashes with function and class variables start_time -> server_start_time sql/mysqld.cc: Fixed compiler warnings: - Removed not used variables - Added #ifndef EMBEDDED_LIBRARY - Fixed shadow warnings sql/net_serv.cc: Fixed compiler warnings sql/opt_range.cc: range -> last_range to avoid shadow warnings Removed not used function print_rowid() sql/opt_range.h: range -> last_range to avoid shadow warnings sql/password.c: Fixed compiler warnings sql/protocol.cc: Fixed compiler warnings sql/repl_failsafe.cc: Fixed compiler warnings sql/set_var.cc: Fixed compiler warnings sql/set_var.h: type() -> show_type() Fixed compiler warnings sql/slave.cc: Fixed compiler warnings sql/sp_head.cc: Fixed compiler warnings sql/sp_head.h: Fixed compiler warnings sql/spatial.cc: Fixed compiler warnings sql/spatial.h: length() -> geom_length() to avoid compiler warnings wkb_end -> wkb_last to avoid compiler warnings with local variables named 'wkb_end' sql/sql_cache.h: Fixed compiler warnings sql/sql_class.cc: Fixed compiler warnings sql/sql_class.h: log -> log_xid() to avoid compiler warnings Fixed shadow compiler warnings sql/sql_derived.cc: Removed not used variable sql/sql_insert.cc: Fixed compiler warnings sql/sql_lex.cc: Fixed compiler warnings sql/sql_lex.h: res -> saved_error to make the meaning of the variable clear and avoid shadow warnings sql/sql_load.cc: Fixed compiler warnings sql/sql_parse.cc: Fixed compiler warnings sql/sql_prepare.cc: Fixed compiler warnings sql/sql_select.cc: Fixed compiler warnings sql/sql_show.cc: Fixed compiler warnings sql/sql_string.cc: Fixed compiler warnings sql/sql_string.h: Fixed compiler warnings sql/sql_table.cc: Fixed compiler warnings sql/sql_trigger.cc: Fixed compiler warnings sql/sql_trigger.h: table -> trigger_table to avoid warnings from local variables sql/sql_union.cc: Fixed compiler warnings (mainly res -> saved_error) sql-common/client.c: Removed not used variable sql-common/my_time.c: Removed not used variable time -> my_time sql/sql_update.cc: Removed not used variable sql/sql_view.cc: Removed not used variable sql/sql_yacc.yy: Removed not used variable sql/table.cc: Removed not used variable sql/tztime.cc: Removed not used variable sql/unireg.cc: Removed not used variable strings/ctype-bin.c: mblen -> mb_len to avoid compiler warnings with local variable mblen strings/ctype-cp932.c: Fixed compiler warnings strings/ctype-eucjpms.c: Fixed compiler warnings strings/ctype-mb.c: mblen -> mb_len to avoid compiler warnings with local variable mblen strings/ctype-simple.c: mblen -> mb_len to avoid compiler warnings with local variable mblen exp -> exponent strings/ctype-sjis.c: Fixed compiler warnings strings/ctype-uca.c: mblen -> mb_len to avoid compiler warnings with local variable mblen strings/ctype-ujis.c: Fixed compiler warnings strings/ctype-utf8.c: Fixed compiler warnings strings/decimal.c: Fixed compiler warnings strings/my_vsnprintf.c: Added comment strings/strtod.c: Fixed compiler warnings tests/mysql_client_test.c: Fixed compiler warnings (Biggest part of patch is to not get a conflict with global function 'bind')
724 lines
20 KiB
C
724 lines
20 KiB
C
/*
|
|
* 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 <my_global.h>
|
|
#include <m_string.h>
|
|
#include <my_pthread.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
|
|
#ifndef EX_OK
|
|
# define EX_OK 0
|
|
#endif
|
|
# 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 %lu %lu",*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 local_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", ("%lu %lu", oldtime, oldchild));
|
|
local_time = fn_time - oldtime;
|
|
t = top ();
|
|
t -> children += local_time;
|
|
DBUG_PRINT ("update", ("%s", modules[t -> pos].name));
|
|
DBUG_PRINT ("update", ("%lu", t -> children));
|
|
local_time -= oldchild;
|
|
modules[oldpos].m_time += local_time;
|
|
modules[oldpos].m_calls++;
|
|
tot_time += local_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 ();
|
|
local_time = fn_time - t -> time - t -> children;
|
|
t -> time = fn_time; t -> children = 0;
|
|
modules[pos].m_time += local_time;
|
|
modules[pos].m_calls++;
|
|
tot_time += local_time;
|
|
tot_calls++;
|
|
break;
|
|
case 'S':
|
|
sscanf (buf+2, "%lx %lx %64s", &fn_sbot, &fn_ssz, fn_name);
|
|
DBUG_PRINT ("srec", ("%lx %lx %s", fn_sbot, fn_ssz, fn_name));
|
|
pos = add (fn_name);
|
|
lastuse = modules[pos].m_stkuse;
|
|
#if 0
|
|
/*
|
|
* Needs further thought. Stack use is determined by
|
|
* difference in stack between two functions with DBUG_ENTER
|
|
* macros. If A calls B calls C, where A and C have the
|
|
* macros, and B doesn't, then B's stack use will be lumped
|
|
* in with either A's or C's. If somewhere else A calls
|
|
* C directly, the stack use will seem to change. Just
|
|
* take the biggest for now...
|
|
*/
|
|
if (lastuse > 0 && lastuse != fn_ssz) {
|
|
fprintf (stderr,
|
|
"warning - %s stack use changed (%lx to %lx)\n",
|
|
fn_name, lastuse, fn_ssz);
|
|
}
|
|
#endif
|
|
if (fn_ssz > lastuse) {
|
|
modules[pos].m_stkuse = fn_ssz;
|
|
}
|
|
if (fn_sbot > highstack) {
|
|
highstack = fn_sbot;
|
|
} else if (fn_sbot < lowstack) {
|
|
lowstack = fn_sbot;
|
|
}
|
|
break;
|
|
default:
|
|
fprintf (stderr, "unknown record type '%c'\n", buf[0]);
|
|
break;
|
|
}
|
|
next_line:;
|
|
}
|
|
|
|
/*
|
|
* Now, we've hit eof. If we still have stuff stacked, then we
|
|
* assume that the user called exit, so give everything the exited
|
|
* time of fn_time.
|
|
*/
|
|
while (pop (&oldpos,&oldtime,&oldchild)) {
|
|
local_time = fn_time - oldtime;
|
|
t = top ();
|
|
t -> children += local_time;
|
|
local_time -= oldchild;
|
|
modules[oldpos].m_time += local_time;
|
|
modules[oldpos].m_calls++;
|
|
tot_time += local_time;
|
|
tot_calls++;
|
|
}
|
|
DBUG_VOID_RETURN;
|
|
}
|
|
|
|
/*
|
|
* out_header () -- print out the header of the report.
|
|
*/
|
|
|
|
void out_header (outf)
|
|
FILE *outf;
|
|
{
|
|
DBUG_ENTER ("out_header");
|
|
if (verbose) {
|
|
fprintf (outf, "Profile of Execution\n");
|
|
fprintf (outf, "Execution times are in milliseconds\n\n");
|
|
fprintf (outf, " Calls\t\t\t Time\n");
|
|
fprintf (outf, " -----\t\t\t ----\n");
|
|
fprintf (outf, "Times\tPercentage\tTime Spent\tPercentage\n");
|
|
fprintf (outf, "Called\tof total\tin Function\tof total Importance\tFunction\n");
|
|
fprintf (outf, "======\t==========\t===========\t========== ==========\t========\t\n");
|
|
} else {
|
|
fprintf (outf, "%ld bytes of stack used, from %lx down to %lx\n\n",
|
|
highstack - lowstack, highstack, lowstack);
|
|
fprintf (outf,
|
|
" %%time sec #call ms/call %%calls weight stack name\n");
|
|
}
|
|
DBUG_VOID_RETURN;
|
|
}
|
|
|
|
/*
|
|
* out_trailer () - writes out the summary line of the report.
|
|
*/
|
|
|
|
void out_trailer (outf,sum_calls,sum_time)
|
|
FILE *outf;
|
|
unsigned long int sum_calls, sum_time;
|
|
{
|
|
DBUG_ENTER ("out_trailer");
|
|
if (verbose)
|
|
{
|
|
fprintf(outf, "======\t==========\t===========\t==========\t========\n");
|
|
fprintf(outf, "%6ld\t%10.2f\t%11ld\t%10.2f\t\t%-15s\n",
|
|
sum_calls, 100.0, sum_time, 100.0, "Totals");
|
|
}
|
|
DBUG_VOID_RETURN;
|
|
}
|
|
|
|
/*
|
|
* out_item () - prints out the output line for a single entry,
|
|
* and sets the calls and time fields appropriately.
|
|
*/
|
|
|
|
void out_item (outf, m,called,timed)
|
|
FILE *outf;
|
|
register struct module_t *m;
|
|
unsigned long int *called, *timed;
|
|
{
|
|
char *name = m -> name;
|
|
register unsigned int calls = m -> m_calls;
|
|
register unsigned long local_time = m -> m_time;
|
|
register unsigned long stkuse = m -> m_stkuse;
|
|
unsigned int import;
|
|
double per_time = 0.0;
|
|
double per_calls = 0.0;
|
|
double ms_per_call, local_ftime;
|
|
|
|
DBUG_ENTER ("out_item");
|
|
|
|
if (tot_time > 0) {
|
|
per_time = (double) (local_time * 100) / (double) tot_time;
|
|
}
|
|
if (tot_calls > 0) {
|
|
per_calls = (double) (calls * 100) / (double) tot_calls;
|
|
}
|
|
import = (unsigned int) (per_time * per_calls);
|
|
|
|
if (verbose) {
|
|
fprintf (outf, "%6d\t%10.2f\t%11ld\t%10.2f %10d\t%-15s\n",
|
|
calls, per_calls, local_time, per_time, import, name);
|
|
} else {
|
|
ms_per_call = local_time;
|
|
ms_per_call /= calls;
|
|
local_ftime = local_time;
|
|
local_ftime /= 1000;
|
|
fprintf(outf, "%8.2f%8.3f%8u%8.3f%8.2f%8u%8lu %-s\n",
|
|
per_time, local_ftime, calls, ms_per_call, per_calls, import,
|
|
stkuse, name);
|
|
}
|
|
*called = calls;
|
|
*timed = local_time;
|
|
DBUG_VOID_RETURN;
|
|
}
|
|
|
|
/*
|
|
* out_body (outf, root,s_calls,s_time) -- Performs an inorder traversal
|
|
* on the binary search tree (root). Calls out_item to actually print
|
|
* the item out.
|
|
*/
|
|
|
|
void out_body (outf, root,s_calls,s_time)
|
|
FILE *outf;
|
|
register unsigned int root;
|
|
register unsigned long int *s_calls, *s_time;
|
|
{
|
|
unsigned long int calls, local_time;
|
|
|
|
DBUG_ENTER ("out_body");
|
|
DBUG_PRINT ("out_body", ("%lu,%lu",*s_calls,*s_time));
|
|
if (root == MAXPROCS) {
|
|
DBUG_PRINT ("out_body", ("%lu,%lu",*s_calls,*s_time));
|
|
} else {
|
|
while (root != MAXPROCS) {
|
|
out_body (outf, s_table[root].lchild,s_calls,s_time);
|
|
out_item (outf, &modules[s_table[root].pos],&calls,&local_time);
|
|
DBUG_PRINT ("out_body", ("-- %lu -- %lu --", calls, local_time));
|
|
*s_calls += calls;
|
|
*s_time += local_time;
|
|
root = s_table[root].rchild;
|
|
}
|
|
DBUG_PRINT ("out_body", ("%lu,%lu", *s_calls, *s_time));
|
|
}
|
|
DBUG_VOID_RETURN;
|
|
}
|
|
|
|
/*
|
|
* output () - print out a nice sorted output report on outf.
|
|
*/
|
|
|
|
void output (outf)
|
|
FILE *outf;
|
|
{
|
|
unsigned long int sum_calls = 0;
|
|
unsigned long int sum_time = 0;
|
|
|
|
DBUG_ENTER ("output");
|
|
if (n_items == 0) {
|
|
fprintf (outf, "%s: No functions to trace\n", my_name);
|
|
exit (EX_DATAERR);
|
|
}
|
|
out_header (outf);
|
|
out_body (outf, 0,&sum_calls,&sum_time);
|
|
out_trailer (outf, sum_calls,sum_time);
|
|
DBUG_VOID_RETURN;
|
|
}
|
|
|
|
|
|
#define usage() fprintf (DBUG_FILE,"Usage: %s [-v] [prof-file]\n",my_name)
|
|
|
|
#ifdef MSDOS
|
|
extern int getopt(int argc, char **argv, char *opts);
|
|
#endif
|
|
extern int optind;
|
|
extern char *optarg;
|
|
|
|
int main (int argc, char **argv)
|
|
{
|
|
register int c;
|
|
int badflg = 0;
|
|
FILE *infile;
|
|
FILE *outfile = {stdout};
|
|
|
|
#if defined(HAVE_PTHREAD_INIT) && defined(THREAD)
|
|
pthread_init(); /* Must be called before DBUG_ENTER */
|
|
#endif
|
|
my_thread_global_init();
|
|
{
|
|
DBUG_ENTER ("main");
|
|
DBUG_PROCESS (argv[0]);
|
|
my_name = argv[0];
|
|
while ((c = getopt (argc,argv,"#:v")) != EOF) {
|
|
switch (c) {
|
|
case '#': /* Debugging Macro enable */
|
|
DBUG_PUSH (optarg);
|
|
break;
|
|
case 'v': /* Verbose mode */
|
|
verbose++;
|
|
break;
|
|
default:
|
|
badflg++;
|
|
break;
|
|
}
|
|
}
|
|
if (badflg) {
|
|
usage ();
|
|
DBUG_RETURN (EX_USAGE);
|
|
}
|
|
if (optind < argc) {
|
|
FILEOPEN (infile, argv[optind], "r");
|
|
} else {
|
|
FILEOPEN (infile, PRO_FILE, "r");
|
|
}
|
|
process (infile);
|
|
output (outfile);
|
|
DBUG_RETURN (EX_OK);
|
|
}
|
|
}
|
|
|
|
#ifdef MSDOS
|
|
|
|
/*
|
|
* From std-unix@ut-sally.UUCP (Moderator, John Quarterman) Sun Nov 3 14:34:15 1985
|
|
* Relay-Version: version B 2.10.3 4.3bsd-beta 6/6/85; site gatech.CSNET
|
|
* Posting-Version: version B 2.10.2 9/18/84; site ut-sally.UUCP
|
|
* Path: gatech!akgua!mhuxv!mhuxt!mhuxr!ulysses!allegra!mit-eddie!genrad!panda!talcott!harvard!seismo!ut-sally!std-unix
|
|
* From: std-unix@ut-sally.UUCP (Moderator, John Quarterman)
|
|
* Newsgroups: mod.std.unix
|
|
* Subject: public domain AT&T getopt source
|
|
* Message-ID: <3352@ut-sally.UUCP>
|
|
* Date: 3 Nov 85 19:34:15 GMT
|
|
* Date-Received: 4 Nov 85 12:25:09 GMT
|
|
* Organization: IEEE/P1003 Portable Operating System Environment Committee
|
|
* Lines: 91
|
|
* Approved: jsq@ut-sally.UUCP
|
|
*
|
|
* Here's something you've all been waiting for: the AT&T public domain
|
|
* source for getopt(3). It is the code which was given out at the 1985
|
|
* UNIFORUM conference in Dallas. I obtained it by electronic mail
|
|
* directly from AT&T. The people there assure me that it is indeed
|
|
* in the public domain.
|
|
*
|
|
* There is no manual page. That is because the one they gave out at
|
|
* UNIFORUM was slightly different from the current System V Release 2
|
|
* manual page. The difference apparently involved a note about the
|
|
* famous rules 5 and 6, recommending using white space between an option
|
|
* and its first argument, and not grouping options that have arguments.
|
|
* Getopt itself is currently lenient about both of these things White
|
|
* space is allowed, but not mandatory, and the last option in a group can
|
|
* have an argument. That particular version of the man page evidently
|
|
* has no official existence, and my source at AT&T did not send a copy.
|
|
* The current SVR2 man page reflects the actual behavor of this getopt.
|
|
* However, I am not about to post a copy of anything licensed by AT&T.
|
|
*
|
|
* I will submit this source to Berkeley as a bug fix.
|
|
*
|
|
* I, personally, make no claims or guarantees of any kind about the
|
|
* following source. I did compile it to get some confidence that
|
|
* it arrived whole, but beyond that you're on your own.
|
|
*
|
|
*/
|
|
|
|
/*LINTLIBRARY*/
|
|
|
|
int opterr = 1;
|
|
int optind = 1;
|
|
int optopt;
|
|
char *optarg;
|
|
|
|
static void _ERR(s,c,argv)
|
|
char *s;
|
|
int c;
|
|
char *argv[];
|
|
{
|
|
char errbuf[3];
|
|
|
|
if (opterr) {
|
|
errbuf[0] = c;
|
|
errbuf[1] = '\n';
|
|
(void) fprintf(stderr, "%s", argv[0]);
|
|
(void) fprintf(stderr, "%s", s);
|
|
(void) fprintf(stderr, "%s", errbuf);
|
|
}
|
|
}
|
|
|
|
int getopt(argc, argv, opts)
|
|
int argc;
|
|
char **argv, *opts;
|
|
{
|
|
static int sp = 1;
|
|
register int c;
|
|
register char *cp;
|
|
|
|
if(sp == 1)
|
|
if(optind >= argc ||
|
|
argv[optind][0] != '-' || argv[optind][1] == '\0')
|
|
return(EOF);
|
|
else if(strcmp(argv[optind], "--") == 0) {
|
|
optind++;
|
|
return(EOF);
|
|
}
|
|
optopt = c = argv[optind][sp];
|
|
if(c == ':' || (cp=strchr(opts, c)) == NULL) {
|
|
_ERR(": illegal option -- ", c, argv);
|
|
if(argv[optind][++sp] == '\0') {
|
|
optind++;
|
|
sp = 1;
|
|
}
|
|
return('?');
|
|
}
|
|
if(*++cp == ':') {
|
|
if(argv[optind][sp+1] != '\0')
|
|
optarg = &argv[optind++][sp+1];
|
|
else if(++optind >= argc) {
|
|
_ERR(": option requires an argument -- ", c, argv);
|
|
sp = 1;
|
|
return('?');
|
|
} else
|
|
optarg = argv[optind++];
|
|
sp = 1;
|
|
} else {
|
|
if(argv[optind][++sp] == '\0') {
|
|
sp = 1;
|
|
optind++;
|
|
}
|
|
optarg = NULL;
|
|
}
|
|
return(c);
|
|
}
|
|
|
|
#endif /* !unix && !xenix */
|