/rts/include/rts/prof/CCS.h
https://github.com/bgamari/ghc · C Header · 227 lines · 102 code · 55 blank · 70 comment · 0 complexity · a38670426116d9640937f216a833a022 MD5 · raw file
- /* -----------------------------------------------------------------------------
- *
- * (c) The GHC Team, 2009-2012
- *
- * Macros for profiling operations in STG code
- *
- * Do not #include this file directly: #include "Rts.h" instead.
- *
- * To understand the structure of the RTS headers, see the wiki:
- * https://gitlab.haskell.org/ghc/ghc/wikis/commentary/source-tree/includes
- *
- * ---------------------------------------------------------------------------*/
- #pragma once
- /* -----------------------------------------------------------------------------
- * Data Structures
- * ---------------------------------------------------------------------------*/
- /*
- * Note [struct alignment]
- * ~~~~~~~~~~~~~~~~~~~~~~~
- * 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
- * generator (GHC.StgToCmm.Prof).
- */
- typedef struct CostCentre_ {
- StgInt ccID; // Unique Id, allocated by the RTS
- char * label;
- char * module;
- char * srcloc;
- // used for accumulating costs at the end of the run...
- StgWord64 mem_alloc; // align 8 (Note [struct alignment])
- StgWord time_ticks;
- StgBool is_caf; // true <=> CAF cost centre
- struct CostCentre_ *link;
- } CostCentre;
- typedef struct CostCentreStack_ {
- StgInt ccsID; // unique ID, allocated by the RTS
- CostCentre *cc; // Cost centre at the top of the stack
- struct CostCentreStack_ *prevStack; // parent
- struct IndexTable_ *indexTable; // children
- struct CostCentreStack_ *root; // root of stack
- StgWord depth; // number of items in the stack
- StgWord64 scc_count; // Count of times this CCS is entered
- // align 8 (Note [struct alignment])
- StgWord selected; // is this CCS shown in the heap
- // profile? (zero if excluded via -hc
- // -hm etc.)
- 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)
- } CostCentreStack;
- /* -----------------------------------------------------------------------------
- * 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 );
- /* -----------------------------------------------------------------------------
- * The rest is PROFILING only...
- * ---------------------------------------------------------------------------*/
- #if defined(PROFILING)
- /* -----------------------------------------------------------------------------
- * Constants
- * ---------------------------------------------------------------------------*/
- #define EMPTY_STACK NULL
- #define EMPTY_TABLE NULL
- /* Constants used to set is_caf flag on CostCentres */
- #define CC_IS_CAF true
- #define CC_NOT_CAF false
- /* -----------------------------------------------------------------------------
- * Data Structures
- * ---------------------------------------------------------------------------*/
- // 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).
- typedef struct IndexTable_ {
- // 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).
- CostCentre *cc;
- CostCentreStack *ccs;
- struct IndexTable_ *next;
- // 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;
- } IndexTable;
- /* -----------------------------------------------------------------------------
- Pre-defined cost centres and cost centre stacks
- -------------------------------------------------------------------------- */
- #if IN_STG_CODE
- extern StgWord CC_MAIN[];
- extern StgWord CCS_MAIN[]; // Top CCS
- extern StgWord CC_SYSTEM[];
- extern StgWord CCS_SYSTEM[]; // RTS costs
- extern StgWord CC_GC[];
- extern StgWord CCS_GC[]; // Garbage collector costs
- extern StgWord CC_OVERHEAD[];
- extern StgWord CCS_OVERHEAD[]; // Profiling overhead
- extern StgWord CC_DONT_CARE[];
- extern StgWord CCS_DONT_CARE[]; // CCS attached to static constructors
- #else
- extern CostCentre CC_MAIN[];
- extern CostCentreStack CCS_MAIN[]; // Top CCS
- extern CostCentre CC_SYSTEM[];
- extern CostCentreStack CCS_SYSTEM[]; // RTS costs
- extern CostCentre CC_GC[];
- extern CostCentreStack CCS_GC[]; // Garbage collector costs
- extern CostCentre CC_OVERHEAD[];
- extern CostCentreStack CCS_OVERHEAD[]; // Profiling overhead
- extern CostCentre CC_DONT_CARE[];
- extern CostCentreStack CCS_DONT_CARE[]; // shouldn't ever get set
- extern CostCentre CC_PINNED[];
- extern CostCentreStack CCS_PINNED[]; // pinned memory
- extern CostCentre CC_IDLE[];
- extern CostCentreStack CCS_IDLE[]; // capability is idle
- #endif /* IN_STG_CODE */
- extern unsigned int RTS_VAR(era);
- /* -----------------------------------------------------------------------------
- * Functions
- * ---------------------------------------------------------------------------*/
- CostCentreStack * pushCostCentre (CostCentreStack *, CostCentre *);
- void enterFunCCS (StgRegTable *reg, CostCentreStack *);
- CostCentre *mkCostCentre (char *label, char *module, char *srcloc);
- extern CostCentre * RTS_VAR(CC_LIST); // registered CC list
- /* -----------------------------------------------------------------------------
- * Declaring Cost Centres & Cost Centre Stacks.
- * -------------------------------------------------------------------------- */
- # 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 \
- }};
- # 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 \
- }};
- /* -----------------------------------------------------------------------------
- * Time / Allocation Macros
- * ---------------------------------------------------------------------------*/
- /* eliminate profiling overhead from allocation costs */
- #define CCS_ALLOC(ccs, size) (ccs)->mem_alloc += ((size)-sizeofW(StgProfHeader))
- #define ENTER_CCS_THUNK(cap,p) cap->r.rCCCS = p->header.prof.ccs
- #else /* !PROFILING */
- #define CCS_ALLOC(ccs, amount) doNothing()
- #define ENTER_CCS_THUNK(cap,p) doNothing()
- #endif /* PROFILING */