cpp: Use #pragma once instead of #ifndef guards
[ghc.git] / includes / rts / prof / CCS.h
1 /* -----------------------------------------------------------------------------
2 *
3 * (c) The GHC Team, 2009-2012
4 *
5 * Macros for profiling operations in STG code
6 *
7 * Do not #include this file directly: #include "Rts.h" instead.
8 *
9 * To understand the structure of the RTS headers, see the wiki:
10 * http://ghc.haskell.org/trac/ghc/wiki/Commentary/SourceTree/Includes
11 *
12 * ---------------------------------------------------------------------------*/
13
14 #pragma once
15
16 /* -----------------------------------------------------------------------------
17 * Data Structures
18 * ---------------------------------------------------------------------------*/
19 /*
20 * Note [struct alignment]
21 * NB. be careful to avoid unwanted padding between fields, by
22 * putting the 8-byte fields on an 8-byte boundary. Padding can
23 * vary between C compilers, and we don't take into account any
24 * possible padding when generating CCS and CC decls in the code
25 * generator (compiler/codeGen/StgCmmProf.hs).
26 */
27
28 typedef struct CostCentre_ {
29 StgInt ccID; // Unique Id, allocated by the RTS
30
31 char * label;
32 char * module;
33 char * srcloc;
34
35 // used for accumulating costs at the end of the run...
36 StgWord64 mem_alloc; // align 8 (Note [struct alignment])
37 StgWord time_ticks;
38
39 StgInt is_caf; // non-zero for a CAF cost centre
40
41 struct CostCentre_ *link;
42 } CostCentre;
43
44 typedef struct CostCentreStack_ {
45 StgInt ccsID; // unique ID, allocated by the RTS
46
47 CostCentre *cc; // Cost centre at the top of the stack
48
49 struct CostCentreStack_ *prevStack; // parent
50 struct IndexTable_ *indexTable; // children
51 struct CostCentreStack_ *root; // root of stack
52 StgWord depth; // number of items in the stack
53
54 StgWord64 scc_count; // Count of times this CCS is entered
55 // align 8 (Note [struct alignment])
56
57 StgWord selected; // is this CCS shown in the heap
58 // profile? (zero if excluded via -hc
59 // -hm etc.)
60
61 StgWord time_ticks; // number of time ticks accumulated by
62 // this CCS
63
64 StgWord64 mem_alloc; // mem allocated by this CCS
65 // align 8 (Note [struct alignment])
66
67 StgWord64 inherited_alloc; // sum of mem_alloc over all children
68 // (calculated at the end)
69 // align 8 (Note [struct alignment])
70
71 StgWord inherited_ticks; // sum of time_ticks over all children
72 // (calculated at the end)
73 } CostCentreStack;
74
75
76 /* -----------------------------------------------------------------------------
77 * Start and stop the profiling timer. These can be called from
78 * Haskell to restrict the profile to portion(s) of the execution.
79 * See the module GHC.Profiling.
80 * ---------------------------------------------------------------------------*/
81
82 void stopProfTimer ( void );
83 void startProfTimer ( void );
84
85 /* -----------------------------------------------------------------------------
86 * The rest is PROFILING only...
87 * ---------------------------------------------------------------------------*/
88
89 #if defined(PROFILING)
90
91 /* -----------------------------------------------------------------------------
92 * Constants
93 * ---------------------------------------------------------------------------*/
94
95 #define EMPTY_STACK NULL
96 #define EMPTY_TABLE NULL
97
98 /* Constants used to set is_caf flag on CostCentres */
99 #define CC_IS_CAF 'c' /* 'c' => *is* a CAF cc */
100 #define CC_NOT_CAF 0
101
102 /* -----------------------------------------------------------------------------
103 * Data Structures
104 * ---------------------------------------------------------------------------*/
105
106 // IndexTable is the list of children of a CCS. (Alternatively it is a
107 // cache of the results of pushing onto a CCS, so that the second and
108 // subsequent times we push a certain CC on a CCS we get the same
109 // result).
110
111 typedef struct IndexTable_ {
112 CostCentre *cc;
113 CostCentreStack *ccs;
114 struct IndexTable_ *next;
115 uint32_t back_edge;
116 } IndexTable;
117
118
119 /* -----------------------------------------------------------------------------
120 Pre-defined cost centres and cost centre stacks
121 -------------------------------------------------------------------------- */
122
123 #if IN_STG_CODE
124
125 extern StgWord CC_MAIN[];
126 extern StgWord CCS_MAIN[]; // Top CCS
127
128 extern StgWord CC_SYSTEM[];
129 extern StgWord CCS_SYSTEM[]; // RTS costs
130
131 extern StgWord CC_GC[];
132 extern StgWord CCS_GC[]; // Garbage collector costs
133
134 extern StgWord CC_OVERHEAD[];
135 extern StgWord CCS_OVERHEAD[]; // Profiling overhead
136
137 extern StgWord CC_DONT_CARE[];
138 extern StgWord CCS_DONT_CARE[]; // CCS attached to static constructors
139
140 #else
141
142 extern CostCentre CC_MAIN[];
143 extern CostCentreStack CCS_MAIN[]; // Top CCS
144
145 extern CostCentre CC_SYSTEM[];
146 extern CostCentreStack CCS_SYSTEM[]; // RTS costs
147
148 extern CostCentre CC_GC[];
149 extern CostCentreStack CCS_GC[]; // Garbage collector costs
150
151 extern CostCentre CC_OVERHEAD[];
152 extern CostCentreStack CCS_OVERHEAD[]; // Profiling overhead
153
154 extern CostCentre CC_DONT_CARE[];
155 extern CostCentreStack CCS_DONT_CARE[]; // shouldn't ever get set
156
157 extern CostCentre CC_PINNED[];
158 extern CostCentreStack CCS_PINNED[]; // pinned memory
159
160 extern CostCentre CC_IDLE[];
161 extern CostCentreStack CCS_IDLE[]; // capability is idle
162
163 #endif /* IN_STG_CODE */
164
165 extern unsigned int RTS_VAR(CC_ID); // global ids
166 extern unsigned int RTS_VAR(CCS_ID);
167
168 extern unsigned int RTS_VAR(era);
169
170 /* -----------------------------------------------------------------------------
171 * Functions
172 * ---------------------------------------------------------------------------*/
173
174 CostCentreStack * pushCostCentre (CostCentreStack *, CostCentre *);
175 void enterFunCCS (StgRegTable *reg, CostCentreStack *);
176 CostCentre *mkCostCentre (char *label, char *module, char *srcloc);
177
178 /* -----------------------------------------------------------------------------
179 Registering CCs and CCSs
180
181 Registering a CC or CCS consists of
182 - assigning it a unique ID
183 - linking it onto the list of registered CCs/CCSs
184
185 Cost centres are registered at startup by a C constructor function
186 generated by the compiler in the _stub.c file for each module. The
187 macros below are invoked by that C code to register CCs and CCSs.
188 -------------------------------------------------------------------------- */
189
190 extern CostCentre * RTS_VAR(CC_LIST); // registered CC list
191 extern CostCentreStack * RTS_VAR(CCS_LIST); // registered CCS list
192
193 #define REGISTER_CC(cc) \
194 do { \
195 if ((cc)->link == (CostCentre *)0) { \
196 (cc)->link = CC_LIST; \
197 CC_LIST = (cc); \
198 (cc)->ccID = CC_ID++; \
199 }} while(0)
200
201 #define REGISTER_CCS(ccs) \
202 do { \
203 if ((ccs)->prevStack == (CostCentreStack *)0) { \
204 (ccs)->prevStack = CCS_LIST; \
205 CCS_LIST = (ccs); \
206 (ccs)->ccsID = CCS_ID++; \
207 }} while(0)
208
209 /* -----------------------------------------------------------------------------
210 * Declaring Cost Centres & Cost Centre Stacks.
211 * -------------------------------------------------------------------------- */
212
213 # define CC_DECLARE(cc_ident,name,mod,loc,caf,is_local) \
214 is_local CostCentre cc_ident[1] \
215 = {{ .ccID = 0, \
216 .label = name, \
217 .module = mod, \
218 .srcloc = loc, \
219 .time_ticks = 0, \
220 .mem_alloc = 0, \
221 .link = 0, \
222 .is_caf = caf \
223 }};
224
225 # define CCS_DECLARE(ccs_ident,cc_ident,is_local) \
226 is_local CostCentreStack ccs_ident[1] \
227 = {{ .ccsID = 0, \
228 .cc = cc_ident, \
229 .prevStack = NULL, \
230 .indexTable = NULL, \
231 .root = NULL, \
232 .depth = 0, \
233 .selected = 0, \
234 .scc_count = 0, \
235 .time_ticks = 0, \
236 .mem_alloc = 0, \
237 .inherited_ticks = 0, \
238 .inherited_alloc = 0 \
239 }};
240
241 /* -----------------------------------------------------------------------------
242 * Time / Allocation Macros
243 * ---------------------------------------------------------------------------*/
244
245 /* eliminate profiling overhead from allocation costs */
246 #define CCS_ALLOC(ccs, size) (ccs)->mem_alloc += ((size)-sizeofW(StgProfHeader))
247 #define ENTER_CCS_THUNK(cap,p) cap->r.rCCCS = p->header.prof.ccs
248
249 #else /* !PROFILING */
250
251 #define CCS_ALLOC(ccs, amount) doNothing()
252 #define ENTER_CCS_THUNK(cap,p) doNothing()
253
254 #endif /* PROFILING */