/* -----------------------------------------------------------------------------
- * $Id: Storage.c,v 1.74 2003/01/23 12:13:12 simonmar Exp $
+ * $Id: Storage.c,v 1.79 2003/03/26 18:59:34 sof Exp $
*
* (c) The GHC Team, 1998-1999
*
StgPtr alloc_Hp = NULL; /* next free byte in small_alloc_list */
StgPtr alloc_HpLim = NULL; /* end of block at small_alloc_list */
-generation *generations; /* all the generations */
-generation *g0; /* generation 0, for convenience */
-generation *oldest_gen; /* oldest generation, for convenience */
-step *g0s0; /* generation 0, step 0, for convenience */
+generation *generations = NULL; /* all the generations */
+generation *g0 = NULL; /* generation 0, for convenience */
+generation *oldest_gen = NULL; /* oldest generation, for convenience */
+step *g0s0 = NULL; /* generation 0, step 0, for convenience */
lnat total_allocated = 0; /* total memory allocated during run */
step *stp;
generation *gen;
- /* Sanity check to make sure the LOOKS_LIKE_ macros appear to be
- * doing something reasonable.
- */
- ASSERT(LOOKS_LIKE_INFO_PTR(&stg_BLACKHOLE_info));
- ASSERT(LOOKS_LIKE_CLOSURE_PTR(&stg_dummy_ret_closure));
- ASSERT(!HEAP_ALLOCED(&stg_dummy_ret_closure));
+ if (generations != NULL) {
+ // multi-init protection
+ return;
+ }
+ /* Sanity check to make sure the LOOKS_LIKE_ macros appear to be
+ * doing something reasonable.
+ */
+ ASSERT(LOOKS_LIKE_INFO_PTR(&stg_BLACKHOLE_info));
+ ASSERT(LOOKS_LIKE_CLOSURE_PTR(&stg_dummy_ret_closure));
+ ASSERT(!HEAP_ALLOCED(&stg_dummy_ret_closure));
+
if (RtsFlags.GcFlags.maxHeapSize != 0 &&
RtsFlags.GcFlags.heapSizeSuggestion >
RtsFlags.GcFlags.maxHeapSize) {
initBlockAllocator();
#if defined(SMP)
- initCondition(&sm_mutex);
+ initMutex(&sm_mutex);
#endif
/* allocate generation info array */
stp = &generations[g].steps[s];
stp->no = s;
stp->blocks = NULL;
+ stp->n_to_blocks = 0;
stp->n_blocks = 0;
stp->gen = &generations[g];
stp->gen_no = g;
/* Tell GNU multi-precision pkg about our custom alloc functions */
mp_set_memory_functions(stgAllocForGMP, stgReallocForGMP, stgDeallocForGMP);
-#if defined(SMP)
- initMutex(&sm_mutex);
-#endif
-
IF_DEBUG(gc, statDescribeGens());
}
allocNurseries( void )
{
#ifdef SMP
- {
- Capability *cap;
- bdescr *bd;
-
- g0s0->blocks = NULL;
- g0s0->n_blocks = 0;
- for (cap = free_capabilities; cap != NULL; cap = cap->link) {
- cap->r.rNursery = allocNursery(NULL, RtsFlags.GcFlags.minAllocAreaSize);
- cap->r.rCurrentNursery = cap->r.rNursery;
- for (bd = cap->r.rNursery; bd != NULL; bd = bd->link) {
- bd->u.back = (bdescr *)cap;
- }
- }
+ Capability *cap;
+ bdescr *bd;
+
+ g0s0->blocks = NULL;
+ g0s0->n_blocks = 0;
+ for (cap = free_capabilities; cap != NULL; cap = cap->link) {
+ cap->r.rNursery = allocNursery(NULL, RtsFlags.GcFlags.minAllocAreaSize);
+ cap->r.rCurrentNursery = cap->r.rNursery;
/* Set the back links to be equal to the Capability,
* so we can do slightly better informed locking.
*/
+ for (bd = cap->r.rNursery; bd != NULL; bd = bd->link) {
+ bd->u.back = (bdescr *)cap;
+ }
}
#else /* SMP */
g0s0->blocks = allocNursery(NULL, RtsFlags.GcFlags.minAllocAreaSize);
StgPtr p;
bdescr *bd = pinned_object_block;
- ACQUIRE_SM_LOCK;
-
- TICK_ALLOC_HEAP_NOCTR(n);
- CCS_ALLOC(CCCS,n);
-
// If the request is for a large object, then allocate()
// will give us a pinned object anyway.
if (n >= LARGE_OBJECT_THRESHOLD/sizeof(W_)) {
- RELEASE_SM_LOCK;
return allocate(n);
}
+ ACQUIRE_SM_LOCK;
+
+ TICK_ALLOC_HEAP_NOCTR(n);
+ CCS_ALLOC(CCCS,n);
+
// we always return 8-byte aligned memory. bd->free must be
// 8-byte aligned to begin with, so we just round up n to
// the nearest multiple of 8 bytes.
#ifdef PROFILING
if (RtsFlags.ProfFlags.doHeapProfile == HEAP_BY_RETAINER) {
- for (bd = firstStack; bd != NULL; bd = bd->link)
- total_blocks += bd->blocks;
+ total_blocks += retainerStackBlocks();
}
#endif