ghc-lib-parser-0.20190402: includes/rts/prof/CCS.h
/* -----------------------------------------------------------------------------
*
* (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 (compiler/codeGen/StgCmmProf.hs).
*/
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 */