summaryrefslogtreecommitdiff
path: root/rts/sm/GC.c
diff options
context:
space:
mode:
authorSimon Marlow <marlowsd@gmail.com>2011-12-06 15:12:07 +0000
committerSimon Marlow <marlowsd@gmail.com>2011-12-06 16:00:27 +0000
commit92e7d6c92fdd14de424524564376d3522f2a40cc (patch)
tree5715d44012b452f5020ca14331a1fe50d5fd9600 /rts/sm/GC.c
parent8b75acd3ca25165536f18976c8d80cb62ad613e4 (diff)
downloadhaskell-92e7d6c92fdd14de424524564376d3522f2a40cc.tar.gz
Allow the number of capabilities to be increased at runtime (#3729)
At present the number of capabilities can only be *increased*, not decreased. The latter presents a few more challenges!
Diffstat (limited to 'rts/sm/GC.c')
-rw-r--r--rts/sm/GC.c50
1 files changed, 30 insertions, 20 deletions
diff --git a/rts/sm/GC.c b/rts/sm/GC.c
index a4ac1fb01d..d30300d363 100644
--- a/rts/sm/GC.c
+++ b/rts/sm/GC.c
@@ -260,7 +260,7 @@ GarbageCollect (rtsBool force_major_gc,
* it with +RTS -gn0), or mark/compact/sweep GC.
*/
if (gc_type == SYNC_GC_PAR) {
- n_gc_threads = RtsFlags.ParFlags.nNodes;
+ n_gc_threads = n_capabilities;
} else {
n_gc_threads = 1;
}
@@ -854,29 +854,39 @@ new_gc_thread (nat n, gc_thread *t)
void
-initGcThreads (void)
+initGcThreads (nat from USED_IF_THREADS, nat to USED_IF_THREADS)
{
- if (gc_threads == NULL) {
#if defined(THREADED_RTS)
- nat i;
- gc_threads = stgMallocBytes (RtsFlags.ParFlags.nNodes *
- sizeof(gc_thread*),
- "alloc_gc_threads");
+ nat i;
- for (i = 0; i < RtsFlags.ParFlags.nNodes; i++) {
- gc_threads[i] =
- stgMallocBytes(sizeof(gc_thread) +
- RtsFlags.GcFlags.generations * sizeof(gen_workspace),
- "alloc_gc_threads");
+ if (from > 0) {
+ gc_threads = stgReallocBytes (gc_threads, to * sizeof(gc_thread*),
+ "initGcThreads");
+ } else {
+ gc_threads = stgMallocBytes (to * sizeof(gc_thread*),
+ "initGcThreads");
+ }
- new_gc_thread(i, gc_threads[i]);
- }
+ // We have to update the gct->cap pointers to point to the new
+ // Capability array now.
+ for (i = 0; i < from; i++) {
+ gc_threads[i]->cap = &capabilities[gc_threads[i]->cap->no];
+ }
+
+ for (i = from; i < to; i++) {
+ gc_threads[i] =
+ stgMallocBytes(sizeof(gc_thread) +
+ RtsFlags.GcFlags.generations * sizeof(gen_workspace),
+ "alloc_gc_threads");
+
+ new_gc_thread(i, gc_threads[i]);
+ }
#else
- gc_threads = stgMallocBytes (sizeof(gc_thread*),"alloc_gc_threads");
- gc_threads[0] = gct;
- new_gc_thread(0,gc_threads[0]);
+ ASSERT(from == 0 && to == 1);
+ gc_threads = stgMallocBytes (sizeof(gc_thread*),"alloc_gc_threads");
+ gc_threads[0] = gct;
+ new_gc_thread(0,gc_threads[0]);
#endif
- }
}
void
@@ -1097,7 +1107,7 @@ gcWorkerThread (Capability *cap)
void
waitForGcThreads (Capability *cap USED_IF_THREADS)
{
- const nat n_threads = RtsFlags.ParFlags.nNodes;
+ const nat n_threads = n_capabilities;
const nat me = cap->no;
nat i, j;
rtsBool retry = rtsTrue;
@@ -1178,7 +1188,7 @@ shutdown_gc_threads (nat me USED_IF_THREADS)
void
releaseGCThreads (Capability *cap USED_IF_THREADS)
{
- const nat n_threads = RtsFlags.ParFlags.nNodes;
+ const nat n_threads = n_capabilities;
const nat me = cap->no;
nat i;
for (i=0; i < n_threads; i++) {