diff options
author | Ben Gamari <ben@smart-cactus.org> | 2022-11-09 12:39:47 -0500 |
---|---|---|
committer | Zubin Duggal <zubin.duggal@gmail.com> | 2023-02-08 14:54:08 +0530 |
commit | 804cd4c7c543946d8fa61edb658019227bb39134 (patch) | |
tree | 639282db91260a39025e69c1e67d2c2dd2943268 | |
parent | 67ec973ce40d8a66d48c0f5f40458380957b6e6f (diff) | |
download | haskell-804cd4c7c543946d8fa61edb658019227bb39134.tar.gz |
rts: Introduce getNumCapabilities
And ensure accesses to n_capabilities are atomic (although with relaxed
ordering). This is necessary as RTS API callers may concurrently call
into the RTS without holding a capability.
(cherry picked from commit 70999283156f527c5aea6dee57a3d14989a9903a)
-rw-r--r-- | includes/rts/Threads.h | 7 | ||||
-rw-r--r-- | rts/Capability.c | 18 | ||||
-rw-r--r-- | rts/Messages.h | 2 | ||||
-rw-r--r-- | rts/PrimOps.cmm | 4 | ||||
-rw-r--r-- | rts/Printer.c | 8 | ||||
-rw-r--r-- | rts/ProfHeap.c | 2 | ||||
-rw-r--r-- | rts/ProfilerReport.c | 4 | ||||
-rw-r--r-- | rts/ProfilerReportJson.c | 2 | ||||
-rw-r--r-- | rts/Profiling.c | 2 | ||||
-rw-r--r-- | rts/Proftimer.c | 2 | ||||
-rw-r--r-- | rts/RetainerProfile.c | 2 | ||||
-rw-r--r-- | rts/RtsAPI.c | 4 | ||||
-rw-r--r-- | rts/RtsStartup.c | 2 | ||||
-rw-r--r-- | rts/SMPClosureOps.h | 8 | ||||
-rw-r--r-- | rts/STM.c | 2 | ||||
-rw-r--r-- | rts/Schedule.c | 24 | ||||
-rw-r--r-- | rts/Stats.c | 8 | ||||
-rw-r--r-- | rts/Task.c | 2 | ||||
-rw-r--r-- | rts/Threads.c | 2 | ||||
-rw-r--r-- | rts/TraverseHeap.c | 2 | ||||
-rw-r--r-- | rts/eventlog/EventLog.c | 9 | ||||
-rw-r--r-- | rts/hooks/LongGCSync.c | 2 | ||||
-rw-r--r-- | rts/posix/Signals.c | 2 | ||||
-rw-r--r-- | rts/sm/Compact.c | 4 | ||||
-rw-r--r-- | rts/sm/GC.c | 62 | ||||
-rw-r--r-- | rts/sm/MarkWeak.c | 2 | ||||
-rw-r--r-- | rts/sm/NonMoving.c | 18 | ||||
-rw-r--r-- | rts/sm/NonMovingCensus.c | 2 | ||||
-rw-r--r-- | rts/sm/NonMovingMark.c | 10 | ||||
-rw-r--r-- | rts/sm/NonMovingSweep.c | 2 | ||||
-rw-r--r-- | rts/sm/Sanity.c | 22 | ||||
-rw-r--r-- | rts/sm/Storage.c | 14 |
32 files changed, 131 insertions, 125 deletions
diff --git a/includes/rts/Threads.h b/includes/rts/Threads.h index 51c11742ca..d471f5301a 100644 --- a/includes/rts/Threads.h +++ b/includes/rts/Threads.h @@ -61,10 +61,13 @@ pid_t forkProcess (HsStablePtr *entry) HsBool rtsSupportsBoundThreads (void); // The number of Capabilities. -// ToDo: I would like this to be private to the RTS and instead expose a -// function getNumCapabilities(), but it is used in compiler/cbits/genSym.c +// TODO: Ideally we would only provide getNumCapabilities +// but this is used in compiler/cbits/genSym.c extern unsigned int n_capabilities; +INLINE_HEADER unsigned int getNumCapabilities(void) +{ return RELAXED_LOAD(&n_capabilities); } + // The number of Capabilities that are not disabled extern uint32_t enabled_capabilities; diff --git a/rts/Capability.c b/rts/Capability.c index 7a83821e00..ecaae5c7a6 100644 --- a/rts/Capability.c +++ b/rts/Capability.c @@ -131,7 +131,7 @@ findSpark (Capability *cap) retry = true; } - if (n_capabilities == 1) { return NULL; } // makes no sense... + if (getNumCapabilities() == 1) { return NULL; } // makes no sense... debugTrace(DEBUG_sched, "cap %d: Trying to steal work from other capabilities", @@ -139,7 +139,7 @@ findSpark (Capability *cap) /* visit cap.s 0..n-1 in sequence until a theft succeeds. We could start at a random place instead of 0 as well. */ - for ( i=0 ; i < n_capabilities ; i++ ) { + for ( i=0 ; i < getNumCapabilities() ; i++ ) { robbed = capabilities[i]; if (cap == robbed) // ourselves... continue; @@ -182,7 +182,7 @@ anySparks (void) { uint32_t i; - for (i=0; i < n_capabilities; i++) { + for (i=0; i < getNumCapabilities(); i++) { if (!emptySparkPoolCap(capabilities[i])) { return true; } @@ -465,7 +465,7 @@ moreCapabilities (uint32_t from USED_IF_THREADS, uint32_t to USED_IF_THREADS) void contextSwitchAllCapabilities(void) { uint32_t i; - for (i=0; i < n_capabilities; i++) { + for (i=0; i < getNumCapabilities(); i++) { contextSwitchCapability(capabilities[i]); } } @@ -473,7 +473,7 @@ void contextSwitchAllCapabilities(void) void interruptAllCapabilities(void) { uint32_t i; - for (i=0; i < n_capabilities; i++) { + for (i=0; i < getNumCapabilities(); i++) { interruptCapability(capabilities[i]); } } @@ -1253,7 +1253,7 @@ void shutdownCapabilities(Task *task, bool safe) { uint32_t i; - for (i=0; i < n_capabilities; i++) { + for (i=0; i < getNumCapabilities(); i++) { ASSERT(task->incall->tso == NULL); shutdownCapability(capabilities[i], task, safe); } @@ -1280,7 +1280,7 @@ freeCapabilities (void) { #if defined(THREADED_RTS) uint32_t i; - for (i=0; i < n_capabilities; i++) { + for (i=0; i < getNumCapabilities(); i++) { freeCapability(capabilities[i]); if (capabilities[i] != &MainCapability) stgFree(capabilities[i]); @@ -1334,7 +1334,7 @@ void markCapabilities (evac_fn evac, void *user) { uint32_t n; - for (n = 0; n < n_capabilities; n++) { + for (n = 0; n < getNumCapabilities(); n++) { markCapability(evac, user, capabilities[n], false); } } @@ -1346,7 +1346,7 @@ bool checkSparkCountInvariant (void) StgWord64 remaining = 0; uint32_t i; - for (i = 0; i < n_capabilities; i++) { + for (i = 0; i < getNumCapabilities(); i++) { sparks.created += capabilities[i]->spark_stats.created; sparks.dud += capabilities[i]->spark_stats.dud; sparks.overflowed+= capabilities[i]->spark_stats.overflowed; diff --git a/rts/Messages.h b/rts/Messages.h index fef4510740..4c88ce9844 100644 --- a/rts/Messages.h +++ b/rts/Messages.h @@ -27,7 +27,7 @@ doneWithMsgThrowTo (Capability *cap, MessageThrowTo *m) { // The message better be locked (unless we are running single-threaded, // where we are a bit more lenient (#19075). - ASSERT(n_capabilities == 1 || m->header.info == &stg_WHITEHOLE_info); + ASSERT(getNumCapabilities() == 1 || m->header.info == &stg_WHITEHOLE_info); IF_NONMOVING_WRITE_BARRIER_ENABLED { updateRemembSetPushClosure(cap, (StgClosure *) m->link); updateRemembSetPushClosure(cap, (StgClosure *) m->source); diff --git a/rts/PrimOps.cmm b/rts/PrimOps.cmm index b5c07af5f2..988a44ec9b 100644 --- a/rts/PrimOps.cmm +++ b/rts/PrimOps.cmm @@ -2716,7 +2716,9 @@ INFO_TABLE_RET(stg_noDuplicate, RET_SMALL, W_ info_ptr) stg_noDuplicatezh /* no arg list: explicit stack layout */ { // With a single capability there's no chance of work duplication. - if (CInt[n_capabilities] == 1 :: CInt) { + CInt n_caps; + n_caps = CInt[n_capabilities]; + if (n_caps == 1 :: CInt) { jump %ENTRY_CODE(Sp(0)) []; } diff --git a/rts/Printer.c b/rts/Printer.c index 7d9614cfd7..f693dbafbf 100644 --- a/rts/Printer.c +++ b/rts/Printer.c @@ -703,7 +703,7 @@ void printWeakLists() { debugBelch("======= WEAK LISTS =======\n"); - for (uint32_t cap_idx = 0; cap_idx < n_capabilities; ++cap_idx) { + for (uint32_t cap_idx = 0; cap_idx < getNumCapabilities(); ++cap_idx) { debugBelch("Capability %d:\n", cap_idx); Capability *cap = capabilities[cap_idx]; for (StgWeak *weak = cap->weak_ptr_list_hd; weak; weak = weak->link) { @@ -730,7 +730,7 @@ void printLargeAndPinnedObjects() { debugBelch("====== PINNED OBJECTS ======\n"); - for (uint32_t cap_idx = 0; cap_idx < n_capabilities; ++cap_idx) { + for (uint32_t cap_idx = 0; cap_idx < getNumCapabilities(); ++cap_idx) { Capability *cap = capabilities[cap_idx]; debugBelch("Capability %d: Current pinned object block: %p\n", @@ -943,7 +943,7 @@ findPtr(P_ p, int follow) // We can't search the nursery, because we don't know which blocks contain // valid data, because the bd->free pointers in the nursery are only reset // just before a block is used. - for (n = 0; n < n_capabilities; n++) { + for (n = 0; n < getNumCapabilities(); n++) { bd = nurseries[i].blocks; i = findPtrBlocks(p,bd,arr,arr_size,i); if (i >= arr_size) return; @@ -956,7 +956,7 @@ findPtr(P_ p, int follow) bd = generations[g].large_objects; i = findPtrBlocks(p,bd,arr,arr_size,i); if (i >= arr_size) return; - for (n = 0; n < n_capabilities; n++) { + for (n = 0; n < getNumCapabilities(); n++) { i = findPtrBlocks(p, gc_threads[n]->gens[g].part_list, arr, arr_size, i); i = findPtrBlocks(p, gc_threads[n]->gens[g].todo_bd, diff --git a/rts/ProfHeap.c b/rts/ProfHeap.c index 863afbd0e1..e8a909b7be 100644 --- a/rts/ProfHeap.c +++ b/rts/ProfHeap.c @@ -1300,7 +1300,7 @@ void heapCensus (Time t) heapCensusChain( census, generations[g].large_objects ); heapCensusCompactList ( census, generations[g].compact_objects ); - for (n = 0; n < n_capabilities; n++) { + for (n = 0; n < getNumCapabilities(); n++) { ws = &gc_threads[n]->gens[g]; heapCensusChain(census, ws->todo_bd); heapCensusChain(census, ws->part_list); diff --git a/rts/ProfilerReport.c b/rts/ProfilerReport.c index 60c90a72da..d313ecdadb 100644 --- a/rts/ProfilerReport.c +++ b/rts/ProfilerReport.c @@ -296,10 +296,10 @@ writeCCSReport( FILE *prof_file, CostCentreStack const *stack, fprintf(prof_file, "\ttotal time = %11.2f secs (%lu ticks @ %d us, %d processor%s)\n", ((double) totals.total_prof_ticks * - (double) RtsFlags.MiscFlags.tickInterval) / (TIME_RESOLUTION * n_capabilities), + (double) RtsFlags.MiscFlags.tickInterval) / (TIME_RESOLUTION * getNumCapabilities()), (unsigned long) totals.total_prof_ticks, (int) TimeToUS(RtsFlags.MiscFlags.tickInterval), - n_capabilities, n_capabilities > 1 ? "s" : ""); + getNumCapabilities(), getNumCapabilities() > 1 ? "s" : ""); fprintf(prof_file, "\ttotal alloc = %11s bytes", showStgWord64(totals.total_alloc * sizeof(W_), diff --git a/rts/ProfilerReportJson.c b/rts/ProfilerReportJson.c index 5a3890c85e..aeca0785ff 100644 --- a/rts/ProfilerReportJson.c +++ b/rts/ProfilerReportJson.c @@ -133,7 +133,7 @@ writeCCSReportJson(FILE *prof_file, RtsFlags.ParFlags.nCapabilities); fprintf(prof_file, "\"total_time\": %11.2f,\n", ((double) totals.total_prof_ticks * - (double) RtsFlags.MiscFlags.tickInterval) / (TIME_RESOLUTION * n_capabilities)); + (double) RtsFlags.MiscFlags.tickInterval) / (TIME_RESOLUTION * getNumCapabilities())); fprintf(prof_file, "\"total_ticks\": %lu,\n", (unsigned long) totals.total_prof_ticks); fprintf(prof_file, "\"tick_interval\": %d,\n", diff --git a/rts/Profiling.c b/rts/Profiling.c index e96f6b2b93..0fc5b8f1da 100644 --- a/rts/Profiling.c +++ b/rts/Profiling.c @@ -153,7 +153,7 @@ void initProfiling (void) /* for the benefit of allocate()... */ { uint32_t n; - for (n=0; n < n_capabilities; n++) { + for (n=0; n < getNumCapabilities(); n++) { capabilities[n]->r.rCCCS = CCS_SYSTEM; } } diff --git a/rts/Proftimer.c b/rts/Proftimer.c index 29abb62a8e..17ea0cbb34 100644 --- a/rts/Proftimer.c +++ b/rts/Proftimer.c @@ -117,7 +117,7 @@ handleProfTick(void) total_ticks++; if (RELAXED_LOAD(&do_prof_ticks)) { uint32_t n; - for (n=0; n < n_capabilities; n++) { + for (n=0; n < getNumCapabilities(); n++) { capabilities[n]->r.rCCCS->time_ticks++; traceProfSampleCostCentre(capabilities[n], capabilities[n]->r.rCCCS, total_ticks); } diff --git a/rts/RetainerProfile.c b/rts/RetainerProfile.c index 0db1cd2a18..e5e8bf1e51 100644 --- a/rts/RetainerProfile.c +++ b/rts/RetainerProfile.c @@ -390,7 +390,7 @@ computeRetainerSet( traverseState *ts ) // // The following code assumes that WEAK objects are considered to be roots // for retainer profiling. - for (n = 0; n < n_capabilities; n++) { + for (n = 0; n < getNumCapabilities(); n++) { // NB: after a GC, all nursery weak_ptr_lists have been migrated // to the global lists living in the generations ASSERT(capabilities[n]->weak_ptr_list_hd == NULL); diff --git a/rts/RtsAPI.c b/rts/RtsAPI.c index d334a05dfb..6800e63bc1 100644 --- a/rts/RtsAPI.c +++ b/rts/RtsAPI.c @@ -772,7 +772,7 @@ void rts_resume (PauseToken *pauseToken) // releaseAllCapabilities will not block because the current task owns all // capabilities. - releaseAllCapabilities(n_capabilities, NULL, task); + releaseAllCapabilities(getNumCapabilities(), NULL, task); exitMyTask(); free(pauseToken); } @@ -810,7 +810,7 @@ static void assert_isPausedOnMyTask(const char *functionName) } // Check that we own all capabilities. - for (unsigned int i = 0; i < n_capabilities; i++) + for (unsigned int i = 0; i < getNumCapabilities(); i++) { Capability *cap = capabilities[i]; if (cap->running_task != task) diff --git a/rts/RtsStartup.c b/rts/RtsStartup.c index 649489d1e3..8201191162 100644 --- a/rts/RtsStartup.c +++ b/rts/RtsStartup.c @@ -466,7 +466,7 @@ hs_exit_(bool wait_foreign) exitScheduler(wait_foreign); /* run C finalizers for all active weak pointers */ - for (i = 0; i < n_capabilities; i++) { + for (i = 0; i < getNumCapabilities(); i++) { runAllCFinalizers(capabilities[i]->weak_ptr_list_hd); } for (g = 0; g < RtsFlags.GcFlags.generations; g++) { diff --git a/rts/SMPClosureOps.h b/rts/SMPClosureOps.h index 2df88db06c..7bc8cc4ea3 100644 --- a/rts/SMPClosureOps.h +++ b/rts/SMPClosureOps.h @@ -16,7 +16,9 @@ * Arguments are swapped for uniformity with unlockClosure. */ #if defined(THREADED_RTS) #define LOCK_CLOSURE(closure, info) \ - if (CInt[n_capabilities] == 1 :: CInt) { \ + CInt _n_caps; \ + _n_caps = CInt[n_capabilities]; \ + if (_n_caps == 1 :: CInt) { \ info = GET_INFO(closure); \ } else { \ ("ptr" info) = ccall reallyLockClosure(closure "ptr"); \ @@ -75,7 +77,7 @@ EXTERN_INLINE StgInfoTable *reallyLockClosure(StgClosure *p) INLINE_HEADER StgInfoTable *lockClosure(StgClosure *p) { - if (n_capabilities == 1) { + if (getNumCapabilities() == 1) { return (StgInfoTable *)p->header.info; } else { @@ -88,7 +90,7 @@ INLINE_HEADER StgInfoTable *lockClosure(StgClosure *p) EXTERN_INLINE StgInfoTable *tryLockClosure(StgClosure *p) { StgWord info; - if (n_capabilities == 1) { + if (RELAXED_LOAD(&n_capabilities) == 1) { return (StgInfoTable *)p->header.info; } else { @@ -1107,7 +1107,7 @@ StgBool stmCommitTransaction(Capability *cap, StgTRecHeader *trec) { max_commits_at_end = getMaxCommits(); max_concurrent_commits = ((max_commits_at_end - max_commits_at_start) + - (n_capabilities * TOKEN_BATCH_SIZE)); + (getNumCapabilities() * TOKEN_BATCH_SIZE)); if (((max_concurrent_commits >> 32) > 0) || shake()) { result = false; } diff --git a/rts/Schedule.c b/rts/Schedule.c index c84e57548b..5a174dc104 100644 --- a/rts/Schedule.c +++ b/rts/Schedule.c @@ -727,7 +727,7 @@ schedulePushWork(Capability *cap USED_IF_THREADS, { #if defined(THREADED_RTS) - Capability *free_caps[n_capabilities], *cap0; + Capability *free_caps[getNumCapabilities()], *cap0; uint32_t i, n_wanted_caps, n_free_caps; uint32_t spare_threads = cap->n_run_queue > 0 ? cap->n_run_queue - 1 : 0; @@ -744,9 +744,9 @@ schedulePushWork(Capability *cap USED_IF_THREADS, // First grab as many free Capabilities as we can. ToDo: we should use // capabilities on the same NUMA node preferably, but not exclusively. - for (i = (cap->no + 1) % n_capabilities, n_free_caps=0; + for (i = (cap->no + 1) % getNumCapabilities(), n_free_caps=0; n_free_caps < n_wanted_caps && i != cap->no; - i = (i + 1) % n_capabilities) { + i = (i + 1) % getNumCapabilities()) { cap0 = capabilities[i]; if (cap != cap0 && !cap0->disabled && tryGrabCapability(cap0,task)) { if (!emptyRunQueue(cap0) @@ -1512,9 +1512,9 @@ static void acquireAllCapabilities(Capability *cap, Task *task) uint32_t i; ASSERT(SEQ_CST_LOAD(&pending_sync) != NULL); - for (i=0; i < n_capabilities; i++) { - debugTrace(DEBUG_sched, "grabbing all the capabilies (%d/%d)", - i, n_capabilities); + for (i=0; i < getNumCapabilities(); i++) { + debugTrace(DEBUG_sched, "grabbing all the capabilities (%d/%d)", + i, getNumCapabilities()); tmpcap = capabilities[i]; if (tmpcap != cap) { // we better hope this task doesn't get migrated to @@ -1653,7 +1653,7 @@ scheduleDoGC (Capability **pcap, Task *task USED_IF_THREADS, // We need an array of size n_capabilities, but since this may // change each time around the loop we must allocate it afresh. - idle_cap = (bool *)stgMallocBytes(n_capabilities * + idle_cap = (bool *)stgMallocBytes(getNumCapabilities() * sizeof(bool), "scheduleDoGC"); sync.idle = idle_cap; @@ -1662,7 +1662,7 @@ scheduleDoGC (Capability **pcap, Task *task USED_IF_THREADS, // GC. The best bet is to choose some inactive ones, so we look for // those first: uint32_t n_idle = need_idle; - for (i=0; i < n_capabilities; i++) { + for (i=0; i < getNumCapabilities(); i++) { if (capabilities[i]->disabled) { idle_cap[i] = true; } else if (n_idle > 0 && @@ -1676,7 +1676,7 @@ scheduleDoGC (Capability **pcap, Task *task USED_IF_THREADS, } // If we didn't find enough inactive capabilities, just pick some // more to be idle. - for (i=0; n_idle > 0 && i < n_capabilities; i++) { + for (i=0; n_idle > 0 && i < getNumCapabilities(); i++) { if (!idle_cap[i] && i != cap->no) { idle_cap[i] = true; n_idle--; @@ -1710,9 +1710,7 @@ scheduleDoGC (Capability **pcap, Task *task USED_IF_THREADS, stat_startGCSync(gc_threads[cap->no]); -#if defined(DEBUG) - unsigned int old_n_capabilities = n_capabilities; -#endif + unsigned int old_n_capabilities = getNumCapabilities(); interruptAllCapabilities(); @@ -2314,7 +2312,7 @@ setNumCapabilities (uint32_t new_n_capabilities USED_IF_THREADS) // update n_capabilities before things start running if (new_n_capabilities > n_capabilities) { - n_capabilities = enabled_capabilities = new_n_capabilities; + RELAXED_STORE(&n_capabilities, enabled_capabilities = new_n_capabilities); } // We're done: release the original Capabilities diff --git a/rts/Stats.c b/rts/Stats.c index 38184b6071..bf3079199d 100644 --- a/rts/Stats.c +++ b/rts/Stats.c @@ -890,7 +890,7 @@ static void report_summary(const RTSSummaryStats* sum) "(%d bound, %d peak workers (%d total), using -N%d)\n\n", taskCount, sum->bound_task_count, peakWorkerCount, workerCount, - n_capabilities); + getNumCapabilities()); statsPrintf(" SPARKS: %" FMT_Word64 " (%" FMT_Word " converted, %" FMT_Word " overflowed, %" @@ -1131,7 +1131,7 @@ static void report_machine_readable (const RTSSummaryStats * sum) MR_STAT("work_balance", "f", sum->work_balance); // next, globals (other than internal counters) - MR_STAT("n_capabilities", FMT_Word32, n_capabilities); + MR_STAT("n_capabilities", FMT_Word32, getNumCapabilities()); MR_STAT("task_count", FMT_Word32, taskCount); MR_STAT("peak_worker_count", FMT_Word32, peakWorkerCount); MR_STAT("worker_count", FMT_Word32, workerCount); @@ -1346,7 +1346,7 @@ stat_exitReport (void) #if defined(THREADED_RTS) sum.bound_task_count = taskCount - workerCount; - for (uint32_t i = 0; i < n_capabilities; i++) { + for (uint32_t i = 0; i < getNumCapabilities(); i++) { sum.sparks.created += capabilities[i]->spark_stats.created; sum.sparks.dud += capabilities[i]->spark_stats.dud; sum.sparks.overflowed+= @@ -1645,7 +1645,7 @@ statDescribeGens(void) gen_blocks = genLiveBlocks(gen); mut = 0; - for (i = 0; i < n_capabilities; i++) { + for (i = 0; i < getNumCapabilities(); i++) { mut += countOccupied(capabilities[i]->mut_lists[g]); // Add the pinned object block. diff --git a/rts/Task.c b/rts/Task.c index 2bd32359cc..f63806f543 100644 --- a/rts/Task.c +++ b/rts/Task.c @@ -530,7 +530,7 @@ void rts_setInCallCapability ( #if defined(THREADED_RTS) if (affinity) { if (RtsFlags.ParFlags.setAffinity) { - setThreadAffinity(preferred_capability, n_capabilities); + setThreadAffinity(preferred_capability, getNumCapabilities()); } } #endif diff --git a/rts/Threads.c b/rts/Threads.c index 6c5adb15ec..24c602a8de 100644 --- a/rts/Threads.c +++ b/rts/Threads.c @@ -950,7 +950,7 @@ printAllThreads(void) debugBelch("all threads:\n"); - for (i = 0; i < n_capabilities; i++) { + for (i = 0; i < getNumCapabilities(); i++) { cap = capabilities[i]; debugBelch("threads on capability %d:\n", cap->no); for (t = cap->run_queue_hd; t != END_TSO_QUEUE; t = t->_link) { diff --git a/rts/TraverseHeap.c b/rts/TraverseHeap.c index c13e0455db..63d21f2416 100644 --- a/rts/TraverseHeap.c +++ b/rts/TraverseHeap.c @@ -1095,7 +1095,7 @@ resetMutableObjects(traverseState* ts) // Traversing through mut_list is necessary // because we can find MUT_VAR objects which have not been // visited during heap traversal. - for (n = 0; n < n_capabilities; n++) { + for (n = 0; n < getNumCapabilities(); n++) { for (bd = capabilities[n]->mut_lists[g]; bd != NULL; bd = bd->link) { for (ml = bd->start; ml < bd->free; ml++) { traverseMaybeInitClosureData(ts, (StgClosure *)*ml); diff --git a/rts/eventlog/EventLog.c b/rts/eventlog/EventLog.c index 3f52cf759a..8e78ed331e 100644 --- a/rts/eventlog/EventLog.c +++ b/rts/eventlog/EventLog.c @@ -665,7 +665,8 @@ get_n_capabilities(void) { #if defined(THREADED_RTS) // XXX n_capabilities may not have been initialized yet - return (n_capabilities != 0) ? n_capabilities : RtsFlags.ParFlags.nCapabilities; + unsigned int n = getNumCapabilities(); + return (n != 0) ? n : RtsFlags.ParFlags.nCapabilities; #else return 1; #endif @@ -772,7 +773,7 @@ finishCapEventLogging(void) if (eventlog_enabled) { // Flush all events remaining in the capabilities' buffers and free them. // N.B. at this point we hold all capabilities. - for (uint32_t c = 0; c < n_capabilities; ++c) { + for (uint32_t c = 0; c < getNumCapabilities(); ++c) { if (capEventBuf[c].begin != NULL) { printAndClearEventBuf(&capEventBuf[c]); stgFree(capEventBuf[c].begin); @@ -1876,7 +1877,7 @@ void flushAllCapsEventsBufs() printAndClearEventBuf(&eventBuf); RELEASE_LOCK(&eventBufMutex); - for (unsigned int i=0; i < n_capabilities; i++) { + for (unsigned int i=0; i < getNumCapabilities(); i++) { flushLocalEventsBuf(capabilities[i]); } flushEventLogWriter(); @@ -1892,7 +1893,7 @@ void flushEventLog(Capability **cap USED_IF_THREADS) Task *task = getMyTask(); stopAllCapabilitiesWith(cap, task, SYNC_FLUSH_EVENT_LOG); flushAllCapsEventsBufs(); - releaseAllCapabilities(n_capabilities, cap ? *cap : NULL, task); + releaseAllCapabilities(getNumCapabilities(), cap ? *cap : NULL, task); #else flushLocalEventsBuf(capabilities[0]); #endif diff --git a/rts/hooks/LongGCSync.c b/rts/hooks/LongGCSync.c index 58ee52fa3d..e7a5626c38 100644 --- a/rts/hooks/LongGCSync.c +++ b/rts/hooks/LongGCSync.c @@ -20,7 +20,7 @@ void LongGCSync (uint32_t me USED_IF_THREADS, Time t STG_UNUSED) #if defined(THREADED_RTS) { uint32_t i; - for (i=0; i < n_capabilities; i++) { + for (i=0; i < getNumCapabilities(); i++) { if (i != me && SEQ_CST_LOAD(&gc_threads[i]->wakeup) == GC_THREAD_STANDING_BY) { debugBelch("Warning: slow GC sync: still waiting for cap %d\n", i); diff --git a/rts/posix/Signals.c b/rts/posix/Signals.c index 185c69eee3..df361cacb7 100644 --- a/rts/posix/Signals.c +++ b/rts/posix/Signals.c @@ -202,7 +202,7 @@ ioManagerDie (void) { // Shut down IO managers - for (i=0; i < n_capabilities; i++) { + for (i=0; i < getNumCapabilities(); i++) { const int fd = RELAXED_LOAD(&capabilities[i]->io_manager_control_wr_fd); if (0 <= fd) { r = write(fd, &byte, 1); diff --git a/rts/sm/Compact.c b/rts/sm/Compact.c index 5031c535a1..6ca6960616 100644 --- a/rts/sm/Compact.c +++ b/rts/sm/Compact.c @@ -978,7 +978,7 @@ compact(StgClosure *static_objects, // mutable lists for (W_ g = 1; g < RtsFlags.GcFlags.generations; g++) { - for (W_ n = 0; n < n_capabilities; n++) { + for (W_ n = 0; n < getNumCapabilities(); n++) { for (bdescr *bd = capabilities[n]->mut_lists[g]; bd != NULL; bd = bd->link) { for (P_ p = bd->start; p < bd->free; p++) { @@ -1024,7 +1024,7 @@ compact(StgClosure *static_objects, debugTrace(DEBUG_gc, "update_fwd: %d", g); update_fwd(gen->blocks); - for (W_ n = 0; n < n_capabilities; n++) { + for (W_ n = 0; n < getNumCapabilities(); n++) { update_fwd(gc_threads[n]->gens[g].todo_bd); update_fwd(gc_threads[n]->gens[g].part_list); } diff --git a/rts/sm/GC.c b/rts/sm/GC.c index 65a02a2de6..84023654cd 100644 --- a/rts/sm/GC.c +++ b/rts/sm/GC.c @@ -309,7 +309,7 @@ GarbageCollect (uint32_t collect_gen, #endif #if defined(PROFILING) - CostCentreStack *save_CCS[n_capabilities]; + CostCentreStack *save_CCS[getNumCapabilities()]; #endif ACQUIRE_SM_LOCK; @@ -340,7 +340,7 @@ GarbageCollect (uint32_t collect_gen, // attribute any costs to CCS_GC #if defined(PROFILING) - for (n = 0; n < n_capabilities; n++) { + for (n = 0; n < getNumCapabilities(); n++) { save_CCS[n] = capabilities[n]->r.rCCCS; capabilities[n]->r.rCCCS = CCS_GC; } @@ -396,9 +396,9 @@ GarbageCollect (uint32_t collect_gen, * here */ if (gc_type == SYNC_GC_PAR) { - n_gc_threads = n_capabilities; + n_gc_threads = getNumCapabilities(); n_gc_idle_threads = 0; - for (uint32_t i = 0; i < n_capabilities; ++i) { + for (uint32_t i = 0; i < getNumCapabilities(); ++i) { if (idle_cap[i]) { ASSERT(i != gct->thread_index); ++n_gc_idle_threads; @@ -406,7 +406,7 @@ GarbageCollect (uint32_t collect_gen, } } else { n_gc_threads = 1; - n_gc_idle_threads = n_capabilities - 1; + n_gc_idle_threads = getNumCapabilities() - 1; } work_stealing = RtsFlags.ParFlags.parGcLoadBalancingEnabled && N >= RtsFlags.ParFlags.parGcLoadBalancingGen && @@ -429,15 +429,15 @@ GarbageCollect (uint32_t collect_gen, SEQ_CST_STORE(&gc_running_threads, 0); ASSERT(n_gc_threads > 0); - ASSERT(n_gc_threads <= n_capabilities); - ASSERT(n_gc_idle_threads < n_capabilities); + ASSERT(n_gc_threads <= getNumCapabilities()); + ASSERT(n_gc_idle_threads < getNumCapabilities()); // If we are work stealing, there better be another(i.e. not us) non-idle gc // thread ASSERT(!work_stealing || n_gc_threads - 1 > n_gc_idle_threads); debugTrace(DEBUG_gc, "GC (gen %d, using %d thread(s), %s work stealing)", - N, (int)n_capabilities - (int)n_gc_idle_threads, + N, (int)getNumCapabilities() - (int)n_gc_idle_threads, work_stealing ? "with": "without"); #if defined(DEBUG) @@ -499,7 +499,7 @@ GarbageCollect (uint32_t collect_gen, // call back into the GC via mark_root() (due to the gct register // variable). if (!is_par_gc()) { - for (n = 0; n < n_capabilities; n++) { + for (n = 0; n < getNumCapabilities(); n++) { #if defined(THREADED_RTS) scavenge_capability_mut_Lists1(capabilities[n]); #else @@ -508,7 +508,7 @@ GarbageCollect (uint32_t collect_gen, } } else { scavenge_capability_mut_lists(gct->cap); - for (n = 0; n < n_capabilities; n++) { + for (n = 0; n < getNumCapabilities(); n++) { if (idle_cap[n]) { markCapability(mark_root, gct, capabilities[n], true/*don't mark sparks*/); @@ -524,7 +524,7 @@ GarbageCollect (uint32_t collect_gen, // follow all the roots that the application knows about. gct->evac_gen_no = 0; if (!is_par_gc()) { - for (n = 0; n < n_capabilities; n++) { + for (n = 0; n < getNumCapabilities(); n++) { markCapability(mark_root, gct, capabilities[n], true/*don't mark sparks*/); } @@ -573,11 +573,11 @@ GarbageCollect (uint32_t collect_gen, #if defined(THREADED_RTS) // See Note [Pruning the spark pool] if (gc_sparks_all_caps) { - for (n = 0; n < n_capabilities; n++) { + for (n = 0; n < getNumCapabilities(); n++) { pruneSparkQueue(false, capabilities[n]); } } else { - for (n = 0; n < n_capabilities; n++) { + for (n = 0; n < getNumCapabilities(); n++) { if (n == cap->no || idle_cap[n]) { pruneSparkQueue(false, capabilities[n]); } @@ -683,7 +683,7 @@ GarbageCollect (uint32_t collect_gen, // stats. Every mutable list is copied during every GC. if (g > 0) { W_ mut_list_size = 0; - for (n = 0; n < n_capabilities; n++) { + for (n = 0; n < getNumCapabilities(); n++) { mut_list_size += countOccupied(capabilities[n]->mut_lists[g]); } copied += mut_list_size; @@ -836,7 +836,7 @@ GarbageCollect (uint32_t collect_gen, // add in the partial blocks in the gen_workspaces { uint32_t i; - for (i = 0; i < n_capabilities; i++) { + for (i = 0; i < getNumCapabilities(); i++) { live_words += gcThreadLiveWords(i, gen->no); live_blocks += gcThreadLiveBlocks(i, gen->no); } @@ -847,7 +847,7 @@ GarbageCollect (uint32_t collect_gen, // flushing] in NonMovingMark.c if (RtsFlags.GcFlags.useNonmoving) { RELEASE_SM_LOCK; - for (n = 0; n < n_capabilities; n++) { + for (n = 0; n < getNumCapabilities(); n++) { nonmovingAddUpdRemSetBlocks(&capabilities[n]->upd_rem_set.queue); } ACQUIRE_SM_LOCK; @@ -1067,7 +1067,7 @@ GarbageCollect (uint32_t collect_gen, // restore enclosing cost centre #if defined(PROFILING) - for (n = 0; n < n_capabilities; n++) { + for (n = 0; n < getNumCapabilities(); n++) { capabilities[n]->r.rCCCS = save_CCS[n]; } #endif @@ -1216,7 +1216,7 @@ freeGcThreads (void) if (gc_threads != NULL) { #if defined(THREADED_RTS) uint32_t i; - for (i = 0; i < n_capabilities; i++) { + for (i = 0; i < getNumCapabilities(); i++) { for (g = 0; g < RtsFlags.GcFlags.generations; g++) { freeWSDeque(gc_threads[i]->gens[g].todo_q); @@ -1442,26 +1442,26 @@ void waitForGcThreads (Capability *cap, bool idle_cap[]) { // n_gc_threads is not valid here, we're too early - uint32_t n_threads = n_capabilities; + uint32_t n_threads = getNumCapabilities(); const uint32_t me = cap->no; uint32_t i, cur_n_gc_entered; Time t0, t1, t2; t0 = t1 = t2 = getProcessElapsedTime(); - for(i = 0; i < n_capabilities; ++i) { + for(i = 0; i < getNumCapabilities(); ++i) { if (i == me || idle_cap[i]) { --n_threads; } } - ASSERT(n_threads < n_capabilities); // must be less because we don't count ourself + ASSERT(n_threads < getNumCapabilities()); // must be less because we don't count ourself if(n_threads == 0) { return; } ACQUIRE_LOCK(&gc_entry_mutex); while((cur_n_gc_entered = SEQ_CST_LOAD(&n_gc_entered)) != n_threads) { ASSERT(cur_n_gc_entered < n_threads); - for(i = 0; i < n_capabilities; ++i) { + for(i = 0; i < getNumCapabilities(); ++i) { if (i == me || idle_cap[i]) { continue; } if (SEQ_CST_LOAD(&gc_threads[i]->wakeup) != GC_THREAD_STANDING_BY) { prodCapability(capabilities[i], cap->running_task); @@ -1551,7 +1551,7 @@ shutdown_gc_threads (uint32_t me USED_IF_THREADS USED_IF_DEBUG, } #if defined(DEBUG) uint32_t i; - for (i=0; i < n_capabilities; i++) { + for (i=0; i < getNumCapabilities(); i++) { if (i == me || idle_cap[i]) continue; ASSERT(SEQ_CST_LOAD(&gc_threads[i]->wakeup) == GC_THREAD_WAITING_TO_CONTINUE); } @@ -1564,7 +1564,7 @@ shutdown_gc_threads (uint32_t me USED_IF_THREADS USED_IF_DEBUG, void releaseGCThreads (Capability *cap USED_IF_THREADS, bool idle_cap[]) { - const uint32_t n_threads = n_capabilities; + const uint32_t n_threads = getNumCapabilities(); const uint32_t me = cap->no; uint32_t i; #if defined(DEBUG) @@ -1616,14 +1616,14 @@ prepare_collected_gen (generation *gen) if (RtsFlags.GcFlags.useNonmoving && g == oldest_gen->no) { // Nonmoving heap's mutable list is always a root. - for (i = 0; i < n_capabilities; i++) { + for (i = 0; i < getNumCapabilities(); i++) { stash_mut_list(capabilities[i], g); } } else if (g != 0) { // Otherwise throw away the current mutable list. Invariant: the // mutable list always has at least one block; this means we can avoid // a check for NULL in recordMutable(). - for (i = 0; i < n_capabilities; i++) { + for (i = 0; i < getNumCapabilities(); i++) { bdescr *old = RELAXED_LOAD(&capabilities[i]->mut_lists[g]); freeChain(old); @@ -1660,7 +1660,7 @@ prepare_collected_gen (generation *gen) // grab all the partial blocks stashed in the gc_thread workspaces and // move them to the old_blocks list of this gen. - for (n = 0; n < n_capabilities; n++) { + for (n = 0; n < getNumCapabilities(); n++) { ws = &gc_threads[n]->gens[gen->no]; for (bd = ws->part_list; bd != NULL; bd = next) { @@ -1759,7 +1759,7 @@ prepare_uncollected_gen (generation *gen) // save the current mutable lists for this generation, and // allocate a fresh block for each one. We'll traverse these // mutable lists as roots early on in the GC. - for (i = 0; i < n_capabilities; i++) { + for (i = 0; i < getNumCapabilities(); i++) { stash_mut_list(capabilities[i], gen->no); } @@ -1833,7 +1833,7 @@ collect_pinned_object_blocks (void) const bool use_nonmoving = RtsFlags.GcFlags.useNonmoving; generation *const gen = (use_nonmoving && major_gc) ? oldest_gen : g0; - for (uint32_t n = 0; n < n_capabilities; n++) { + for (uint32_t n = 0; n < getNumCapabilities(); n++) { bdescr *last = NULL; if (use_nonmoving && gen == oldest_gen) { // Mark objects as belonging to the nonmoving heap @@ -1949,7 +1949,7 @@ resizeGenerations (void) // minimum size for generation zero min_alloc = stg_max((RtsFlags.GcFlags.pcFreeHeap * max) / 200, RtsFlags.GcFlags.minAllocAreaSize - * (W_)n_capabilities); + * (W_)getNumCapabilities()); // Auto-enable compaction when the residency reaches a // certain percentage of the maximum heap size (default: 30%). @@ -2021,7 +2021,7 @@ static void resize_nursery (void) { const StgWord min_nursery = - RtsFlags.GcFlags.minAllocAreaSize * (StgWord)n_capabilities; + RtsFlags.GcFlags.minAllocAreaSize * (StgWord)getNumCapabilities(); if (RtsFlags.GcFlags.generations == 1) { // Two-space collector: diff --git a/rts/sm/MarkWeak.c b/rts/sm/MarkWeak.c index b8d120823c..f61802dc43 100644 --- a/rts/sm/MarkWeak.c +++ b/rts/sm/MarkWeak.c @@ -385,7 +385,7 @@ void collectFreshWeakPtrs() { uint32_t i; // move recently allocated weak_ptr_list to the old list as well - for (i = 0; i < n_capabilities; i++) { + for (i = 0; i < getNumCapabilities(); i++) { Capability *cap = capabilities[i]; if (cap->weak_ptr_list_tl != NULL) { IF_DEBUG(sanity, checkWeakPtrSanity(cap->weak_ptr_list_hd, cap->weak_ptr_list_tl)); diff --git a/rts/sm/NonMoving.c b/rts/sm/NonMoving.c index d47faa2b9f..f363b9516e 100644 --- a/rts/sm/NonMoving.c +++ b/rts/sm/NonMoving.c @@ -733,7 +733,7 @@ void nonmovingInit(void) initMutex(&concurrent_coll_finished_lock); #endif for (unsigned int i = 0; i < NONMOVING_ALLOCA_CNT; i++) { - nonmovingHeap.allocators[i] = alloc_nonmoving_allocator(n_capabilities); + nonmovingHeap.allocators[i] = alloc_nonmoving_allocator(getNumCapabilities()); } nonmovingMarkInitUpdRemSet(); } @@ -826,7 +826,7 @@ static void nonmovingPrepareMark(void) struct NonmovingAllocator *alloca = nonmovingHeap.allocators[alloca_idx]; // Update current segments' snapshot pointers - for (uint32_t cap_n = 0; cap_n < n_capabilities; ++cap_n) { + for (uint32_t cap_n = 0; cap_n < getNumCapabilities(); ++cap_n) { struct NonmovingSegment *seg = alloca->current[cap_n]; nonmovingSegmentInfo(seg)->next_free_snap = seg->next_free; } @@ -945,7 +945,7 @@ void nonmovingCollect(StgWeak **dead_weaks, StgTSO **resurrected_threads) // Mark roots trace(TRACE_nonmoving_gc, "Marking roots for nonmoving GC"); markCAFs((evac_fn)markQueueAddRoot, mark_queue); - for (unsigned int n = 0; n < n_capabilities; ++n) { + for (unsigned int n = 0; n < getNumCapabilities(); ++n) { markCapability((evac_fn)markQueueAddRoot, mark_queue, capabilities[n], true/*don't mark sparks*/); } @@ -1190,7 +1190,7 @@ static void nonmovingMark_(MarkQueue *mark_queue, StgWeak **dead_weaks, StgTSO * // Prune spark lists // See Note [Spark management under the nonmoving collector]. #if defined(THREADED_RTS) - for (uint32_t n = 0; n < n_capabilities; n++) { + for (uint32_t n = 0; n < getNumCapabilities(); n++) { pruneSparkQueue(true, capabilities[n]); } #endif @@ -1266,7 +1266,7 @@ void assert_in_nonmoving_heap(StgPtr p) bdescr *bd = Bdescr(p); if (bd->flags & BF_LARGE) { // It should be in a capability (if it's not filled yet) or in non-moving heap - for (uint32_t cap = 0; cap < n_capabilities; ++cap) { + for (uint32_t cap = 0; cap < getNumCapabilities(); ++cap) { if (bd == capabilities[cap]->pinned_object_block) { return; } @@ -1285,7 +1285,7 @@ void assert_in_nonmoving_heap(StgPtr p) for (int alloca_idx = 0; alloca_idx < NONMOVING_ALLOCA_CNT; ++alloca_idx) { struct NonmovingAllocator *alloca = nonmovingHeap.allocators[alloca_idx]; // Search current segments - for (uint32_t cap_idx = 0; cap_idx < n_capabilities; ++cap_idx) { + for (uint32_t cap_idx = 0; cap_idx < getNumCapabilities(); ++cap_idx) { struct NonmovingSegment *seg = alloca->current[cap_idx]; if (p >= (P_)seg && p < (((P_)seg) + NONMOVING_SEGMENT_SIZE_W)) { return; @@ -1357,7 +1357,7 @@ void nonmovingPrintAllocator(struct NonmovingAllocator *alloc) debugBelch("%p ", (void*)seg); } debugBelch("\nCurrent segments:\n"); - for (uint32_t i = 0; i < n_capabilities; ++i) { + for (uint32_t i = 0; i < getNumCapabilities(); ++i) { debugBelch("%p ", alloc->current[i]); } debugBelch("\n"); @@ -1368,7 +1368,7 @@ void locate_object(P_ obj) // Search allocators for (int alloca_idx = 0; alloca_idx < NONMOVING_ALLOCA_CNT; ++alloca_idx) { struct NonmovingAllocator *alloca = nonmovingHeap.allocators[alloca_idx]; - for (uint32_t cap = 0; cap < n_capabilities; ++cap) { + for (uint32_t cap = 0; cap < getNumCapabilities(); ++cap) { struct NonmovingSegment *seg = alloca->current[cap]; if (obj >= (P_)seg && obj < (((P_)seg) + NONMOVING_SEGMENT_SIZE_W)) { debugBelch("%p is in current segment of capability %d of allocator %d at %p\n", obj, cap, alloca_idx, (void*)seg); @@ -1499,7 +1499,7 @@ void nonmovingPrintSweepList() void check_in_mut_list(StgClosure *p) { - for (uint32_t cap_n = 0; cap_n < n_capabilities; ++cap_n) { + for (uint32_t cap_n = 0; cap_n < getNumCapabilities(); ++cap_n) { for (bdescr *bd = capabilities[cap_n]->mut_lists[oldest_gen->no]; bd; bd = bd->link) { for (StgPtr q = bd->start; q < bd->free; ++q) { if (*((StgPtr**)q) == (StgPtr*)p) { diff --git a/rts/sm/NonMovingCensus.c b/rts/sm/NonMovingCensus.c index 2dcec4b745..41b6f7433b 100644 --- a/rts/sm/NonMovingCensus.c +++ b/rts/sm/NonMovingCensus.c @@ -56,7 +56,7 @@ nonmovingAllocatorCensus_(struct NonmovingAllocator *alloc, bool collect_live_wo } } - for (unsigned int cap=0; cap < n_capabilities; cap++) + for (unsigned int cap=0; cap < getNumCapabilities(); cap++) { struct NonmovingSegment *seg = alloc->current[cap]; unsigned int n = nonmovingSegmentBlockCount(seg); diff --git a/rts/sm/NonMovingMark.c b/rts/sm/NonMovingMark.c index 2fd85dc4f0..1b33c7bc6f 100644 --- a/rts/sm/NonMovingMark.c +++ b/rts/sm/NonMovingMark.c @@ -325,7 +325,7 @@ void nonmovingBeginFlush(Task *task) // task suspended due to a foreign call) in which case our requestSync // logic won't have been hit. Make sure that everyone so far has flushed. // Ideally we want to mark asynchronously with syncing. - for (uint32_t i = 0; i < n_capabilities; i++) { + for (uint32_t i = 0; i < getNumCapabilities(); i++) { nonmovingFlushCapUpdRemSetBlocks(capabilities[i]); } } @@ -337,7 +337,7 @@ bool nonmovingWaitForFlush() { ACQUIRE_LOCK(&upd_rem_set_lock); debugTrace(DEBUG_nonmoving_gc, "Flush count %d", upd_rem_set_flush_count); - bool finished = upd_rem_set_flush_count == n_capabilities; + bool finished = upd_rem_set_flush_count == getNumCapabilities(); if (!finished) { waitCondition(&upd_rem_set_flushed_cond, &upd_rem_set_lock); } @@ -400,7 +400,7 @@ bool nonmovingWaitForFlush() void nonmovingFinishFlush(Task *task) { // See Note [Unintentional marking in resurrectThreads] - for (uint32_t i = 0; i < n_capabilities; i++) { + for (uint32_t i = 0; i < getNumCapabilities(); i++) { reset_upd_rem_set(&capabilities[i]->upd_rem_set); } // Also reset upd_rem_set_block_list in case some of the UpdRemSets were @@ -411,7 +411,7 @@ void nonmovingFinishFlush(Task *task) debugTrace(DEBUG_nonmoving_gc, "Finished update remembered set flush..."); traceConcSyncEnd(); stat_endNonmovingGcSync(); - releaseAllCapabilities(n_capabilities, NULL, task); + releaseAllCapabilities(getNumCapabilities(), NULL, task); } #endif @@ -1348,7 +1348,7 @@ mark_closure (MarkQueue *queue, const StgClosure *p0, StgClosure **origin) else if (bd->flags & BF_PINNED) { #if defined(DEBUG) bool found_it = false; - for (uint32_t i = 0; i < n_capabilities; ++i) { + for (uint32_t i = 0; i < getNumCapabilities(); ++i) { if (capabilities[i]->pinned_object_block == bd) { found_it = true; break; diff --git a/rts/sm/NonMovingSweep.c b/rts/sm/NonMovingSweep.c index 1a7c97b7e6..da480ba8f4 100644 --- a/rts/sm/NonMovingSweep.c +++ b/rts/sm/NonMovingSweep.c @@ -279,7 +279,7 @@ dirty_BLOCKING_QUEUE: /* N.B. This happens during the pause so we own all capabilities. */ void nonmovingSweepMutLists() { - for (uint32_t n = 0; n < n_capabilities; n++) { + for (uint32_t n = 0; n < getNumCapabilities(); n++) { Capability *cap = capabilities[n]; bdescr *old_mut_list = cap->mut_lists[oldest_gen->no]; cap->mut_lists[oldest_gen->no] = allocBlockOnNode_lock(cap->node); diff --git a/rts/sm/Sanity.c b/rts/sm/Sanity.c index beafe1ac5f..976d42546a 100644 --- a/rts/sm/Sanity.c +++ b/rts/sm/Sanity.c @@ -622,7 +622,7 @@ void checkNonmovingHeap (const struct NonmovingHeap *heap) const struct NonmovingAllocator *alloc = heap->allocators[i]; checkNonmovingSegments(alloc->filled); checkNonmovingSegments(alloc->active); - for (unsigned int cap=0; cap < n_capabilities; cap++) { + for (unsigned int cap=0; cap < getNumCapabilities(); cap++) { checkNonmovingSegments(alloc->current[cap]); } } @@ -826,7 +826,7 @@ static void checkMutableLists (void) { uint32_t i; - for (i = 0; i < n_capabilities; i++) { + for (i = 0; i < getNumCapabilities(); i++) { checkLocalMutableLists(i); } } @@ -946,7 +946,7 @@ static void checkGeneration (generation *gen, checkHeapChain(gen->blocks); - for (n = 0; n < n_capabilities; n++) { + for (n = 0; n < getNumCapabilities(); n++) { ws = &gc_threads[n]->gens[gen->no]; checkHeapChain(ws->todo_bd); checkHeapChain(ws->part_list); @@ -971,7 +971,7 @@ static void checkFullHeap (bool after_major_gc) for (g = 0; g < RtsFlags.GcFlags.generations; g++) { checkGeneration(&generations[g], after_major_gc); } - for (n = 0; n < n_capabilities; n++) { + for (n = 0; n < getNumCapabilities(); n++) { checkNurserySanity(&nurseries[n]); } } @@ -1019,7 +1019,7 @@ findMemoryLeak (void) { uint32_t g, i, j; for (g = 0; g < RtsFlags.GcFlags.generations; g++) { - for (i = 0; i < n_capabilities; i++) { + for (i = 0; i < getNumCapabilities(); i++) { markBlocks(capabilities[i]->mut_lists[g]); markBlocks(gc_threads[i]->gens[g].part_list); markBlocks(gc_threads[i]->gens[g].scavd_list); @@ -1034,7 +1034,7 @@ findMemoryLeak (void) markBlocks(nurseries[i].blocks); } - for (i = 0; i < n_capabilities; i++) { + for (i = 0; i < getNumCapabilities(); i++) { markBlocks(gc_threads[i]->free_blocks); markBlocks(capabilities[i]->pinned_object_block); markBlocks(capabilities[i]->upd_rem_set.queue.blocks); @@ -1050,7 +1050,7 @@ findMemoryLeak (void) struct NonmovingAllocator *alloc = nonmovingHeap.allocators[i]; markNonMovingSegments(alloc->filled); markNonMovingSegments(alloc->active); - for (j = 0; j < n_capabilities; j++) { + for (j = 0; j < getNumCapabilities(); j++) { markNonMovingSegments(alloc->current[j]); } } @@ -1161,7 +1161,7 @@ countNonMovingAllocator(struct NonmovingAllocator *alloc) { W_ ret = countNonMovingSegments(alloc->filled) + countNonMovingSegments(alloc->active); - for (uint32_t i = 0; i < n_capabilities; ++i) { + for (uint32_t i = 0; i < getNumCapabilities(); ++i) { ret += countNonMovingSegments(alloc->current[i]); } return ret; @@ -1202,7 +1202,7 @@ memInventory (bool show) for (g = 0; g < RtsFlags.GcFlags.generations; g++) { gen_blocks[g] = 0; - for (i = 0; i < n_capabilities; i++) { + for (i = 0; i < getNumCapabilities(); i++) { gen_blocks[g] += countBlocks(capabilities[i]->mut_lists[g]); gen_blocks[g] += countBlocks(gc_threads[i]->gens[g].part_list); gen_blocks[g] += countBlocks(gc_threads[i]->gens[g].scavd_list); @@ -1215,7 +1215,7 @@ memInventory (bool show) ASSERT(countBlocks(nurseries[i].blocks) == nurseries[i].n_blocks); nursery_blocks += nurseries[i].n_blocks; } - for (i = 0; i < n_capabilities; i++) { + for (i = 0; i < getNumCapabilities(); i++) { W_ n = countBlocks(gc_threads[i]->free_blocks); gc_free_blocks += n; if (capabilities[i]->pinned_object_block != NULL) { @@ -1241,7 +1241,7 @@ memInventory (bool show) free_blocks = countFreeList(); // count UpdRemSet blocks - for (i = 0; i < n_capabilities; ++i) { + for (i = 0; i < getNumCapabilities(); ++i) { upd_rem_set_blocks += countBlocks(capabilities[i]->upd_rem_set.queue.blocks); } upd_rem_set_blocks += countBlocks(upd_rem_set_block_list); diff --git a/rts/sm/Storage.c b/rts/sm/Storage.c index 7d450a8931..3a727910cf 100644 --- a/rts/sm/Storage.c +++ b/rts/sm/Storage.c @@ -224,7 +224,7 @@ initStorage (void) #endif if (RtsFlags.GcFlags.useNonmoving) - nonmovingAddCapabilities(n_capabilities); + nonmovingAddCapabilities(getNumCapabilities()); /* The oldest generation has one step. */ if (RtsFlags.GcFlags.compact || RtsFlags.GcFlags.sweep) { @@ -256,7 +256,7 @@ initStorage (void) for (n = 0; n < n_numa_nodes; n++) { next_nursery[n] = n; } - storageAddCapabilities(0, n_capabilities); + storageAddCapabilities(0, getNumCapabilities()); IF_DEBUG(gc, statDescribeGens()); @@ -374,7 +374,7 @@ void listAllBlocks (ListBlocksCb cb, void *user) { uint32_t g, i; for (g = 0; g < RtsFlags.GcFlags.generations; g++) { - for (i = 0; i < n_capabilities; i++) { + for (i = 0; i < getNumCapabilities(); i++) { cb(user, capabilities[i]->mut_lists[g]); cb(user, gc_threads[i]->gens[g].part_list); cb(user, gc_threads[i]->gens[g].scavd_list); @@ -386,7 +386,7 @@ void listAllBlocks (ListBlocksCb cb, void *user) for (i = 0; i < n_nurseries; i++) { cb(user, nurseries[i].blocks); } - for (i = 0; i < n_capabilities; i++) { + for (i = 0; i < getNumCapabilities(); i++) { if (capabilities[i]->pinned_object_block != NULL) { cb(user, capabilities[i]->pinned_object_block); } @@ -818,7 +818,7 @@ resetNurseries (void) for (n = 0; n < n_numa_nodes; n++) { next_nursery[n] = n; } - assignNurseriesToCapabilities(0, n_capabilities); + assignNurseriesToCapabilities(0, getNumCapabilities()); #if defined(DEBUG) bdescr *bd; @@ -1569,7 +1569,7 @@ calcTotalAllocated (void) uint64_t tot_alloc = 0; W_ n; - for (n = 0; n < n_capabilities; n++) { + for (n = 0; n < getNumCapabilities(); n++) { tot_alloc += capabilities[n]->total_allocated; traceEventHeapAllocated(capabilities[n], @@ -1590,7 +1590,7 @@ updateNurseriesStats (void) uint32_t i; bdescr *bd; - for (i = 0; i < n_capabilities; i++) { + for (i = 0; i < getNumCapabilities(); i++) { // The current nursery block and the current allocate block have not // yet been accounted for in cap->total_allocated, so we add them here. bd = capabilities[i]->r.rCurrentNursery; |