/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

  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. * https://gitlab.haskell.org/ghc/ghc/wikis/commentary/source-tree/includes
  11. *
  12. * ---------------------------------------------------------------------------*/
  13. #pragma once
  14. /* -----------------------------------------------------------------------------
  15. * Data Structures
  16. * ---------------------------------------------------------------------------*/
  17. /*
  18. * Note [struct alignment]
  19. * ~~~~~~~~~~~~~~~~~~~~~~~
  20. * NB. be careful to avoid unwanted padding between fields, by
  21. * putting the 8-byte fields on an 8-byte boundary. Padding can
  22. * vary between C compilers, and we don't take into account any
  23. * possible padding when generating CCS and CC decls in the code
  24. * generator (GHC.StgToCmm.Prof).
  25. */
  26. typedef struct CostCentre_ {
  27. StgInt ccID; // Unique Id, allocated by the RTS
  28. char * label;
  29. char * module;
  30. char * srcloc;
  31. // used for accumulating costs at the end of the run...
  32. StgWord64 mem_alloc; // align 8 (Note [struct alignment])
  33. StgWord time_ticks;
  34. StgBool is_caf; // true <=> CAF cost centre
  35. struct CostCentre_ *link;
  36. } CostCentre;
  37. typedef struct CostCentreStack_ {
  38. StgInt ccsID; // unique ID, allocated by the RTS
  39. CostCentre *cc; // Cost centre at the top of the stack
  40. struct CostCentreStack_ *prevStack; // parent
  41. struct IndexTable_ *indexTable; // children
  42. struct CostCentreStack_ *root; // root of stack
  43. StgWord depth; // number of items in the stack
  44. StgWord64 scc_count; // Count of times this CCS is entered
  45. // align 8 (Note [struct alignment])
  46. StgWord selected; // is this CCS shown in the heap
  47. // profile? (zero if excluded via -hc
  48. // -hm etc.)
  49. StgWord time_ticks; // number of time ticks accumulated by
  50. // this CCS
  51. StgWord64 mem_alloc; // mem allocated by this CCS
  52. // align 8 (Note [struct alignment])
  53. StgWord64 inherited_alloc; // sum of mem_alloc over all children
  54. // (calculated at the end)
  55. // align 8 (Note [struct alignment])
  56. StgWord inherited_ticks; // sum of time_ticks over all children
  57. // (calculated at the end)
  58. } CostCentreStack;
  59. /* -----------------------------------------------------------------------------
  60. * Start and stop the profiling timer. These can be called from
  61. * Haskell to restrict the profile to portion(s) of the execution.
  62. * See the module GHC.Profiling.
  63. * ---------------------------------------------------------------------------*/
  64. void stopProfTimer ( void );
  65. void startProfTimer ( void );
  66. /* -----------------------------------------------------------------------------
  67. * The rest is PROFILING only...
  68. * ---------------------------------------------------------------------------*/
  69. #if defined(PROFILING)
  70. /* -----------------------------------------------------------------------------
  71. * Constants
  72. * ---------------------------------------------------------------------------*/
  73. #define EMPTY_STACK NULL
  74. #define EMPTY_TABLE NULL
  75. /* Constants used to set is_caf flag on CostCentres */
  76. #define CC_IS_CAF true
  77. #define CC_NOT_CAF false
  78. /* -----------------------------------------------------------------------------
  79. * Data Structures
  80. * ---------------------------------------------------------------------------*/
  81. // IndexTable is the list of children of a CCS. (Alternatively it is a
  82. // cache of the results of pushing onto a CCS, so that the second and
  83. // subsequent times we push a certain CC on a CCS we get the same
  84. // result).
  85. typedef struct IndexTable_ {
  86. // Just a linked list of (cc, ccs) pairs, where the `ccs` is the result of
  87. // pushing `cc` to the owner of the index table (another CostCentreStack).
  88. CostCentre *cc;
  89. CostCentreStack *ccs;
  90. struct IndexTable_ *next;
  91. // back_edge is true when `cc` is already in the stack, so pushing it
  92. // truncates or drops (see RECURSION_DROPS and RECURSION_TRUNCATES in
  93. // Profiling.c).
  94. bool back_edge;
  95. } IndexTable;
  96. /* -----------------------------------------------------------------------------
  97. Pre-defined cost centres and cost centre stacks
  98. -------------------------------------------------------------------------- */
  99. #if IN_STG_CODE
  100. extern StgWord CC_MAIN[];
  101. extern StgWord CCS_MAIN[]; // Top CCS
  102. extern StgWord CC_SYSTEM[];
  103. extern StgWord CCS_SYSTEM[]; // RTS costs
  104. extern StgWord CC_GC[];
  105. extern StgWord CCS_GC[]; // Garbage collector costs
  106. extern StgWord CC_OVERHEAD[];
  107. extern StgWord CCS_OVERHEAD[]; // Profiling overhead
  108. extern StgWord CC_DONT_CARE[];
  109. extern StgWord CCS_DONT_CARE[]; // CCS attached to static constructors
  110. #else
  111. extern CostCentre CC_MAIN[];
  112. extern CostCentreStack CCS_MAIN[]; // Top CCS
  113. extern CostCentre CC_SYSTEM[];
  114. extern CostCentreStack CCS_SYSTEM[]; // RTS costs
  115. extern CostCentre CC_GC[];
  116. extern CostCentreStack CCS_GC[]; // Garbage collector costs
  117. extern CostCentre CC_OVERHEAD[];
  118. extern CostCentreStack CCS_OVERHEAD[]; // Profiling overhead
  119. extern CostCentre CC_DONT_CARE[];
  120. extern CostCentreStack CCS_DONT_CARE[]; // shouldn't ever get set
  121. extern CostCentre CC_PINNED[];
  122. extern CostCentreStack CCS_PINNED[]; // pinned memory
  123. extern CostCentre CC_IDLE[];
  124. extern CostCentreStack CCS_IDLE[]; // capability is idle
  125. #endif /* IN_STG_CODE */
  126. extern unsigned int RTS_VAR(era);
  127. /* -----------------------------------------------------------------------------
  128. * Functions
  129. * ---------------------------------------------------------------------------*/
  130. CostCentreStack * pushCostCentre (CostCentreStack *, CostCentre *);
  131. void enterFunCCS (StgRegTable *reg, CostCentreStack *);
  132. CostCentre *mkCostCentre (char *label, char *module, char *srcloc);
  133. extern CostCentre * RTS_VAR(CC_LIST); // registered CC list
  134. /* -----------------------------------------------------------------------------
  135. * Declaring Cost Centres & Cost Centre Stacks.
  136. * -------------------------------------------------------------------------- */
  137. # define CC_DECLARE(cc_ident,name,mod,loc,caf,is_local) \
  138. is_local CostCentre cc_ident[1] \
  139. = {{ .ccID = 0, \
  140. .label = name, \
  141. .module = mod, \
  142. .srcloc = loc, \
  143. .time_ticks = 0, \
  144. .mem_alloc = 0, \
  145. .link = 0, \
  146. .is_caf = caf \
  147. }};
  148. # define CCS_DECLARE(ccs_ident,cc_ident,is_local) \
  149. is_local CostCentreStack ccs_ident[1] \
  150. = {{ .ccsID = 0, \
  151. .cc = cc_ident, \
  152. .prevStack = NULL, \
  153. .indexTable = NULL, \
  154. .root = NULL, \
  155. .depth = 0, \
  156. .selected = 0, \
  157. .scc_count = 0, \
  158. .time_ticks = 0, \
  159. .mem_alloc = 0, \
  160. .inherited_ticks = 0, \
  161. .inherited_alloc = 0 \
  162. }};
  163. /* -----------------------------------------------------------------------------
  164. * Time / Allocation Macros
  165. * ---------------------------------------------------------------------------*/
  166. /* eliminate profiling overhead from allocation costs */
  167. #define CCS_ALLOC(ccs, size) (ccs)->mem_alloc += ((size)-sizeofW(StgProfHeader))
  168. #define ENTER_CCS_THUNK(cap,p) cap->r.rCCCS = p->header.prof.ccs
  169. #else /* !PROFILING */
  170. #define CCS_ALLOC(ccs, amount) doNothing()
  171. #define ENTER_CCS_THUNK(cap,p) doNothing()
  172. #endif /* PROFILING */