* simultaneous access by two STG threads.
*/
#ifdef SMP
-Mutex sm_mutex = INIT_MUTEX_VAR;
+Mutex sm_mutex;
#endif
/*
initMutex(&sm_mutex);
#endif
+ ACQUIRE_SM_LOCK;
+
/* allocate generation info array */
generations = (generation *)stgMallocBytes(RtsFlags.GcFlags.generations
* sizeof(struct generation_),
}
#ifdef SMP
- n_nurseries = RtsFlags.ParFlags.nNodes;
+ n_nurseries = n_capabilities;
nurseries = stgMallocBytes (n_nurseries * sizeof(struct step_),
"initStorage: nurseries");
#else
#ifdef SMP
if (RtsFlags.GcFlags.generations == 1) {
errorBelch("-G1 is incompatible with SMP");
- stg_exit(1);
+ stg_exit(EXIT_FAILURE);
}
#endif
mp_set_memory_functions(stgAllocForGMP, stgReallocForGMP, stgDeallocForGMP);
IF_DEBUG(gc, statDescribeGens());
+
+ RELEASE_SM_LOCK;
}
void
-------------------------------------------------------------------------- */
StgPtr
-allocateLocal( StgRegTable *reg, nat n )
+allocateLocal (Capability *cap, nat n)
{
bdescr *bd;
StgPtr p;
/* small allocation (<LARGE_OBJECT_THRESHOLD) */
} else {
- bd = reg->rCurrentAlloc;
+ bd = cap->r.rCurrentAlloc;
if (bd == NULL || bd->free + n > bd->start + BLOCK_SIZE_W) {
// The CurrentAlloc block is full, we need to find another
// one. First, we try taking the next block from the
// nursery:
- bd = reg->rCurrentNursery->link;
+ bd = cap->r.rCurrentNursery->link;
if (bd == NULL || bd->free + n > bd->start + BLOCK_SIZE_W) {
// The nursery is empty, or the next block is already
// full: allocate a fresh block (we can't fail here).
ACQUIRE_SM_LOCK;
bd = allocBlock();
- reg->rNursery->n_blocks++;
+ cap->r.rNursery->n_blocks++;
RELEASE_SM_LOCK;
bd->gen_no = 0;
- bd->step = g0s0;
+ bd->step = cap->r.rNursery;
bd->flags = 0;
} else {
// we have a block in the nursery: take it and put
// it at the *front* of the nursery list, and use it
// to allocate() from.
- reg->rCurrentNursery->link = bd->link;
+ cap->r.rCurrentNursery->link = bd->link;
if (bd->link != NULL) {
- bd->link->u.back = reg->rCurrentNursery;
+ bd->link->u.back = cap->r.rCurrentNursery;
}
}
- dbl_link_onto(bd, ®->rNursery->blocks);
- reg->rCurrentAlloc = bd;
- IF_DEBUG(sanity, checkNurserySanity(reg->rNursery));
+ dbl_link_onto(bd, &cap->r.rNursery->blocks);
+ cap->r.rCurrentAlloc = bd;
+ IF_DEBUG(sanity, checkNurserySanity(cap->r.rNursery));
}
}
p = bd->free;
}
/* -----------------------------------------------------------------------------
+ This is the write barrier for MUT_VARs, a.k.a. IORefs. A
+ MUT_VAR_CLEAN object is not on the mutable list; a MUT_VAR_DIRTY
+ is. When written to, a MUT_VAR_CLEAN turns into a MUT_VAR_DIRTY
+ and is put on the mutable list.
+ -------------------------------------------------------------------------- */
+
+void
+dirty_MUT_VAR(StgClosure *p)
+{
+ if (p->header.info == &stg_MUT_VAR_CLEAN_info) {
+ p->header.info = &stg_MUT_VAR_DIRTY_info;
+ recordMutable(p);
+ }
+}
+
+/* -----------------------------------------------------------------------------
Allocation functions for GMP.
These all use the allocate() interface - we can't have any garbage
/* allocate and fill it in. */
#if defined(SMP)
- arr = (StgArrWords *)allocateLocal(&(myCapability()->r), total_size_in_words);
+ arr = (StgArrWords *)allocateLocal(myTask()->cap, total_size_in_words);
#else
- arr = (StgArrWords *)allocateLocal(&MainCapability.r, total_size_in_words);
+ arr = (StgArrWords *)allocateLocal(&MainCapability, total_size_in_words);
#endif
SET_ARR_HDR(arr, &stg_ARR_WORDS_info, CCCS, data_size_in_words);
bdescr *bd;
total_blocks = stp->n_blocks;
+ total_blocks += stp->n_old_blocks;
for (bd = stp->large_objects; bd; bd = bd->link) {
total_blocks += bd->blocks;
/* hack for megablock groups: they have an extra block or two in
/* count the blocks we current have */
for (g = 0; g < RtsFlags.GcFlags.generations; g++) {
+ for (i = 0; i < n_capabilities; i++) {
+ for (bd = capabilities[i].mut_lists[g]; bd != NULL; bd = bd->link) {
+ total_blocks += bd->blocks;
+ }
+ }
for (bd = generations[g].mut_list; bd != NULL; bd = bd->link) {
total_blocks += bd->blocks;
}
for (i = 0; i < n_nurseries; i++) {
total_blocks += stepBlocks(&nurseries[i]);
}
-
- if (RtsFlags.GcFlags.generations == 1) {
- /* two-space collector has a to-space too :-) */
- total_blocks += g0s0->n_old_blocks;
- }
+#ifdef SMP
+ // We put pinned object blocks in g0s0, so better count blocks there too.
+ total_blocks += stepBlocks(g0s0);
+#endif
/* any blocks held by allocate() */
for (bd = small_alloc_list; bd; bd = bd->link) {