fields in closures.
\begin{code}
-#if defined(USE_COST_CENTRES) || defined(CONCURRENT)
+#if defined(PROFILING) || defined(CONCURRENT)
# define CC_EXTERN(cc_ident) \
extern struct cc CAT2(cc_ident,_struct); \
CC_EXTERN(CC_MAIN); /* initial MAIN cost centre */
CC_EXTERN(CC_GC); /* Garbage Collection cost center */
-# ifdef GUM
+# ifdef PAR
CC_EXTERN(CC_MSG); /* Communications cost center */
CC_EXTERN(CC_IDLE); /* Idle-time cost centre */
# endif
source using the @CC_DECLARE@ macro where @label@, @module@ and
@group@ are strings and @ident@ the cost centre identifier.
-\begin{code}
-# define CC_IS_CAF 'C'
-# define CC_IS_DICT 'D'
-# define CC_IS_SUBSUMED 'S'
-# define CC_IS_BORING '\0'
+\begin{code}
+# define CC_IS_CAF 'c'
+# define CC_IS_DICT 'd'
+# define CC_IS_SUBSUMED 's'
+# define CC_IS_BORING 'B'
# define STATIC_CC_REF(cc_ident) &CAT2(cc_ident,_struct)
# define DYN_CC_REF(cc_ident) cc_ident /* unused */
-# define CC_DECLARE(cc_ident,name,module,group,subsumed,is_local) \
- is_local struct cc CAT2(cc_ident,_struct) \
- = {NOT_REGISTERED, UNHASHED, name, module, group, \
- subsumed, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; \
+# define CC_DECLARE(cc_ident,name,module,group,subsumed,is_local) \
+ is_local struct cc CAT2(cc_ident,_struct) \
+ = {NOT_REGISTERED, UNHASHED, name, module, group, \
+ subsumed, INIT_CC_STATS}; \
is_local CostCentre cc_ident = STATIC_CC_REF(cc_ident)
-#endif /* defined(USE_COST_CENTRES) || defined(CONCURRENT) */
+#endif /* defined(PROFILING) || defined(CONCURRENT) */
\end{code}
Definitions relating to the profiling field as a whole.
%************************************************************************
The cost-centre profiling is only on if the driver turns on
-@USE_COST_CENTRES@.
+@PROFILING@.
These are the {\em dummy} definitions in force if we do {\em NOT}
-turn on @USE_COST_CENTRES@. Get them out of the way....
+turn on @PROFILING@. Get them out of the way....
\begin{code}
-#if !defined(USE_COST_CENTRES)
+#if !defined(PROFILING)
/*** Declaration Definitions ***/
# define SET_CC_HDR(closure, cc) /* Dont set CC header */
# define SET_STATIC_CC_HDR(cc) /* No static CC header */
-# define SET_CCC(cc_ident,is_dupd)
+# define SET_CCC(cc_ident,do_scc_count)
+# define SET_DICT_CCC(cc_ident,do_scc_count)
+# define SET_CCC_RTS(cc_ident,do_sub_count,do_count)
# define RESTORE_CCC(cc)
# define ENTER_CC_TCL(closure)
# define ENTER_CC_F(cc)
# define ENTER_CC_FCL(closure)
+# define ENTER_CC_FSUB()
+# define ENTER_CC_FCAF(cc)
+# define ENTER_CC_FLOAD(cc)
# define ENTER_CC_PAP(cc)
# define ENTER_CC_PAP_CL(closure)
# define CC_ALLOC(cc, size, kind)
# define HEAP_PROFILE_CLOSURE(closure,size)
-# ifndef GUM
+# ifndef PAR
# define START_TIME_PROFILER
# define RESTART_TIME_PROFILER
# define STOP_TIME_PROFILER
# endif
-#endif /* !defined(USE_COST_CENTRES) */
+#endif /* !defined(PROFILING) */
\end{code}
%************************************************************************
closures. This is adjacent to the info pointer.
\begin{code}
-#if defined(USE_COST_CENTRES)
+#if defined(PROFILING)
CC_EXTERN(CC_SUBSUMED); /* top level fns SUBSUMED cost centre */
CC_EXTERN(CC_OVERHEAD); /* costs due only to profiling machinery */
CC_EXTERN(CC_CAFs); /* prelude cost centre (CAFs only) */
CC_EXTERN(CC_DICTs); /* prelude cost centre (DICTs only) */
-# define IS_CAF_OR_DICT_CC(cc) \
- (((cc)->is_subsumed == CC_IS_CAF) || ((cc)->is_subsumed == CC_IS_DICT))
-
-# define IS_SUBSUMED_CC(cc) ((cc)->is_subsumed == CC_IS_SUBSUMED)
+# define IS_CAF_OR_DICT_OD_SUB_CC(cc) \
+ ((cc)->is_subsumed & ' ') /* tests for lower case character */
\end{code}
recursion. (Huh? WDP 94/07)
\begin{code}
-# define SET_CCC_X(cc,is_dupd) \
- do { \
- if (!(is_dupd)) { CCC->sub_scc_count++; } /* inc subcc count of CCC */ \
- CCC = (CostCentre)(cc); /* set CCC to ident cc */ \
- if (!(is_dupd)) { CCC->scc_count++; } /* inc scc count of new CCC*/ \
+# define SET_CCC_X(cc,do_subcc_count,do_subdict_count,do_scc_count) \
+ do { \
+ if ((do_subcc_count)) { CCC->sub_scc_count++; } /* inc subcc count of CCC */ \
+ if ((do_subdict_count)) { CCC->sub_dictcc_count++; } /* inc sub dict count of CCC */ \
+ CCC = (CostCentre)(cc); /* set CCC to ident cc */ \
+ ASSERT_IS_REGISTERED(CCC,1); \
+ if ((do_scc_count)) { CCC->scc_count++; } /* inc scc count of new CCC*/ \
} while(0)
-# define SET_CCC(cc_ident,is_dupd) SET_CCC_X(STATIC_CC_REF(cc_ident),is_dupd)
+# define SET_CCC(cc_ident,do_scc_count) \
+ SET_CCC_X(STATIC_CC_REF(cc_ident),do_scc_count,0,do_scc_count)
+
+# define SET_DICT_CCC(cc_ident,do_scc_count) \
+ SET_CCC_X(STATIC_CC_REF(cc_ident),0,do_scc_count,do_scc_count)
+
+# define SET_CCC_RTS(cc_ident,do_sub_count,do_scc_count) \
+ SET_CCC_X(STATIC_CC_REF(cc_ident),do_sub_count,0,do_scc_count)
\end{code}
We have this @RESTORE_CCC@ macro, rather than just an assignment,
# define ENTER_CC_CAF_X(cc) \
do { \
CCC->sub_cafcc_count++; /* inc subcaf count of CCC */ \
- CCC = (CostCentre)(cc); /* set CCC to ident cc */ \
+ CCC = (CostCentre)(cc); /* set CCC to ident cc */ \
ASSERT_IS_REGISTERED(CCC,1); \
- CCC->cafcc_count++; /* inc cafcc count of CCC */ \
+ CCC->scc_count++; /* inc scc count of CAF cc */ \
} while(0)
# define ENTER_CC_CAF(cc_ident) ENTER_CC_CAF_X(STATIC_CC_REF(cc_ident))
On entering a closure we only count the enter to thunks ...
\begin{code}
-# define ENTER_CC_T(cc) \
- do { \
- CCC = (CostCentre)(cc); \
- ASSERT_IS_REGISTERED(CCC,1); \
- CCC->thunk_count++; /* inc thunk count of new CCC */ \
+# define ENTER_CC_T(cc) \
+ do { \
+ CCC = (CostCentre)(cc); \
+ ASSERT_IS_REGISTERED(CCC,1); \
+ CCC_DETAIL_COUNT(CCC->thunk_count); \
} while(0)
-# define ENTER_CC_TCL(closure) \
+# define ENTER_CC_TCL(closure) \
ENTER_CC_T(CC_HDR(closure))
/* Here is our special "hybrid" case when we do *not* set the CCC.
do { \
CostCentre cc = (CostCentre) (centre); \
ASSERT_IS_REGISTERED(cc,1); \
- if ( ! IS_CAF_OR_DICT_CC(cc) ) { \
+ if ( ! IS_CAF_OR_DICT_OR_SUB_CC(cc) ) { \
CCC = cc; \
+ } else { \
+ CCC_DETAIL_COUNT(cc->caffun_subsumed); \
+ CCC_DETAIL_COUNT(CCC->subsumed_caf_count); \
} \
- CCC->function_count++; \
+ CCC_DETAIL_COUNT(CCC->function_count); \
} while(0)
# define ENTER_CC_FCL(closure) \
ENTER_CC_F(CC_HDR(closure))
+# define ENTER_CC_FSUB() \
+ do { \
+ CCC_DETAIL_COUNT(CCC->subsumed_fun_count); \
+ CCC_DETAIL_COUNT(CCC->function_count); \
+ } while(0)
+
+# define ENTER_CC_FCAF(centre) \
+ do { \
+ CostCentre cc = (CostCentre) (centre); \
+ ASSERT_IS_REGISTERED(cc,1); \
+ CCC_DETAIL_COUNT(cc->caffun_subsumed); \
+ CCC_DETAIL_COUNT(CCC->subsumed_caf_count); \
+ CCC_DETAIL_COUNT(CCC->function_count); \
+ } while(0)
+
+# define ENTER_CC_FLOAD(cc) \
+ do { \
+ CCC = (CostCentre)(cc); \
+ ASSERT_IS_REGISTERED(CCC,1); \
+ CCC_DETAIL_COUNT(CCC->function_count); \
+ } while(0)
+
/* These ENTER_CC_PAP things are only used in the RTS */
# define ENTER_CC_PAP(centre) \
do { \
CostCentre cc = (CostCentre) (centre); \
ASSERT_IS_REGISTERED(cc,1); \
- if ( ! IS_CAF_OR_DICT_CC(cc) ) { \
+ if ( ! IS_CAF_OR_DICT_OR_SUB_CC(cc) ) { \
CCC = cc; \
+ } else { \
+ CCC_DETAIL_COUNT(cc->caffun_subsumed); \
+ CCC_DETAIL_COUNT(CCC->subsumed_caf_count); \
} \
- CCC->pap_count++; \
+ CCC_DETAIL_COUNT(CCC->pap_count); \
} while(0)
# define ENTER_CC_PAP_CL(closure) \
ENTER_CC_PAP(CC_HDR(closure))
-#endif /* USE_COST_CENTRES */
+# if defined(PROFILING_DETAIL_COUNTS)
+# define CCC_DETAIL_COUNT(inc_this) ((inc_this)++)
+# else
+# define CCC_DETAIL_COUNT(inc_this) /*nothing*/
+# endif
+
+#endif /* PROFILING */
\end{code}
%************************************************************************
the register stack.
\begin{code}
-#if defined(USE_COST_CENTRES)
+#if defined(PROFILING)
extern F_ _regMain (STG_NO_ARGS);
extern F_ *register_stack;
# define POP_REGISTER_STACK \
*(--register_stack)
-extern I_ SM_trace;
-
# define START_REGISTER_CCS(reg_mod_name) \
static int _module_registered = 0; \
STGFUN(reg_mod_name) { \
} while(0); \
FUNEND; }
-#endif /* USE_COST_CENTRES */
+#endif /* PROFILING */
\end{code}
We don't want to attribute costs to an unregistered cost-centre:
\begin{code}
-#if !defined(USE_COST_CENTRES) || !defined(DEBUG)
+#if !defined(PROFILING) || !defined(DEBUG)
# define ASSERT_IS_REGISTERED(cc,chk_not_overhead) /*nothing*/
#else
# define ASSERT_IS_REGISTERED(cc,chk_not_overhead) \
- do { \
+ do { /* beware of cc name-capture */ \
CostCentre c_c = (CostCentre) (cc); \
if (c_c->registered == NOT_REGISTERED) { \
fprintf(stderr,"Entering unregistered CC: %s\n",c_c->label); \
Similarily, the SP stuff should probably be the highly uninformative
@INTERNAL_KIND@.
+SOF 4/96: Renamed MallocPtr_K to ForeignObj_K
+
\begin{code}
-#if defined(USE_COST_CENTRES)
+#if defined(PROFILING)
# define CON_K 1
# define FN_K 2
# define ARR_K 6
# ifndef PAR
-# define MallocPtr_K 7 /* Malloc Pointer */
+# define ForeignObj_K 7 /* Malloc Pointer */
# define SPT_K 8 /* Stable Pointer Table */
# endif /* !PAR */
# define CAT_DECLARE(base_name, kind, descr, type) \
static struct ClCat MK_CAT_IDENT(base_name) = {UNHASHED,-1,kind,descr,type};
-#endif /* USE_COST_CENTRES */
+#endif /* PROFILING */
\end{code}
%************************************************************************
Stuff to do with timer signals:
\begin{code}
-#if defined(USE_COST_CENTRES) || defined(GUM)
+#if defined(PROFILING) || defined(PAR)
extern I_ time_profiling; /* Flag indicating if timer/serial profiling is required */
# define TICK_FREQUENCY 50 /* ticks per second */
# define TICK_MILLISECS (1000/TICK_FREQUENCY) /* milli-seconds per tick */
-# ifdef CONCURRENT
-extern I_ profilerTicks;
-extern I_ tick_millisecs;
-# endif
-
# define DEFAULT_INTERVAL TICK_FREQUENCY /* 1 second */
/* These are never called directly from threaded code */
# define RESTART_TIME_PROFILER ULTRASAFESTGCALL0(void,(void *),restart_time_profiler) /*R StgOverflow.lc */
# define STOP_TIME_PROFILER ULTRASAFESTGCALL0(void,(void *),stop_time_profiler) /*R StgOverflow.lc */
-# if defined(USE_COST_CENTRES)
+# if defined(PROFILING)
# define OR_INTERVAL_EXPIRED || (interval_expired) /*R StgMacros.h */
# endif
\end{code}
value(s).
\begin{code}
-# if defined(USE_COST_CENTRES)
+# if defined(PROFILING)
# define DEFAULT_MAX_CC 4096
# define DEFAULT_MAX_MOD 256
extern hash_t init_index_type(STG_NO_ARGS);
extern hash_t index_type PROTO((ClCategory clcat));
-# endif /* USE_COST_CENTRES */
+# endif /* PROFILING */
\end{code}
memory alloc macros.
\begin{code}
-# define CC_TICK(cc) \
- do { CostCentre centre = (CostCentre) (cc); \
- ASSERT_IS_REGISTERED(centre,1); \
- centre->time_ticks += 1; \
+# define CC_TICK(centre) \
+ do { CostCentre cc = (CostCentre) (centre); \
+ ASSERT_IS_REGISTERED(cc,1); \
+ cc->time_ticks += 1; \
} while(0)
-# if defined(USE_COST_CENTRES)
-# define CC_ALLOC(cc, size, kind) \
- do { CostCentre cc_ = (CostCentre) (cc); \
- ASSERT_IS_REGISTERED(cc_,0/*OK if OVERHEAD*/); \
- cc_->mem_allocs += 1; \
- cc_->mem_alloc += (size) - (PROF_FIXED_HDR + AGE_FIXED_HDR); \
- } while(0) /* beware name-capture by ASSERT_IS...! */
+# if defined(PROFILING)
+# define CC_ALLOC(centre, size, kind) \
+ do { CostCentre cc = (CostCentre) (centre); \
+ ASSERT_IS_REGISTERED(cc,0/*OK if OVERHEAD*/); \
+ CCC_DETAIL_COUNT(cc->mem_allocs); \
+ cc->mem_alloc += (size) - (PROF_FIXED_HDR + TICKY_FIXED_HDR); \
+ } while(0)
# endif
\end{code}
%************************************************************************
\begin{code}
-extern I_ cc_profiling; /* Are we performing/reporting cc profiling? */
-extern I_ heap_profiling_reqd; /* Are we performing heap profiling? */
+I_ init_cc_profiling PROTO((I_ rts_argc, char *rts_argv[], char *prog_argv[]));
+void report_cc_profiling PROTO((I_ final));
-# define SORTCC_LABEL 'C'
-# define SORTCC_TIME 'T'
-# define SORTCC_ALLOC 'A'
-extern char cc_profiling_sort; /* How to sort cost centre report */
-
-extern I_ init_cc_profiling PROTO((I_ rts_argc, char *rts_argv[], char *prog_argv[]));
-extern void report_cc_profiling PROTO((I_ final));
-
-extern void cc_register(STG_NO_ARGS);
-extern void cc_sort PROTO((CostCentre *sort, char sort_on));
+void cc_register(STG_NO_ARGS);
+void cc_sort PROTO((CostCentre *sort, char sort_on));
+rtsBool cc_to_ignore PROTO((CostCentre));
\end{code}
%************************************************************************
%************************************************************************
\begin{code}
-# define HEAP_NO_PROFILING 0 /* N.B. Used as indexes into arrays */
-
-# if defined(USE_COST_CENTRES)
-
-# define HEAP_BY_CC 1
-# define HEAP_BY_MOD 2
-# define HEAP_BY_GRP 3
-# define HEAP_BY_DESCR 4
-# define HEAP_BY_TYPE 5
-# define HEAP_BY_TIME 6
-
-# define CCchar 'C'
-# define MODchar 'M'
-# define GRPchar 'G'
-# define DESCRchar 'D'
-# define TYPEchar 'Y'
-# define TIMEchar 'T'
-
-extern I_ heap_profile_init PROTO((I_ prof,
- char *select_cc_str,
- char *select_mod_str,
- char *select_grp_str,
- char *select_descr_str,
- char *select_typ_str,
- char *select_kind_str,
- I_ select_age,
- char *argv[]));
-
-extern void heap_profile_finish(STG_NO_ARGS);
-
-extern void heap_profile_setup(STG_NO_ARGS); /* called at start of heap profile */
-extern void heap_profile_done(STG_NO_ARGS); /* called at end of heap profile */
-
-extern void (* heap_profile_fn) PROTO((P_ closure,I_ size));
+# if defined(PROFILING)
+
+I_ heap_profile_init PROTO((char *argv[]));
+
+void heap_profile_finish(STG_NO_ARGS);
+
+void heap_profile_setup(STG_NO_ARGS); /* called at start of heap profile */
+void heap_profile_done(STG_NO_ARGS); /* called at end of heap profile */
+
+void (* heap_profile_fn) PROTO((P_ closure,I_ size));
extern I_ earlier_ticks; /* no. of earlier ticks grouped */
extern hash_t time_intervals; /* no. of time intervals reported -- 18 */
-# define HEAP_PROFILE_CLOSURE(closure,size) \
- STGCALL2(void,(void *, P_, I_),(*heap_profile_fn),closure,size) /*R SM2s.lh */
+# define HEAP_PROFILE_CLOSURE(closure,size) \
+ do { \
+ if (heap_profile_fn) { \
+ STGCALL2(void,(void *, P_, I_),(*heap_profile_fn),closure,size); \
+ }} while(0)
-# endif /* USE_COST_CENTRES */
+# endif /* PROFILING */
\end{code}
End multi-slurp protection:
\begin{code}
-#endif /* USE_COST_CENTRES || GUM */
+#endif /* PROFILING || PAR */
#endif /* CostCentre_H */
\end{code}