diff --git a/lib_com/control.c b/lib_com/control.c index 20865de23788f218d0022257b64fe0a2d8c35ad6..f4b089a4ac62fe88c8d841acb5afe4f936dc67ef 100644 --- a/lib_com/control.c +++ b/lib_com/control.c @@ -20,6 +20,8 @@ #include "stl.h" +#define WMC_TOOL_SKIP + #ifdef WMOPS int funcId_where_last_call_to_else_occurred; long funcid_total_wmops_at_last_call_to_else; diff --git a/lib_com/count.c b/lib_com/count.c index eaf6f04f422786a7f67642b6e3bfca292eb2afde..55a2b86377dcd0d48090eae530bdf9f8867b0885 100644 --- a/lib_com/count.c +++ b/lib_com/count.c @@ -104,6 +104,9 @@ void setFrameRate( int samplingFreq, int frameLength ) return; } +#ifdef SUPPORT_WMOPS_DETAIL +int lookup_table[MAX_HASH_TABLE_SIZE]; +#endif /* * Below list is used for displaying the code profiling information in @@ -256,8 +259,11 @@ static char *objectName[MAXCOUNTERS + 1]; static Word16 fwc_corr[MAXCOUNTERS + 1]; static long int nbTimeObjectIsCalled[MAXCOUNTERS + 1]; - +#ifdef SUPPORT_WMOPS_DETAIL +#define NbFuncMax ( 80000 ) /* may need to be increased if the total number of function calls exceeds the limit */ +#else #define NbFuncMax ( 4096 ) +#endif /** @@ -322,6 +328,20 @@ static char *my_strdup( const char *s ) return strcpy( dup, s ); } + +#ifdef SUPPORT_WMOPS_DETAIL +int calc_hash( const char *str ) +{ + /* A simple hash function (might be good to replace with a better one) */ + int hash_value = 0; + for ( int i = 0; str[i]; i++ ) + { + hash_value += str[i]; + } + return hash_value % MAX_HASH_TABLE_SIZE; +} +#endif + #endif /* ifdef WMOPS */ @@ -426,7 +446,7 @@ static Word32 WMOPS_frameStat( void ) #ifdef WMOPS static void WMOPS_clearMultiCounter( void ) { - Word16 i; + Word32 i; Word32 *ptr = (Word32 *) &multiCounter[currCounter]; for ( i = 0; i < (Word16) ( sizeof( multiCounter[currCounter] ) / sizeof( Word32 ) ); i++ ) @@ -440,7 +460,7 @@ static void WMOPS_clearMultiCounter( void ) void ClearNbTimeObjectsAreCalled() { #ifdef WMOPS - Word16 i; + Word32 i; for ( i = 0; i < (Word16) ( sizeof( multiCounter[currCounter] ) / sizeof( Word32 ) ); i++ ) { @@ -452,7 +472,7 @@ void ClearNbTimeObjectsAreCalled() Word32 TotalWeightedOperation() { #ifdef WMOPS - Word16 i; + Word32 i; Word32 tot, *ptr; const Word32 *ptr2; @@ -492,7 +512,7 @@ Word32 DeltaWeightedOperation() void Init_WMOPS_counter( void ) { #ifdef WMOPS - Word16 i; + Word32 i; /* reset function weight operation counter variable */ @@ -591,7 +611,7 @@ Word32 fwc( void ) void WMOPS_output( Word16 dtx_mode ) { #ifdef WMOPS - Word16 i; + Word32 i; Word32 tot, tot_wm, tot_wc; /* get operations since last reset (or init), but do not update the counters (except the glob_wc[] maximum) @@ -626,7 +646,7 @@ void WMOPS_output( Word16 dtx_mode ) void WMOPS_output_avg( Word16 dtx_mode, Word32 *tot_wm, Word32 *num_frames ) { #ifdef WMOPS - Word16 i; + Word32 i; Word32 tot, tot_wc; /* get operations since last reset (or init), but do not update the counters (except the glob_wc[] maximum) @@ -663,7 +683,7 @@ void generic_WMOPS_output( Word16 dtx_mode, char *test_file_name ) { #ifdef WMOPS int saved_value; - Word16 i; + Word32 i; Word32 tot, tot_wm, tot_wc, *ptr; const Word32 *ptr2; Word40 grand_total; @@ -952,9 +972,40 @@ void printStack( char *text, char *Id ) #ifdef WMOPS void BASOP_push_wmops( const char *label ) { - int new_flag, prev_counter; + int prev_counter; int i, j; +#ifdef SUPPORT_WMOPS_DETAIL + int label_hash; + label_hash = calc_hash( label ); + + /* check, if string matches (get new entry, if not) */ + i = lookup_table[label_hash]; + while ( i != -1 && strcmp( objectName[i], label ) != 0 ) + { + i = lookup_table[++label_hash]; + } + + prev_counter = readCounterId(); + + if ( i == -1 ) + { + /* create new entry */ + i = (int) getCounterId( label ); + lookup_table[label_hash] = i; + + setCounter( maxCounter ); + Init_WMOPS_counter(); + } + else + { + setCounter( i ); + } + +#else + + int new_flag; + /* Check if new counter label */ new_flag = 1; for ( i = 1; i <= maxCounter; i++ ) @@ -979,7 +1030,7 @@ void BASOP_push_wmops( const char *label ) { setCounter( i ); } - +#endif /* Push current context onto stack */ if ( currCounter >= 0 ) @@ -1280,8 +1331,8 @@ void WMOPS_output_all_std( Word16 dtx_mode ) ( glob_bc[i] == MAX_32 ) ? 0 : frameRate * (float) glob_bc[i], ( glob_wc[i] == 0 ) ? 0 : frameRate * (float) glob_wc[i], ( nbframe[i] == 0 ) ? 0 : (float) total_wmops[i] / (float) nbframe[i], - frameRate * ( glob_sum_bc[i] ), - frameRate * ( glob_sum_wc[i] ), + ( glob_sum_bc[i] == MAX_32 ) ? 0 : frameRate * ( glob_sum_bc[i] ), + ( glob_sum_wc[i] == 0 ) ? 0 : frameRate * ( glob_sum_wc[i] ), ( nbframe[i] == 0 ) ? 0 : (float) ( ( total_sum[i] ) / (float) nbframe[i] ) ); /* frameRate*(glob_bc[i]+wmops_children_bc[i]), */ /* frameRate*(glob_wc[i]+wmops_children_wc[i]), */ diff --git a/lib_com/count.h b/lib_com/count.h index 10e96e44fad77b519fa544389b64623cad14b4be..94daad27d0b9118e445df06ca13498c1e888ea4c 100644 --- a/lib_com/count.h +++ b/lib_com/count.h @@ -62,8 +62,14 @@ #include - +#ifdef SUPPORT_WMOPS_DETAIL +#define MAX_HASH_TABLE_SIZE 1000000 /* may need to be increased if there are too many conflicts in calc_hash() */ +extern int lookup_table[]; +int calc_hash( const char *str ); +#define MAXCOUNTERS ( 1024 ) /* may need to be increased if the total number of instrumented functions exceeds the limit */ +#else #define MAXCOUNTERS ( 512 ) +#endif #define MAX_CALLERS_SAVED_FRAMES 5 /* # of Frame for which WMOPS Complexity Details will be saved, 0 = Disabled */ int getCounterId( const char *objectName ); diff --git a/lib_com/options.h b/lib_com/options.h index 095c183e8756b680cea7bdb5c9b5afa00ae4df88..504b5f986948796dacefd16a671358be624e64f8 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -54,10 +54,15 @@ #define SUPPORT_JBM_TRACEFILE /* Support for JBM tracefile, which is needed for 3GPP objective/subjective testing, but not relevant for real-world implementations */ -/*#define WMOPS*/ /* Activate complexity and memory counters */ +#define SUPPORT_WMOPS_DETAIL /* VA: Add WMOPS_DETAIL to allow automatic instrumentation of all functions for detailed complexity measurements */ + +#define WMOPS /* Activate complexity and memory counters */ #ifdef WMOPS /*#define WMOPS_PER_FRAME*/ /* Output per-frame complexity (writes one float value per frame to the file "wmops_analysis") */ /*#define MEM_COUNT_DETAILS*/ /* Output detailed memory analysis for the worst-case frame (writes to the file "mem_analysis.csv") */ +#ifdef SUPPORT_WMOPS_DETAIL +/*#define WMOPS_DETAIL*/ /* Output detailed complexity printout for every function. Increases runtime overhead */ +#endif #endif /* #################### End DEBUGGING switches ############################ */ diff --git a/lib_debug/wmc_auto.c b/lib_debug/wmc_auto.c index e37fecf2ebdec6b1fead6dccf0df4e8ff5bc321c..5add9c518b74ae7cd14d5ceeaf077b627939fbd0 100644 --- a/lib_debug/wmc_auto.c +++ b/lib_debug/wmc_auto.c @@ -131,6 +131,11 @@ void reset_wmops( void ) BASOP_init + for ( i = 0; i < MAX_HASH_TABLE_SIZE; i++ ) + { + lookup_table[i] = -1; + } + /* initilize the list of WMOPS records */ /* initilize the BASOP WMOPS counters */ for ( i = 0; i < max_num_wmops_records; i++ ) diff --git a/lib_debug/wmc_auto.h b/lib_debug/wmc_auto.h index 5f5d6d9753f98612762f47dca560f63c7b22ddd6..0acd223b3d2199da3f155945a90259d68a5db8d0 100644 --- a/lib_debug/wmc_auto.h +++ b/lib_debug/wmc_auto.h @@ -1024,11 +1024,11 @@ int push_stack( const char *filename, const char *fctname ); int pop_stack( const char *filename, const char *fctname ); #ifdef WMOPS_DETAIL -#define STACK_DEPTH_FCT_CALL ( push_wmops( __FUNCTION__ ), push_stack( __FILE__, __FUNCTION__ ) ) /* add push_wmops() in all function calls */ -#define STACK_DEPTH_FCT_RETURN ( pop_wmops(), pop_stack( __FILE__, __FUNCTION__ ) ) /* add pop_wmops() in all function returns */ +#define STACK_DEPTH_FCT_CALL ( push_wmops( __func__, "[WMC_AUTO]" ), push_stack( __FILE__, __func__ ) ) /* add push_wmops() in all function calls */ +#define STACK_DEPTH_FCT_RETURN ( pop_wmops(), pop_stack( __FILE__, __func__ ) ) /* add pop_wmops() in all function returns */ #else -#define STACK_DEPTH_FCT_CALL push_stack( __FILE__, __FUNCTION__ ) -#define STACK_DEPTH_FCT_RETURN pop_stack( __FILE__, __FUNCTION__ ) +#define STACK_DEPTH_FCT_CALL push_stack( __FILE__, __func__ ) +#define STACK_DEPTH_FCT_RETURN pop_stack( __FILE__, __func__ ) #endif void reset_stack( void );