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