1 #ifndef INC_PROFILER_LOWLEVEL_H 2 #define INC_PROFILER_LOWLEVEL_H 3 4 #ifdef __cplusplus 5 #define Prof_C "C" 6 #define Prof_extern_C extern "C" 7 #define Prof_dummy_declare 8 #else 9 #define Prof_C 10 #define Prof_extern_C 11 #define Prof_dummy_declare int Prof_dummy_dec = 12 #endif 13 14 #ifdef WIN32 15 #include "prof_win32.h" 16 #else 17 #error "need to define Prof_get_timestamp() and Prof_Int64" 18 #endif 19 20 21 typedef struct 22 { 23 char * name; 24 void * highlevel; 25 char initialized; 26 char visited; 27 char pad0,pad1; 28 } Prof_Zone; 29 30 typedef struct Prof_Zone_Stack 31 { 32 Prof_Int64 t_self_start; 33 34 Prof_Int64 total_self_ticks; 35 Prof_Int64 total_hier_ticks; 36 37 unsigned int total_entry_count; 38 39 struct Prof_Zone_Stack * parent; 40 Prof_Zone * zone; 41 int recursion_depth; 42 43 void * highlevel; 44 } Prof_Zone_Stack; 45 46 47 extern Prof_C Prof_Zone_Stack * Prof_stack; // current Zone stack 48 extern Prof_C Prof_Zone_Stack Prof_dummy; // parent never matches 49 50 extern Prof_C Prof_Zone_Stack * Prof_StackAppend(Prof_Zone *zone); 51 // return the zone stack created by pushing 'zone' on the current 52 53 54 #ifdef Prof_ENABLED 55 56 static Prof_Int64 Prof_time; 57 58 #define Prof_Begin_Cache(z) \ 59 /* declare a static cache of the zone stack */ \ 60 static Prof_Zone_Stack *Prof_cache = &Prof_dummy 61 62 #define Prof_Begin_Raw(z) \ 63 Prof_Begin_Cache(z); \ 64 Prof_Begin_Code(z) 65 66 #define Prof_Begin_Code(z) \ 67 Prof_dummy_declare ( \ 68 \ 69 /* check the cached Zone_Stack and update if needed */ \ 70 (Prof_cache->parent != Prof_stack \ 71 ? Prof_cache = Prof_StackAppend(&z) \ 72 : 0), \ 73 \ 74 ++Prof_cache->total_entry_count, \ 75 Prof_get_timestamp(&Prof_time), \ 76 \ 77 /* stop the timer on the parent zone stack */ \ 78 (Prof_stack->total_self_ticks += \ 79 Prof_time - Prof_stack->t_self_start), \ 80 \ 81 /* make cached stack current */ \ 82 Prof_stack = Prof_cache, \ 83 \ 84 /* start the timer on this stack */ \ 85 Prof_stack->t_self_start = Prof_time, \ 86 0) 87 88 #define Prof_End_Raw() \ 89 \ 90 (Prof_get_timestamp(&Prof_time), \ 91 \ 92 /* stop timer for current zone stack */ \ 93 Prof_stack->total_self_ticks += \ 94 Prof_time - Prof_stack->t_self_start, \ 95 \ 96 /* make parent chain current */ \ 97 Prof_stack = Prof_stack->parent, \ 98 \ 99 /* start timer for parent zone stack */ \ 100 Prof_stack->t_self_start = Prof_time) 101 102 103 #define Prof_Declare(z) Prof_Zone Prof_region_##z 104 #define Prof_Define(z) Prof_Declare(z) = { #z } 105 #define Prof_Region(z) Prof_Begin_Raw(Prof_region_##z); 106 #define Prof_End Prof_End_Raw(); 107 108 #define Prof_Begin(z) static Prof_Define(z); Prof_Region(z) 109 #define Prof_Counter(z) Prof_Begin(z) Prof_End 110 111 #ifdef __cplusplus 112 113 #define Prof(x) static Prof_Define(x); Prof_Scope(x) 114 115 #define Prof_Scope(x) \ 116 Prof_Begin_Cache(x); \ 117 Prof_Scope_Var Prof_scope_var(Prof_region_ ## x, Prof_cache) 118 119 struct Prof_Scope_Var { 120 inline Prof_Scope_Var(Prof_Zone &zone, Prof_Zone_Stack * &Prof_cache); 121 inline ~Prof_Scope_Var(); 122 }; 123 Prof_Scope_Var(Prof_Zone & zone,Prof_Zone_Stack * & Prof_cache)124 inline Prof_Scope_Var::Prof_Scope_Var(Prof_Zone &zone, Prof_Zone_Stack * &Prof_cache) { 125 Prof_Begin_Code(zone); 126 } 127 ~Prof_Scope_Var()128 inline Prof_Scope_Var::~Prof_Scope_Var() { 129 Prof_End_Raw(); 130 } 131 132 #endif 133 134 135 136 #else // ifdef Prof_ENABLED 137 138 #ifdef __cplusplus 139 #define Prof(x) 140 #define Prof_Scope(x) 141 #endif 142 143 #define Prof_Define(name) 144 #define Prof_Begin(z) 145 #define Prof_End 146 #define Prof_Region(z) 147 #define Prof_Counter(z) 148 149 #endif 150 151 #endif // INC_PROFILER_LOWLEVEL_H 152 153