/* -----------------------------------------------------------------------------
- * $Id: Profiling.c,v 1.17 2000/04/03 15:54:49 simonmar Exp $
+ * $Id: Profiling.c,v 1.20 2000/05/12 13:01:04 simonmar Exp $
*
* (c) The GHC Team, 1998-2000
*
*/
static lnat total_alloc, total_prof_ticks;
-/* Globals for opening the profiling log file
+/* Globals for opening the profiling log file(s)
*/
static char *prof_filename; /* prof report file name = <program>.prof */
FILE *prof_file;
+static char *hp_filename; /* heap profile (hp2ps style) log file */
+FILE *hp_file;
+
/* The Current Cost Centre Stack (for attributing costs)
*/
CostCentreStack *CCCS;
* Static Functions
*/
-static CostCentreStack * ActualPush_ ( CostCentreStack *ccs, CostCentre *cc,
- CostCentreStack *new_ccs );
-
-static rtsBool ccs_to_ignore ( CostCentreStack *ccs );
-static void count_ticks ( CostCentreStack *ccs );
-static void reportCCS ( CostCentreStack *ccs, nat indent );
-static void DecCCS ( CostCentreStack *ccs );
-static void DecBackEdge ( CostCentreStack *ccs, CostCentreStack *oldccs );
-static CostCentreStack *CheckLoop ( CostCentreStack *ccs, CostCentre *cc );
-static CostCentreStack *pruneCCSTree ( CostCentreStack *ccs );
-
-static CostCentreStack *ActualPush ( CostCentreStack *, CostCentre * );
-static CostCentreStack *IsInIndexTable ( IndexTable *, CostCentre * );
-static IndexTable *AddToIndexTable ( IndexTable *, CostCentreStack *,
- CostCentre *, unsigned int );
+static CostCentreStack * ActualPush_ ( CostCentreStack *ccs, CostCentre *cc,
+ CostCentreStack *new_ccs );
+static rtsBool ccs_to_ignore ( CostCentreStack *ccs );
+static void count_ticks ( CostCentreStack *ccs );
+static void inherit_costs ( CostCentreStack *ccs );
+static void reportCCS ( CostCentreStack *ccs, nat indent );
+static void DecCCS ( CostCentreStack *ccs );
+static void DecBackEdge ( CostCentreStack *ccs,
+ CostCentreStack *oldccs );
+static CostCentreStack * CheckLoop ( CostCentreStack *ccs, CostCentre *cc );
+static CostCentreStack * pruneCCSTree ( CostCentreStack *ccs );
+static CostCentreStack * ActualPush ( CostCentreStack *, CostCentre * );
+static CostCentreStack * IsInIndexTable ( IndexTable *, CostCentre * );
+static IndexTable * AddToIndexTable ( IndexTable *, CostCentreStack *,
+ CostCentre *, unsigned int );
#ifdef DEBUG
static void printCCS ( CostCentreStack *ccs );
{
/* for the benefit of allocate()... */
CCCS = CCS_SYSTEM;
-
+
/* Initialize counters for IDs */
CC_ID = 1;
CCS_ID = 1;
static void
initProfilingLogFile(void)
{
- /* Initialise the log file name */
- prof_filename = stgMallocBytes(strlen(prog_argv[0]) + 6, "initProfiling");
- sprintf(prof_filename, "%s.prof", prog_argv[0]);
-
- /* open the log file */
- if ((prof_file = fopen(prof_filename, "w")) == NULL) {
- fprintf(stderr, "Can't open profiling report file %s\n", prof_filename);
- RtsFlags.CcFlags.doCostCentres = 0;
- return;
- }
+ /* Initialise the log file name */
+ prof_filename = stgMallocBytes(strlen(prog_argv[0]) + 6, "initProfiling");
+ sprintf(prof_filename, "%s.prof", prog_argv[0]);
+
+ /* open the log file */
+ if ((prof_file = fopen(prof_filename, "w")) == NULL) {
+ fprintf(stderr, "Can't open profiling report file %s\n", prof_filename);
+ RtsFlags.CcFlags.doCostCentres = 0;
+ return;
+ }
- if (RtsFlags.CcFlags.doCostCentres == COST_CENTRES_XML) {
- /* dump the time, and the profiling interval */
- fprintf(prof_file, "\"%s\"\n", time_str());
- fprintf(prof_file, "\"%d ms\"\n", TICK_MILLISECS);
+ if (RtsFlags.CcFlags.doCostCentres == COST_CENTRES_XML) {
+ /* dump the time, and the profiling interval */
+ fprintf(prof_file, "\"%s\"\n", time_str());
+ fprintf(prof_file, "\"%d ms\"\n", TICK_MILLISECS);
+
+ /* declare all the cost centres */
+ {
+ CostCentre *cc;
+ for (cc = CC_LIST; cc != NULL; cc = cc->link) {
+ fprintf(prof_file, "%d %d \"%s\" \"%s\"\n",
+ CC_UQ, cc->ccID, cc->label, cc->module);
+ }
+ }
+ }
- /* declare all the cost centres */
- {
- CostCentre *cc;
- for (cc = CC_LIST; cc != NULL; cc = cc->link) {
- fprintf(prof_file, "%d %d \"%s\" \"%s\"\n",
- CC_UQ, cc->ccID, cc->label, cc->module);
- }
+ if (RtsFlags.ProfFlags.doHeapProfile) {
+ /* Initialise the log file name */
+ hp_filename = stgMallocBytes(strlen(prog_argv[0]) + 6, "initProfiling");
+ sprintf(hp_filename, "%s.hp", prog_argv[0]);
+
+ /* open the log file */
+ if ((hp_file = fopen(hp_filename, "w")) == NULL) {
+ fprintf(stderr, "Can't open profiling report file %s\n",
+ hp_filename);
+ RtsFlags.ProfFlags.doHeapProfile = 0;
+ return;
+ }
}
- }
}
void
/* Initialise the various _scc_ counters to zero
*/
new_ccs->scc_count = 0;
- new_ccs->sub_scc_count = 0;
- new_ccs->sub_cafcc_count = 0;
/* Initialize all other stats here. There should be a quick way
* that's easily used elsewhere too
*/
new_ccs->time_ticks = 0;
new_ccs->mem_alloc = 0;
+ new_ccs->inherited_ticks = 0;
+ new_ccs->inherited_alloc = 0;
new_ccs->root = ccs->root;
}
-void
-print_ccs (FILE *fp, CostCentreStack *ccs)
-{
- if (ccs == CCCS) {
- fprintf(fp, "Cost-Centre Stack: ");
- }
-
- if (ccs != CCS_MAIN)
- {
- print_ccs(fp, ccs->prevStack);
- fprintf(fp, "->[%s,%s]", ccs->cc->label, ccs->cc->module);
- } else {
- fprintf(fp, "[%s,%s]", ccs->cc->label, ccs->cc->module);
- }
-
- if (ccs == CCCS) {
- fprintf(fp, "\n");
- }
-}
-
-
static void
DecCCS(CostCentreStack *ccs)
{
static void
fprint_header( void )
{
- fprintf(prof_file, "%-24s %-10s", "COST CENTRE", "MODULE");
+ fprintf(prof_file, "%-24s %-10s individual inherited\n", "", "");
- fprintf(prof_file, "%8s %5s %5s %8s %5s", "scc", "%time", "%alloc", "inner", "cafs");
+ fprintf(prof_file, "%-24s %-10s", "COST CENTRE", "MODULE");
+ fprintf(prof_file, "%8s %5s %5s %5s %5s", "entries", "%time", "%alloc", "%time", "%alloc");
if (RtsFlags.CcFlags.doCostCentres >= COST_CENTRES_VERBOSE) {
fprintf(prof_file, " %5s %9s", "ticks", "bytes");
report_per_cc_costs();
+ inherit_costs(CCS_MAIN);
+
fprint_header();
reportCCS(pruneCCSTree(CCS_MAIN), 0);
fprintf(prof_file, "%-*s%-*s %-10s",
indent, "", 24-indent, cc->label, cc->module);
- fprintf(prof_file, "%8ld %5.1f %5.1f %8ld %5ld",
+ fprintf(prof_file, "%8ld %5.1f %5.1f %5.1f %5.1f",
ccs->scc_count,
total_prof_ticks == 0 ? 0.0 : (ccs->time_ticks / (StgFloat) total_prof_ticks * 100),
total_alloc == 0 ? 0.0 : (ccs->mem_alloc / (StgFloat) total_alloc * 100),
- ccs->sub_scc_count, ccs->sub_cafcc_count);
-
+ total_prof_ticks == 0 ? 0.0 : (ccs->inherited_ticks / (StgFloat) total_prof_ticks * 100),
+ total_alloc == 0 ? 0.0 : (ccs->inherited_alloc / (StgFloat) total_alloc * 100)
+ );
+
if (RtsFlags.CcFlags.doCostCentres >= COST_CENTRES_VERBOSE) {
fprintf(prof_file, " %5ld %9ld", ccs->time_ticks, ccs->mem_alloc*sizeof(W_));
#if defined(PROFILING_DETAIL_COUNTS)
}
}
+/* Traverse the cost centre stack tree and inherit ticks & allocs.
+ */
+static void
+inherit_costs(CostCentreStack *ccs)
+{
+ IndexTable *i;
+
+ if (ccs_to_ignore(ccs)) { return; }
+
+ ccs->inherited_ticks += ccs->time_ticks;
+ ccs->inherited_alloc += ccs->mem_alloc;
+
+ for (i = ccs->indexTable; i != NULL; i = i->next)
+ if (!i->back_edge) {
+ inherit_costs(i->ccs);
+ ccs->inherited_ticks += i->ccs->inherited_ticks;
+ ccs->inherited_alloc += i->ccs->inherited_alloc;
+ }
+
+ return;
+}
+
/* return rtsTrue if it is one of the ones that
* should not be reported normally (because it confuses
* the users)
/* force printing of *all* cost centres if -P -P */ )
|| ( ccs->indexTable != 0 )
- || ( (ccs->scc_count || ccs->sub_scc_count ||
- ccs->time_ticks || ccs->mem_alloc
- || (RtsFlags.CcFlags.doCostCentres >= COST_CENTRES_VERBOSE
- && (ccs->sub_cafcc_count
-#if defined(PROFILING_DETAIL_COUNTS)
- || cc->thunk_count || cc->function_count || cc->pap_count
-#endif
- ))))) {
- return ccs;
+ || ( ccs->scc_count || ccs->time_ticks || ccs->mem_alloc )
+ ) {
+ return ccs;
} else {
- return NULL;
+ return NULL;
}
}
CostCentre *cc;
IndexTable *i;
+ if (ccs_to_ignore(ccs)) { return; }
+
cc = ccs->cc;
fprintf(prof_file, " 1 %d %lu %lu %lu",
}
}
+void
+print_ccs (FILE *fp, CostCentreStack *ccs)
+{
+ if (ccs == CCCS) {
+ fprintf(fp, "Cost-Centre Stack: ");
+ }
+
+ if (ccs != CCS_MAIN)
+ {
+ print_ccs(fp, ccs->prevStack);
+ fprintf(fp, "->[%s,%s]", ccs->cc->label, ccs->cc->module);
+ } else {
+ fprintf(fp, "[%s,%s]", ccs->cc->label, ccs->cc->module);
+ }
+
+ if (ccs == CCCS) {
+ fprintf(fp, "\n");
+ }
+}
+
+
#ifdef DEBUG
static void
printCCS ( CostCentreStack *ccs )