CCS.h 8.41 KB
Newer Older
1
2
/* -----------------------------------------------------------------------------
 *
Gabor Greif's avatar
Gabor Greif committed
3
 * (c) The GHC Team, 2009-2012
4
5
 *
 * Macros for profiling operations in STG code
6
 *
7
8
9
 * Do not #include this file directly: #include "Rts.h" instead.
 *
 * To understand the structure of the RTS headers, see the wiki:
10
 *   https://gitlab.haskell.org/ghc/ghc/wikis/commentary/source-tree/includes
11
 *
12
13
 * ---------------------------------------------------------------------------*/

14
#pragma once
15

16
/* -----------------------------------------------------------------------------
17
18
 * Data Structures
 * ---------------------------------------------------------------------------*/
19
/*
20
 * Note [struct alignment]
Ben Gamari's avatar
Ben Gamari committed
21
 * ~~~~~~~~~~~~~~~~~~~~~~~
22
23
24
25
 * NB. be careful to avoid unwanted padding between fields, by
 * putting the 8-byte fields on an 8-byte boundary.  Padding can
 * vary between C compilers, and we don't take into account any
 * possible padding when generating CCS and CC decls in the code
26
 * generator (GHC.StgToCmm.Prof).
27
 */
28

29
typedef struct CostCentre_ {
30
    StgInt ccID;              // Unique Id, allocated by the RTS
31

32
33
    char * label;
    char * module;
34
    char * srcloc;
35
36
37

    // used for accumulating costs at the end of the run...
    StgWord64 mem_alloc;      // align 8 (Note [struct alignment])
38
    StgWord   time_ticks;
39

40
    StgBool is_caf;           // true <=> CAF cost centre
41

42
    struct CostCentre_ *link;
43
44
} CostCentre;

45
typedef struct CostCentreStack_ {
46
47
48
49
    StgInt ccsID;               // unique ID, allocated by the RTS

    CostCentre *cc;             // Cost centre at the top of the stack

50
51
52
    struct CostCentreStack_ *prevStack;   // parent
    struct IndexTable_      *indexTable;  // children
    struct CostCentreStack_ *root;        // root of stack
53
    StgWord    depth;           // number of items in the stack
54

55
56
    StgWord64  scc_count;       // Count of times this CCS is entered
                                // align 8 (Note [struct alignment])
57

58
59
60
    StgWord    selected;        // is this CCS shown in the heap
                                // profile? (zero if excluded via -hc
                                // -hm etc.)
61

62
63
64
65
66
67
68
69
70
71
72
73
    StgWord    time_ticks;      // number of time ticks accumulated by
                                // this CCS

    StgWord64  mem_alloc;       // mem allocated by this CCS
                                // align 8 (Note [struct alignment])

    StgWord64  inherited_alloc; // sum of mem_alloc over all children
                                // (calculated at the end)
                                // align 8 (Note [struct alignment])

    StgWord    inherited_ticks; // sum of time_ticks over all children
                                // (calculated at the end)
74
75
76
} CostCentreStack;


77
78
79
80
81
82
83
84
85
/* -----------------------------------------------------------------------------
 * Start and stop the profiling timer.  These can be called from
 * Haskell to restrict the profile to portion(s) of the execution.
 * See the module GHC.Profiling.
 * ---------------------------------------------------------------------------*/

void stopProfTimer      ( void );
void startProfTimer     ( void );

86
87
88
/* -----------------------------------------------------------------------------
 * The rest is PROFILING only...
 * ---------------------------------------------------------------------------*/
89

90
#if defined(PROFILING)
91

92
93
94
95
96
97
98
/* -----------------------------------------------------------------------------
 * Constants
 * ---------------------------------------------------------------------------*/

#define EMPTY_STACK NULL
#define EMPTY_TABLE NULL

99
/* Constants used to set is_caf flag on CostCentres */
100
101
#define CC_IS_CAF      true
#define CC_NOT_CAF     false
102
/* -----------------------------------------------------------------------------
103
104
 * Data Structures
 * ---------------------------------------------------------------------------*/
105

106
107
108
109
110
// IndexTable is the list of children of a CCS. (Alternatively it is a
// cache of the results of pushing onto a CCS, so that the second and
// subsequent times we push a certain CC on a CCS we get the same
// result).

111
typedef struct IndexTable_ {
112
113
    // Just a linked list of (cc, ccs) pairs, where the `ccs` is the result of
    // pushing `cc` to the owner of the index table (another CostCentreStack).
114
115
    CostCentre *cc;
    CostCentreStack *ccs;
116
    struct IndexTable_ *next;
117
118
119
120
    // back_edge is true when `cc` is already in the stack, so pushing it
    // truncates or drops (see RECURSION_DROPS and RECURSION_TRUNCATES in
    // Profiling.c).
    bool back_edge;
121
122
} IndexTable;

123

124
125
126
127
/* -----------------------------------------------------------------------------
   Pre-defined cost centres and cost centre stacks
   -------------------------------------------------------------------------- */

128
129
#if IN_STG_CODE

130
extern StgWord CC_MAIN[];
131
extern StgWord CCS_MAIN[];      // Top CCS
132

133
extern StgWord CC_SYSTEM[];
134
extern StgWord CCS_SYSTEM[];    // RTS costs
135
136

extern StgWord CC_GC[];
137
extern StgWord CCS_GC[];         // Garbage collector costs
138
139

extern StgWord CC_OVERHEAD[];
140
extern StgWord CCS_OVERHEAD[];   // Profiling overhead
141
142

extern StgWord CC_DONT_CARE[];
143
extern StgWord CCS_DONT_CARE[];  // CCS attached to static constructors
144
145
146

#else

147
extern CostCentre      CC_MAIN[];
148
extern CostCentreStack CCS_MAIN[];      // Top CCS
149

150
extern CostCentre      CC_SYSTEM[];
151
extern CostCentreStack CCS_SYSTEM[];    // RTS costs
152
153

extern CostCentre      CC_GC[];
154
extern CostCentreStack CCS_GC[];         // Garbage collector costs
155
156

extern CostCentre      CC_OVERHEAD[];
157
extern CostCentreStack CCS_OVERHEAD[];   // Profiling overhead
158
159

extern CostCentre      CC_DONT_CARE[];
160
161
162
163
extern CostCentreStack CCS_DONT_CARE[];  // shouldn't ever get set

extern CostCentre      CC_PINNED[];
extern CostCentreStack CCS_PINNED[];     // pinned memory
164

165
166
167
extern CostCentre      CC_IDLE[];
extern CostCentreStack CCS_IDLE[];       // capability is idle

168
#endif /* IN_STG_CODE */
169
170

extern unsigned int RTS_VAR(era);
171
172

/* -----------------------------------------------------------------------------
173
 * Functions
174
175
 * ---------------------------------------------------------------------------*/

176
CostCentreStack * pushCostCentre (CostCentreStack *, CostCentre *);
177
void              enterFunCCS    (StgRegTable *reg, CostCentreStack *);
178
CostCentre *mkCostCentre (char *label, char *module, char *srcloc);
179

180
extern CostCentre * RTS_VAR(CC_LIST);               // registered CC list
181
182
183
184
185

/* -----------------------------------------------------------------------------
 * Declaring Cost Centres & Cost Centre Stacks.
 * -------------------------------------------------------------------------- */

186
187
188
189
190
191
192
193
194
195
# define CC_DECLARE(cc_ident,name,mod,loc,caf,is_local)  \
     is_local CostCentre cc_ident[1]                     \
       = {{ .ccID       = 0,                             \
            .label      = name,                          \
            .module     = mod,                           \
            .srcloc     = loc,                           \
            .time_ticks = 0,                             \
            .mem_alloc  = 0,                             \
            .link       = 0,                             \
            .is_caf     = caf                            \
196
197
         }};

198
199
200
201
202
203
204
205
206
207
208
209
210
211
# define CCS_DECLARE(ccs_ident,cc_ident,is_local)        \
     is_local CostCentreStack ccs_ident[1]               \
       = {{ .ccsID               = 0,                    \
            .cc                  = cc_ident,             \
            .prevStack           = NULL,                 \
            .indexTable          = NULL,                 \
            .root                = NULL,                 \
            .depth               = 0,                    \
            .selected            = 0,                    \
            .scc_count           = 0,                    \
            .time_ticks          = 0,                    \
            .mem_alloc           = 0,                    \
            .inherited_ticks     = 0,                    \
            .inherited_alloc     = 0                     \
212
213
214
215
216
217
218
219
       }};

/* -----------------------------------------------------------------------------
 * Time / Allocation Macros
 * ---------------------------------------------------------------------------*/

/* eliminate profiling overhead from allocation costs */
#define CCS_ALLOC(ccs, size) (ccs)->mem_alloc += ((size)-sizeofW(StgProfHeader))
220
#define ENTER_CCS_THUNK(cap,p) cap->r.rCCCS = p->header.prof.ccs
221

222
223
224
#else /* !PROFILING */

#define CCS_ALLOC(ccs, amount) doNothing()
225
#define ENTER_CCS_THUNK(cap,p) doNothing()
226

227
#endif /* PROFILING */