summaryrefslogtreecommitdiff
path: root/rts/sm/Storage.c
diff options
context:
space:
mode:
Diffstat (limited to 'rts/sm/Storage.c')
-rw-r--r--rts/sm/Storage.c70
1 files changed, 41 insertions, 29 deletions
diff --git a/rts/sm/Storage.c b/rts/sm/Storage.c
index be3badfbe4..fe7bf435eb 100644
--- a/rts/sm/Storage.c
+++ b/rts/sm/Storage.c
@@ -60,7 +60,7 @@ nursery *nurseries = NULL; /* array of nurseries, size == n_capabilities */
Mutex sm_mutex;
#endif
-static void allocNurseries ( void );
+static void allocNurseries (nat from, nat to);
static void
initGeneration (generation *gen, int g)
@@ -94,7 +94,7 @@ initGeneration (generation *gen, int g)
void
initStorage( void )
{
- nat g, n;
+ nat g;
if (generations != NULL) {
// multi-init protection
@@ -146,9 +146,6 @@ initStorage( void )
g0 = &generations[0];
oldest_gen = &generations[RtsFlags.GcFlags.generations-1];
- nurseries = stgMallocBytes(n_capabilities * sizeof(struct nursery_),
- "initStorage: nurseries");
-
/* Set up the destination pointers in each younger gen. step */
for (g = 0; g < RtsFlags.GcFlags.generations-1; g++) {
generations[g].to = &generations[g+1];
@@ -168,14 +165,6 @@ initStorage( void )
generations[0].max_blocks = 0;
- /* The allocation area. Policy: keep the allocation area
- * small to begin with, even if we have a large suggested heap
- * size. Reason: we're going to do a major collection first, and we
- * don't want it to be a big one. This vague idea is borne out by
- * rigorous experimental evidence.
- */
- allocNurseries();
-
weak_ptr_list = NULL;
caf_list = END_OF_STATIC_LIST;
revertible_caf_list = END_OF_STATIC_LIST;
@@ -192,20 +181,44 @@ initStorage( void )
N = 0;
- // allocate a block for each mut list
- for (n = 0; n < n_capabilities; n++) {
- for (g = 1; g < RtsFlags.GcFlags.generations; g++) {
- capabilities[n].mut_lists[g] = allocBlock();
- }
- }
-
- initGcThreads();
+ storageAddCapabilities(0, n_capabilities);
IF_DEBUG(gc, statDescribeGens());
RELEASE_SM_LOCK;
}
+void storageAddCapabilities (nat from, nat to)
+{
+ nat n, g;
+
+ if (from > 0) {
+ nurseries = stgReallocBytes(nurseries, to * sizeof(struct nursery_),
+ "storageAddCapabilities");
+ } else {
+ nurseries = stgMallocBytes(to * sizeof(struct nursery_),
+ "storageAddCapabilities");
+ }
+
+ /* The allocation area. Policy: keep the allocation area
+ * small to begin with, even if we have a large suggested heap
+ * size. Reason: we're going to do a major collection first, and we
+ * don't want it to be a big one. This vague idea is borne out by
+ * rigorous experimental evidence.
+ */
+ allocNurseries(from, to);
+
+ // allocate a block for each mut list
+ for (n = from; n < to; n++) {
+ for (g = 1; g < RtsFlags.GcFlags.generations; g++) {
+ capabilities[n].mut_lists[g] = allocBlock();
+ }
+ }
+
+ initGcThreads(from, to);
+}
+
+
void
exitStorage (void)
{
@@ -445,11 +458,11 @@ allocNursery (bdescr *tail, nat blocks)
}
static void
-assignNurseriesToCapabilities (void)
+assignNurseriesToCapabilities (nat from, nat to)
{
nat i;
- for (i = 0; i < n_capabilities; i++) {
+ for (i = from; i < to; i++) {
capabilities[i].r.rNursery = &nurseries[i];
capabilities[i].r.rCurrentNursery = nurseries[i].blocks;
capabilities[i].r.rCurrentAlloc = NULL;
@@ -457,17 +470,17 @@ assignNurseriesToCapabilities (void)
}
static void
-allocNurseries( void )
+allocNurseries (nat from, nat to)
{
nat i;
- for (i = 0; i < n_capabilities; i++) {
- nurseries[i].blocks =
+ for (i = from; i < to; i++) {
+ nurseries[i].blocks =
allocNursery(NULL, RtsFlags.GcFlags.minAllocAreaSize);
nurseries[i].n_blocks =
RtsFlags.GcFlags.minAllocAreaSize;
}
- assignNurseriesToCapabilities();
+ assignNurseriesToCapabilities(from, to);
}
lnat // words allocated
@@ -493,8 +506,7 @@ clearNurseries (void)
void
resetNurseries (void)
{
- assignNurseriesToCapabilities();
-
+ assignNurseriesToCapabilities(0, n_capabilities);
}
lnat