summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--includes/InfoTables.h10
-rw-r--r--includes/RtsFlags.h3
-rw-r--r--rts/Arena.c6
-rw-r--r--rts/Makefile2
-rw-r--r--rts/ProfHeap.c220
-rw-r--r--rts/Profiling.h10
-rw-r--r--rts/Proftimer.c6
-rw-r--r--rts/RtsFlags.c28
-rw-r--r--rts/RtsStartup.c11
-rw-r--r--rts/RtsUtils.c2
-rw-r--r--rts/Schedule.c47
-rw-r--r--rts/Timer.c5
12 files changed, 166 insertions, 184 deletions
diff --git a/includes/InfoTables.h b/includes/InfoTables.h
index 77171f1bc0..67bd97bc8f 100644
--- a/includes/InfoTables.h
+++ b/includes/InfoTables.h
@@ -412,6 +412,16 @@ typedef struct _StgConInfoTable {
#endif
/*
+ * GET_CON_DESC(info)
+ * info must be a StgConInfoTable*.
+ */
+#ifdef TABLES_NEXT_TO_CODE
+#define GET_CON_DESC(info) ((char *)((StgWord)((info)+1) + (info->con_desc)))
+#else
+#define GET_CON_DESC(info) ((info)->con_desc)
+#endif
+
+/*
* GET_FUN_SRT(info)
* info must be a StgFunInfoTable*
*/
diff --git a/includes/RtsFlags.h b/includes/RtsFlags.h
index f7f79b6980..4bfe27636a 100644
--- a/includes/RtsFlags.h
+++ b/includes/RtsFlags.h
@@ -86,8 +86,7 @@ struct PROFILING_FLAGS {
# define HEAP_BY_RETAINER 6
# define HEAP_BY_LDV 7
-# define HEAP_BY_INFOPTR 1 /* DEBUG only */
-# define HEAP_BY_CLOSURE_TYPE 2 /* DEBUG only */
+# define HEAP_BY_CLOSURE_TYPE 8
nat profileInterval; /* delta between samples (in ms) */
nat profileIntervalTicks; /* delta between samples (in 'ticks') */
diff --git a/rts/Arena.c b/rts/Arena.c
index b2b5ce2d5a..fcdc6cce14 100644
--- a/rts/Arena.c
+++ b/rts/Arena.c
@@ -42,7 +42,7 @@ newArena( void )
Arena *arena;
arena = stgMallocBytes(sizeof(Arena), "newArena");
- arena->current = allocBlock();
+ arena->current = allocBlock_lock();
arena->current->link = NULL;
arena->free = arena->current->start;
arena->lim = arena->current->start + BLOCK_SIZE_W;
@@ -81,7 +81,7 @@ arenaAlloc( Arena *arena, size_t size )
} else {
// allocate a fresh block...
req_blocks = (lnat)BLOCK_ROUND_UP(size) / BLOCK_SIZE;
- bd = allocGroup(req_blocks);
+ bd = allocGroup_lock(req_blocks);
arena_blocks += req_blocks;
bd->gen_no = 0;
@@ -106,7 +106,7 @@ arenaFree( Arena *arena )
next = bd->link;
arena_blocks -= bd->blocks;
ASSERT(arena_blocks >= 0);
- freeGroup(bd);
+ freeGroup_lock(bd);
}
stgFree(arena);
}
diff --git a/rts/Makefile b/rts/Makefile
index 6bf42712cb..184a8440cc 100644
--- a/rts/Makefile
+++ b/rts/Makefile
@@ -35,7 +35,7 @@ WAYS=$(GhcLibWays) $(GhcRTSWays)
ifneq "$(findstring debug, $(way))" ""
GhcRtsHcOpts=
-GhcRtsCcOpts=-g
+GhcRtsCcOpts=-g -O0
endif
# -----------------------------------------------------------------------------
diff --git a/rts/ProfHeap.c b/rts/ProfHeap.c
index ea71e20fd4..dfa00677fd 100644
--- a/rts/ProfHeap.c
+++ b/rts/ProfHeap.c
@@ -1,18 +1,10 @@
-/* -----------------------------------------------------------------------------
+/* ----------------------------------------------------------------------------
*
* (c) The GHC Team, 1998-2003
*
* Support for heap profiling
*
- * ---------------------------------------------------------------------------*/
-
-#if defined(DEBUG) && !defined(PROFILING)
-#define DEBUG_HEAP_PROF
-#else
-#undef DEBUG_HEAP_PROF
-#endif
-
-#if defined(PROFILING) || defined(DEBUG_HEAP_PROF)
+ * --------------------------------------------------------------------------*/
#include "PosixSource.h"
#include "Rts.h"
@@ -103,70 +95,86 @@ static void aggregateCensusInfo( void );
static void dumpCensus( Census *census );
-/* -----------------------------------------------------------------------------
+/* ----------------------------------------------------------------------------
Closure Type Profiling;
+ ------------------------------------------------------------------------- */
- PROBABLY TOTALLY OUT OF DATE -- ToDo (SDM)
- -------------------------------------------------------------------------- */
-
-#ifdef DEBUG_HEAP_PROF
static char *type_names[] = {
- "INVALID_OBJECT"
- , "CONSTR"
- , "CONSTR_STATIC"
- , "CONSTR_NOCAF_STATIC"
-
- , "FUN"
- , "FUN_STATIC"
-
- , "THUNK"
- , "THUNK_STATIC"
- , "THUNK_SELECTOR"
-
- , "BCO"
- , "AP_STACK"
- , "AP"
-
- , "PAP"
-
- , "IND"
- , "IND_OLDGEN"
- , "IND_PERM"
- , "IND_OLDGEN_PERM"
- , "IND_STATIC"
-
- , "RET_BCO"
- , "RET_SMALL"
- , "RET_BIG"
- , "RET_DYN"
- , "UPDATE_FRAME"
- , "CATCH_FRAME"
- , "STOP_FRAME"
-
- , "BLACKHOLE"
- , "MVAR"
-
- , "ARR_WORDS"
-
- , "MUT_ARR_PTRS_CLEAN"
- , "MUT_ARR_PTRS_DIRTY"
- , "MUT_ARR_PTRS_FROZEN"
- , "MUT_VAR_CLEAN"
- , "MUT_VAR_DIRTY"
-
- , "WEAK"
-
- , "TSO"
-
- , "BLOCKED_FETCH"
- , "FETCH_ME"
-
- , "EVACUATED"
-};
-
-#endif /* DEBUG_HEAP_PROF */
-
-/* -----------------------------------------------------------------------------
+ "INVALID_OBJECT",
+ "CONSTR",
+ "CONSTR_1_0",
+ "CONSTR_0_1",
+ "CONSTR_2_0",
+ "CONSTR_1_1",
+ "CONSTR_0_2",
+ "CONSTR_STATIC",
+ "CONSTR_NOCAF_STATIC",
+ "FUN",
+ "FUN_1_0",
+ "FUN_0_1",
+ "FUN_2_0",
+ "FUN_1_1",
+ "FUN_0_2",
+ "FUN_STATIC",
+ "THUNK",
+ "THUNK_1_0",
+ "THUNK_0_1",
+ "THUNK_2_0",
+ "THUNK_1_1",
+ "THUNK_0_2",
+ "THUNK_STATIC",
+ "THUNK_SELECTOR",
+ "BCO",
+ "AP",
+ "PAP",
+ "AP_STACK",
+ "IND",
+ "IND_OLDGEN",
+ "IND_PERM",
+ "IND_OLDGEN_PERM",
+ "IND_STATIC",
+ "RET_BCO",
+ "RET_SMALL",
+ "RET_BIG",
+ "RET_DYN",
+ "RET_FUN",
+ "UPDATE_FRAME",
+ "CATCH_FRAME",
+ "STOP_FRAME",
+ "CAF_BLACKHOLE",
+ "BLACKHOLE",
+ "SE_BLACKHOLE",
+ "SE_CAF_BLACKHOLE",
+ "MVAR",
+ "ARR_WORDS",
+ "MUT_ARR_PTRS_CLEAN",
+ "MUT_ARR_PTRS_DIRTY",
+ "MUT_ARR_PTRS_FROZEN0",
+ "MUT_ARR_PTRS_FROZEN",
+ "MUT_VAR_CLEAN",
+ "MUT_VAR_DIRTY",
+ "WEAK",
+ "STABLE_NAME",
+ "TSO",
+ "BLOCKED_FETCH",
+ "FETCH_ME",
+ "FETCH_ME_BQ",
+ "RBH",
+ "EVACUATED",
+ "REMOTE_REF",
+ "TVAR_WATCH_QUEUE",
+ "INVARIANT_CHECK_QUEUE",
+ "ATOMIC_INVARIANT",
+ "TVAR",
+ "TREC_CHUNK",
+ "TREC_HEADER",
+ "ATOMICALLY_FRAME",
+ "CATCH_RETRY_FRAME",
+ "CATCH_STM_FRAME",
+ "N_CLOSURE_TYPES"
+ };
+
+/* ----------------------------------------------------------------------------
* Find the "closure identity", which is a unique pointer reresenting
* the band to which this closure's heap space is attributed in the
* heap profile.
@@ -193,11 +201,26 @@ closureIdentity( StgClosure *p )
else
return NULL;
-#else // DEBUG
- case HEAP_BY_INFOPTR:
- return (void *)((StgClosure *)p)->header.info;
+#else
case HEAP_BY_CLOSURE_TYPE:
- return type_names[get_itbl(p)->type];
+ {
+ StgInfoTable *info;
+ info = get_itbl(p);
+ switch (info->type) {
+ case CONSTR:
+ case CONSTR_1_0:
+ case CONSTR_0_1:
+ case CONSTR_2_0:
+ case CONSTR_1_1:
+ case CONSTR_0_2:
+ case CONSTR_STATIC:
+ case CONSTR_NOCAF_STATIC:
+ printf("",strlen(GET_CON_DESC(itbl_to_con_itbl(info))));
+ return GET_CON_DESC(itbl_to_con_itbl(info));
+ default:
+ return type_names[info->type];
+ }
+ }
#endif
default:
@@ -300,6 +323,7 @@ LDV_recordDead( StgClosure *c, nat size )
/* --------------------------------------------------------------------------
* Initialize censuses[era];
* ----------------------------------------------------------------------- */
+
STATIC_INLINE void
initEra(Census *census)
{
@@ -325,6 +349,7 @@ freeEra(Census *census)
* Increases era by 1 and initialize census[era].
* Reallocates gi[] and increases its size if needed.
* ----------------------------------------------------------------------- */
+
static void
nextEra( void )
{
@@ -348,23 +373,23 @@ nextEra( void )
initEra( &censuses[era] );
}
-/* -----------------------------------------------------------------------------
- * DEBUG heap profiling, by info table
- * -------------------------------------------------------------------------- */
+/* ----------------------------------------------------------------------------
+ * Heap profiling by info table
+ * ------------------------------------------------------------------------- */
-#ifdef DEBUG_HEAP_PROF
+#if !defined(PROFILNG)
FILE *hp_file;
static char *hp_filename;
-void initProfiling1( void )
+void initProfiling1 (void)
{
}
-void freeProfiling1( void )
+void freeProfiling1 (void)
{
}
-void initProfiling2( void )
+void initProfiling2 (void)
{
if (RtsFlags.ProfFlags.doHeapProfile) {
/* Initialise the log file name */
@@ -387,7 +412,7 @@ void endProfiling( void )
{
endHeapProfiling();
}
-#endif /* DEBUG_HEAP_PROF */
+#endif /* !PROFILING */
static void
printSample(rtsBool beginSample, StgDouble sampleValue)
@@ -463,10 +488,6 @@ initHeapProfiling(void)
printSample(rtsTrue, 0);
printSample(rtsFalse, 0);
-#ifdef DEBUG_HEAP_PROF
- DEBUG_LoadSymbols(prog_name);
-#endif
-
#ifdef PROFILING
if (doingRetainerProfiling()) {
initRetainerProfiling();
@@ -603,7 +624,7 @@ strMatchesSelector( char* str, char* sel )
rtsBool
closureSatisfiesConstraints( StgClosure* p )
{
-#ifdef DEBUG_HEAP_PROF
+#if !defined(PROFILING)
(void)p; /* keep gcc -Wall happy */
return rtsTrue;
#else
@@ -808,11 +829,8 @@ dumpCensus( Census *census )
if (count == 0) continue;
-#ifdef DEBUG_HEAP_PROF
+#if !defined(PROFILING)
switch (RtsFlags.ProfFlags.doHeapProfile) {
- case HEAP_BY_INFOPTR:
- fprintf(hp_file, "%s", lookupGHCName(ctr->identity));
- break;
case HEAP_BY_CLOSURE_TYPE:
fprintf(hp_file, "%s", (char *)ctr->identity);
break;
@@ -984,10 +1002,7 @@ heapCensusChain( Census *census, bdescr *bd )
case TSO:
prim = rtsTrue;
-#ifdef DEBUG_HEAP_PROF
- size = tso_sizeW((StgTSO *)p);
- break;
-#else
+#ifdef PROFILING
if (RtsFlags.ProfFlags.includeTSOs) {
size = tso_sizeW((StgTSO *)p);
break;
@@ -996,6 +1011,9 @@ heapCensusChain( Census *census, bdescr *bd )
p += tso_sizeW((StgTSO *)p);
continue;
}
+#else
+ size = tso_sizeW((StgTSO *)p);
+ break;
#endif
case TREC_HEADER:
@@ -1034,11 +1052,11 @@ heapCensusChain( Census *census, bdescr *bd )
identity = NULL;
-#ifdef DEBUG_HEAP_PROF
- real_size = size;
-#else
+#ifdef PROFILING
// subtract the profiling overhead
real_size = size - sizeofW(StgProfHeader);
+#else
+ real_size = size;
#endif
if (closureSatisfiesConstraints((StgClosure*)p)) {
@@ -1158,13 +1176,13 @@ heapCensus( void )
// future restriction by biography.
#ifdef PROFILING
if (RtsFlags.ProfFlags.bioSelector == NULL)
-#endif
{
freeHashTable( census->hash, NULL/* don't free the elements */ );
arenaFree( census->arena );
census->hash = NULL;
census->arena = NULL;
}
+#endif
// we're into the next time period now
nextEra();
@@ -1174,5 +1192,3 @@ heapCensus( void )
#endif
}
-#endif /* PROFILING || DEBUG_HEAP_PROF */
-
diff --git a/rts/Profiling.h b/rts/Profiling.h
index edfc1b2c5e..8961da9b17 100644
--- a/rts/Profiling.h
+++ b/rts/Profiling.h
@@ -11,15 +11,13 @@
#include <stdio.h>
-#if defined(PROFILING) || defined(DEBUG)
-void initProfiling1 ( void );
-void freeProfiling1 ( void );
-void initProfiling2 ( void );
-void endProfiling ( void );
+void initProfiling1 (void);
+void freeProfiling1 (void);
+void initProfiling2 (void);
+void endProfiling (void);
extern FILE *prof_file;
extern FILE *hp_file;
-#endif
#ifdef PROFILING
diff --git a/rts/Proftimer.c b/rts/Proftimer.c
index ce20c491af..32e5c56073 100644
--- a/rts/Proftimer.c
+++ b/rts/Proftimer.c
@@ -6,8 +6,6 @@
*
* ---------------------------------------------------------------------------*/
-#if defined (PROFILING)
-
#include "PosixSource.h"
#include "Rts.h"
@@ -66,9 +64,11 @@ initProfTimer( void )
void
handleProfTick(void)
{
+#ifdef PROFILING
if (do_prof_ticks) {
CCCS->time_ticks++;
}
+#endif
if (do_heap_prof_ticks) {
ticks_to_heap_profile--;
@@ -78,5 +78,3 @@ handleProfTick(void)
}
}
}
-
-#endif /* PROFILING */
diff --git a/rts/RtsFlags.c b/rts/RtsFlags.c
index 58b69aff49..1cf7700b51 100644
--- a/rts/RtsFlags.c
+++ b/rts/RtsFlags.c
@@ -172,9 +172,10 @@ void initRtsFlagsDefaults(void)
RtsFlags.CcFlags.doCostCentres = 0;
#endif /* PROFILING or PAR */
-#ifdef PROFILING
RtsFlags.ProfFlags.doHeapProfile = rtsFalse;
RtsFlags.ProfFlags.profileInterval = 100;
+
+#ifdef PROFILING
RtsFlags.ProfFlags.includeTSOs = rtsFalse;
RtsFlags.ProfFlags.showCCSOnException = rtsFalse;
RtsFlags.ProfFlags.maxRetainerSetSize = 8;
@@ -186,9 +187,6 @@ void initRtsFlagsDefaults(void)
RtsFlags.ProfFlags.ccsSelector = NULL;
RtsFlags.ProfFlags.retainerSelector = NULL;
RtsFlags.ProfFlags.bioSelector = NULL;
-
-#elif defined(DEBUG)
- RtsFlags.ProfFlags.doHeapProfile = rtsFalse;
#endif
RtsFlags.MiscFlags.tickInterval = 50; /* In milliseconds */
@@ -382,20 +380,17 @@ usage_text[] = {
" -L<chars> Maximum length of a cost-centre stack in a heap profile",
" (default: 25)",
"",
-" -i<sec> Time between heap samples (seconds, default: 0.1)",
-"",
" -xt Include threads (TSOs) in a heap profile",
"",
" -xc Show current cost centre stack on raising an exception",
+"",
# endif
#endif /* PROFILING or PAR */
-#if !defined(PROFILING) && defined(DEBUG)
+#if !defined(PROFILING)
"",
-" -h<break-down> Debugging Heap residency profile",
-" (output file <program>.hp)",
-" break-down: L = closure label (default)",
-" T = closure type (constructor, thunk etc.)",
+" -hT Heap residency profile (output file <program>.hp)",
#endif
+" -i<sec> Time between heap samples (seconds, default: 0.1)",
"",
#if defined(TICKY_TICKY)
" -r<file> Produce ticky-ticky statistics (with -rstderr for stderr)",
@@ -936,12 +931,9 @@ error = rtsTrue;
}
) break;
case 'h': /* serial heap profile */
-#if !defined(PROFILING) && defined(DEBUG)
+#if !defined(PROFILING)
switch (rts_argv[arg][2]) {
case '\0':
- case 'L':
- RtsFlags.ProfFlags.doHeapProfile = HEAP_BY_INFOPTR;
- break;
case 'T':
RtsFlags.ProfFlags.doHeapProfile = HEAP_BY_CLOSURE_TYPE;
break;
@@ -1057,7 +1049,6 @@ error = rtsTrue;
#endif /* PROFILING */
break;
-#if defined(PROFILING)
case 'i': /* heap sample interval */
if (rts_argv[arg][2] == '\0') {
/* use default */
@@ -1069,7 +1060,6 @@ error = rtsTrue;
RtsFlags.ProfFlags.profileInterval = cst;
}
break;
-#endif
/* =========== CONCURRENT ========================= */
case 'C': /* context switch interval */
@@ -1251,13 +1241,11 @@ error = rtsTrue;
RtsFlags.MiscFlags.tickInterval);
}
-#ifdef PROFILING
if (RtsFlags.ProfFlags.profileInterval > 0) {
RtsFlags.MiscFlags.tickInterval =
stg_min(RtsFlags.ProfFlags.profileInterval,
RtsFlags.MiscFlags.tickInterval);
}
-#endif
if (RtsFlags.ConcFlags.ctxtSwitchTime > 0) {
RtsFlags.ConcFlags.ctxtSwitchTicks =
@@ -1267,10 +1255,8 @@ error = rtsTrue;
RtsFlags.ConcFlags.ctxtSwitchTicks = 0;
}
-#ifdef PROFILING
RtsFlags.ProfFlags.profileIntervalTicks =
RtsFlags.ProfFlags.profileInterval / RtsFlags.MiscFlags.tickInterval;
-#endif
if (error) {
const char **p;
diff --git a/rts/RtsStartup.c b/rts/RtsStartup.c
index 85b1c020fb..1d0fec5dd7 100644
--- a/rts/RtsStartup.c
+++ b/rts/RtsStartup.c
@@ -38,8 +38,9 @@
#include "FrontPanel.h"
#endif
-#if defined(PROFILING) || defined(DEBUG)
# include "Profiling.h"
+
+#if defined(PROFILING)
# include "ProfHeap.h"
# include "RetainerProfile.h"
#endif
@@ -244,9 +245,7 @@ hs_init(int *argc, char **argv[])
initThreadLabelTable();
#endif
-#if defined(PROFILING) || defined(DEBUG)
initProfiling1();
-#endif
/* start the virtual timer 'subsystem'. */
startTimer();
@@ -353,11 +352,9 @@ hs_add_root(void (*init_root)(void))
startupHpc();
-#if defined(PROFILING) || defined(DEBUG)
// This must be done after module initialisation.
// ToDo: make this work in the presence of multiple hs_add_root()s.
initProfiling2();
-#endif
}
/* -----------------------------------------------------------------------------
@@ -455,9 +452,7 @@ hs_exit(void)
/* free the stable pointer table */
exitStablePtrTable();
-#if defined(PROFILING) || defined(DEBUG)
freeProfiling1();
-#endif
#if defined(DEBUG)
/* free the thread label table */
@@ -477,9 +472,7 @@ hs_exit(void)
reportCCSProfiling();
#endif
-#if defined(PROFILING) || defined(DEBUG)
endProfiling();
-#endif
#ifdef PROFILING
// Originally, this was in report_ccs_profiling(). Now, retainer
diff --git a/rts/RtsUtils.c b/rts/RtsUtils.c
index 7048e94cd0..94c357e5ba 100644
--- a/rts/RtsUtils.c
+++ b/rts/RtsUtils.c
@@ -316,7 +316,6 @@ resetGenSymZh(void) /* it's your funeral */
Get the current time as a string. Used in profiling reports.
-------------------------------------------------------------------------- */
-#if defined(PROFILING) || defined(DEBUG) || defined(PAR) || defined(GRAN)
char *
time_str(void)
{
@@ -335,7 +334,6 @@ time_str(void)
}
return nowstr;
}
-#endif
/* -----------------------------------------------------------------------------
* Reset a file handle to blocking mode. We do this for the standard
diff --git a/rts/Schedule.c b/rts/Schedule.c
index 3d87003756..6063fcdc41 100644
--- a/rts/Schedule.c
+++ b/rts/Schedule.c
@@ -28,10 +28,8 @@
#include "ThreadLabels.h"
#include "LdvProfile.h"
#include "Updates.h"
-#ifdef PROFILING
#include "Proftimer.h"
#include "ProfHeap.h"
-#endif
#if defined(GRAN) || defined(PARALLEL_HASKELL)
# include "GranSimRts.h"
# include "GranSim.h"
@@ -216,7 +214,7 @@ static rtsBool scheduleHandleYield( Capability *cap, StgTSO *t,
static void scheduleHandleThreadBlocked( StgTSO *t );
static rtsBool scheduleHandleThreadFinished( Capability *cap, Task *task,
StgTSO *t );
-static rtsBool scheduleDoHeapProfile(rtsBool ready_to_gc);
+static rtsBool scheduleNeedHeapProfile(rtsBool ready_to_gc);
static Capability *scheduleDoGC(Capability *cap, Task *task,
rtsBool force_major);
@@ -572,9 +570,7 @@ run_thread:
debugTrace(DEBUG_sched, "-->> running thread %ld %s ...",
(long)t->id, whatNext_strs[t->what_next]);
-#if defined(PROFILING)
startHeapProfTimer();
-#endif
// Check for exceptions blocked on this thread
maybePerformBlockedException (cap, t);
@@ -667,8 +663,8 @@ run_thread:
// ----------------------------------------------------------------------
// Costs for the scheduler are assigned to CCS_SYSTEM
-#if defined(PROFILING)
stopHeapProfTimer();
+#if defined(PROFILING)
CCCS = CCS_SYSTEM;
#endif
@@ -705,8 +701,7 @@ run_thread:
barf("schedule: invalid thread return code %d", (int)ret);
}
- if (scheduleDoHeapProfile(ready_to_gc)) { ready_to_gc = rtsFalse; }
- if (ready_to_gc) {
+ if (ready_to_gc || scheduleNeedHeapProfile(ready_to_gc)) {
cap = scheduleDoGC(cap,task,rtsFalse);
}
} /* end of while() */
@@ -1920,36 +1915,21 @@ scheduleHandleThreadFinished (Capability *cap STG_UNUSED, Task *task, StgTSO *t)
}
/* -----------------------------------------------------------------------------
- * Perform a heap census, if PROFILING
+ * Perform a heap census
* -------------------------------------------------------------------------- */
static rtsBool
-scheduleDoHeapProfile( rtsBool ready_to_gc STG_UNUSED )
+scheduleNeedHeapProfile( rtsBool ready_to_gc STG_UNUSED )
{
-#if defined(PROFILING)
// When we have +RTS -i0 and we're heap profiling, do a census at
// every GC. This lets us get repeatable runs for debugging.
if (performHeapProfile ||
(RtsFlags.ProfFlags.profileInterval==0 &&
RtsFlags.ProfFlags.doHeapProfile && ready_to_gc)) {
-
- // checking black holes is necessary before GC, otherwise
- // there may be threads that are unreachable except by the
- // blackhole queue, which the GC will consider to be
- // deadlocked.
- scheduleCheckBlackHoles(&MainCapability);
-
- debugTrace(DEBUG_sched, "garbage collecting before heap census");
- GarbageCollect(rtsTrue);
-
- debugTrace(DEBUG_sched, "performing heap census");
- heapCensus();
-
- performHeapProfile = rtsFalse;
- return rtsTrue; // true <=> we already GC'd
+ return rtsTrue;
+ } else {
+ return rtsFalse;
}
-#endif
- return rtsFalse;
}
/* -----------------------------------------------------------------------------
@@ -1960,6 +1940,7 @@ static Capability *
scheduleDoGC (Capability *cap, Task *task USED_IF_THREADS, rtsBool force_major)
{
StgTSO *t;
+ rtsBool heap_census;
#ifdef THREADED_RTS
static volatile StgWord waiting_for_gc;
rtsBool was_waiting;
@@ -2067,6 +2048,8 @@ scheduleDoGC (Capability *cap, Task *task USED_IF_THREADS, rtsBool force_major)
deleteAllThreads(&capabilities[0]);
sched_state = SCHED_SHUTTING_DOWN;
}
+
+ heap_census = scheduleNeedHeapProfile(rtsTrue);
/* everybody back, start the GC.
* Could do it in this thread, or signal a condition var
@@ -2076,8 +2059,14 @@ scheduleDoGC (Capability *cap, Task *task USED_IF_THREADS, rtsBool force_major)
#if defined(THREADED_RTS)
debugTrace(DEBUG_sched, "doing GC");
#endif
- GarbageCollect(force_major);
+ GarbageCollect(force_major || heap_census);
+ if (heap_census) {
+ debugTrace(DEBUG_sched, "performing heap census");
+ heapCensus();
+ performHeapProfile = rtsFalse;
+ }
+
#if defined(THREADED_RTS)
// release our stash of capabilities.
for (i = 0; i < n_capabilities; i++) {
diff --git a/rts/Timer.c b/rts/Timer.c
index 493fe3d35f..05d1fecdc7 100644
--- a/rts/Timer.c
+++ b/rts/Timer.c
@@ -42,9 +42,7 @@ static
void
handle_tick(int unused STG_UNUSED)
{
-#ifdef PROFILING
handleProfTick();
-#endif
if (RtsFlags.ConcFlags.ctxtSwitchTicks > 0) {
ticks_to_ctxt_switch--;
if (ticks_to_ctxt_switch <= 0) {
@@ -86,10 +84,7 @@ handle_tick(int unused STG_UNUSED)
void
startTimer(void)
{
-#ifdef PROFILING
initProfTimer();
-#endif
-
startTicker(RtsFlags.MiscFlags.tickInterval, handle_tick);
}