Documentation and refactoring in CCS related code
[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 StgBool is_caf; // true <=> 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 true
100 #define CC_NOT_CAF false
101 /* -----------------------------------------------------------------------------
102 * Data Structures
103 * ---------------------------------------------------------------------------*/
104
105 // IndexTable is the list of children of a CCS. (Alternatively it is a
106 // cache of the results of pushing onto a CCS, so that the second and
107 // subsequent times we push a certain CC on a CCS we get the same
108 // result).
109
110 typedef struct IndexTable_ {
111 // Just a linked list of (cc, ccs) pairs, where the `ccs` is the result of
112 // pushing `cc` to the owner of the index table (another CostCentreStack).
113 CostCentre *cc;
114 CostCentreStack *ccs;
115 struct IndexTable_ *next;
116 // back_edge is true when `cc` is already in the stack, so pushing it
117 // truncates or drops (see RECURSION_DROPS and RECURSION_TRUNCATES in
118 // Profiling.c).
119 bool back_edge;
120 } IndexTable;
121
122
123 /* -----------------------------------------------------------------------------
124 Pre-defined cost centres and cost centre stacks
125 -------------------------------------------------------------------------- */
126
127 #if IN_STG_CODE
128
129 extern StgWord CC_MAIN[];
130 extern StgWord CCS_MAIN[]; // Top CCS
131
132 extern StgWord CC_SYSTEM[];
133 extern StgWord CCS_SYSTEM[]; // RTS costs
134
135 extern StgWord CC_GC[];
136 extern StgWord CCS_GC[]; // Garbage collector costs
137
138 extern StgWord CC_OVERHEAD[];
139 extern StgWord CCS_OVERHEAD[]; // Profiling overhead
140
141 extern StgWord CC_DONT_CARE[];
142 extern StgWord CCS_DONT_CARE[]; // CCS attached to static constructors
143
144 #else
145
146 extern CostCentre CC_MAIN[];
147 extern CostCentreStack CCS_MAIN[]; // Top CCS
148
149 extern CostCentre CC_SYSTEM[];
150 extern CostCentreStack CCS_SYSTEM[]; // RTS costs
151
152 extern CostCentre CC_GC[];
153 extern CostCentreStack CCS_GC[]; // Garbage collector costs
154
155 extern CostCentre CC_OVERHEAD[];
156 extern CostCentreStack CCS_OVERHEAD[]; // Profiling overhead
157
158 extern CostCentre CC_DONT_CARE[];
159 extern CostCentreStack CCS_DONT_CARE[]; // shouldn't ever get set
160
161 extern CostCentre CC_PINNED[];
162 extern CostCentreStack CCS_PINNED[]; // pinned memory
163
164 extern CostCentre CC_IDLE[];
165 extern CostCentreStack CCS_IDLE[]; // capability is idle
166
167 #endif /* IN_STG_CODE */
168
169 extern unsigned int RTS_VAR(era);
170
171 /* -----------------------------------------------------------------------------
172 * Functions
173 * ---------------------------------------------------------------------------*/
174
175 CostCentreStack * pushCostCentre (CostCentreStack *, CostCentre *);
176 void enterFunCCS (StgRegTable *reg, CostCentreStack *);
177 CostCentre *mkCostCentre (char *label, char *module, char *srcloc);
178
179 extern CostCentre * RTS_VAR(CC_LIST); // registered CC list
180
181 /* -----------------------------------------------------------------------------
182 * Declaring Cost Centres & Cost Centre Stacks.
183 * -------------------------------------------------------------------------- */
184
185 # define CC_DECLARE(cc_ident,name,mod,loc,caf,is_local) \
186 is_local CostCentre cc_ident[1] \
187 = {{ .ccID = 0, \
188 .label = name, \
189 .module = mod, \
190 .srcloc = loc, \
191 .time_ticks = 0, \
192 .mem_alloc = 0, \
193 .link = 0, \
194 .is_caf = caf \
195 }};
196
197 # define CCS_DECLARE(ccs_ident,cc_ident,is_local) \
198 is_local CostCentreStack ccs_ident[1] \
199 = {{ .ccsID = 0, \
200 .cc = cc_ident, \
201 .prevStack = NULL, \
202 .indexTable = NULL, \
203 .root = NULL, \
204 .depth = 0, \
205 .selected = 0, \
206 .scc_count = 0, \
207 .time_ticks = 0, \
208 .mem_alloc = 0, \
209 .inherited_ticks = 0, \
210 .inherited_alloc = 0 \
211 }};
212
213 /* -----------------------------------------------------------------------------
214 * Time / Allocation Macros
215 * ---------------------------------------------------------------------------*/
216
217 /* eliminate profiling overhead from allocation costs */
218 #define CCS_ALLOC(ccs, size) (ccs)->mem_alloc += ((size)-sizeofW(StgProfHeader))
219 #define ENTER_CCS_THUNK(cap,p) cap->r.rCCCS = p->header.prof.ccs
220
221 #else /* !PROFILING */
222
223 #define CCS_ALLOC(ccs, amount) doNothing()
224 #define ENTER_CCS_THUNK(cap,p) doNothing()
225
226 #endif /* PROFILING */