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