[Git][ghc/ghc][wip/tsan/codegen] 3 commits: getCapability
Ben Gamari (@bgamari)
gitlab at gitlab.haskell.org
Wed Nov 16 01:23:34 UTC 2022
Ben Gamari pushed to branch wip/tsan/codegen at Glasgow Haskell Compiler / GHC
Commits:
4d5cbb90 by Ben Gamari at 2022-11-15T17:52:32-05:00
getCapability
- - - - -
723b92f3 by Ben Gamari at 2022-11-15T17:52:33-05:00
rts: Statically allocate capabilities
This is a rather simplistic way of solving #17289.
- - - - -
526e6fb8 by Ben Gamari at 2022-11-15T20:23:26-05:00
Fix it
- - - - -
6 changed files:
- rts/Capability.c
- rts/Capability.h
- rts/IOManager.c
- rts/Schedule.c
- rts/Stats.c
- rts/include/rts/Config.h
Changes:
=====================================
rts/Capability.c
=====================================
@@ -45,7 +45,7 @@ uint32_t enabled_capabilities = 0;
// Capabilities, because there may be pointers to them in use
// (e.g. threads in waitForCapability(), see #8209), so this is
// an array of Capability* rather than an array of Capability.
-Capability **capabilities = NULL;
+Capability *capabilities[MAX_N_CAPABILITIES];
// Holds the Capability which last became free. This is used so that
// an in-call has a chance of quickly finding a free Capability.
@@ -388,6 +388,12 @@ void initCapabilities (void)
}
#endif
+ if (RtsFlags.ParFlags.nCapabilities > MAX_N_CAPABILITIES) {
+ errorBelch("warning: this GHC runtime system only supports up to %d capabilities",
+ MAX_N_CAPABILITIES);
+ RtsFlags.ParFlags.nCapabilities = MAX_N_CAPABILITIES;
+ }
+
n_capabilities = 0;
moreCapabilities(0, RtsFlags.ParFlags.nCapabilities);
n_capabilities = RtsFlags.ParFlags.nCapabilities;
@@ -395,7 +401,6 @@ void initCapabilities (void)
#else /* !THREADED_RTS */
n_capabilities = 1;
- capabilities = stgMallocBytes(sizeof(Capability*), "initCapabilities");
capabilities[0] = &MainCapability;
initCapability(&MainCapability, 0);
@@ -408,7 +413,7 @@ void initCapabilities (void)
// a worker Task to each Capability, which will quickly put the
// Capability on the free list when it finds nothing to do.
for (i = 0; i < n_numa_nodes; i++) {
- last_free_capability[i] = capabilities[0];
+ last_free_capability[i] = getCapability(0);
}
}
@@ -416,8 +421,6 @@ void
moreCapabilities (uint32_t from USED_IF_THREADS, uint32_t to USED_IF_THREADS)
{
#if defined(THREADED_RTS)
- Capability **new_capabilities = stgMallocBytes(to * sizeof(Capability*), "moreCapabilities");
-
// We must disable the timer while we do this since the tick handler may
// call contextSwitchAllCapabilities, which may see the capabilities array
// as we free it. The alternative would be to protect the capabilities
@@ -429,30 +432,22 @@ moreCapabilities (uint32_t from USED_IF_THREADS, uint32_t to USED_IF_THREADS)
// THREADED_RTS must work on builds that don't have a mutable
// BaseReg (eg. unregisterised), so in this case
// capabilities[0] must coincide with &MainCapability.
- new_capabilities[0] = &MainCapability;
+ capabilities[0] = &MainCapability;
initCapability(&MainCapability, 0);
}
else
{
for (uint32_t i = 0; i < to; i++) {
- if (i < from) {
- new_capabilities[i] = capabilities[i];
- } else {
- new_capabilities[i] = stgMallocBytes(sizeof(Capability),
+ if (i >= from) {
+ capabilities[i] = stgMallocBytes(sizeof(Capability),
"moreCapabilities");
- initCapability(new_capabilities[i], i);
+ initCapability(capabilities[i], i);
}
}
}
debugTrace(DEBUG_sched, "allocated %d more capabilities", to - from);
- Capability **old_capabilities = ACQUIRE_LOAD(&capabilities);
- RELEASE_STORE(&capabilities, new_capabilities);
- if (old_capabilities != NULL) {
- stgFree(old_capabilities);
- }
-
startTimer();
#endif
}
@@ -828,8 +823,7 @@ static Capability * find_capability_for_task(const Task * task)
{
if (task->preferred_capability != -1) {
// Does the task have a preferred capability? If so, use it
- return capabilities[task->preferred_capability %
- enabled_capabilities];
+ return getCapability(task->preferred_capability % enabled_capabilities);
} else {
// Try last_free_capability first
Capability *cap = RELAXED_LOAD(&last_free_capability[task->node]);
=====================================
rts/Capability.h
=====================================
@@ -261,11 +261,11 @@ INLINE_HEADER void releaseCapability_ (Capability* cap STG_UNUSED,
// extern uint32_t enabled_capabilities;
// Array of all the capabilities
-extern Capability **capabilities;
+extern Capability *capabilities[MAX_N_CAPABILITIES];
INLINE_HEADER Capability *getCapability(uint32_t i)
{
- return RELAXED_LOAD(&capabilities)[i];
+ return RELAXED_LOAD(&capabilities[i]);
}
//
=====================================
rts/IOManager.c
=====================================
@@ -140,7 +140,7 @@ void
setIOManagerControlFd(uint32_t cap_no USED_IF_THREADS, int fd USED_IF_THREADS) {
#if defined(THREADED_RTS)
if (cap_no < n_capabilities) {
- RELAXED_STORE(&capabilities[cap_no]->io_manager_control_wr_fd, fd);
+ RELAXED_STORE(&getCapability(cap_no)->io_manager_control_wr_fd, fd);
} else {
errorBelch("warning: setIOManagerControlFd called with illegal capability number.");
}
=====================================
rts/Schedule.c
=====================================
@@ -1839,7 +1839,7 @@ delete_threads_and_gc:
tmp_cap = getCapability(i);
ASSERT(tmp_cap->disabled);
if (i != cap->no) {
- dest_cap = capabilities[i % enabled_capabilities];
+ dest_cap = getCapability(i % enabled_capabilities);
while (!emptyRunQueue(tmp_cap)) {
tso = popRunQueue(tmp_cap);
migrateThread(tmp_cap, tso, dest_cap);
@@ -2600,9 +2600,9 @@ scheduleThreadOn(Capability *cap, StgWord cpu USED_IF_THREADS, StgTSO *tso)
if (cpu == cap->no) {
appendToRunQueue(cap,tso);
} else {
- migrateThread(cap, tso, capabilities[cpu]);
+ migrateThread(cap, tso, getCapability(cpu));
}
- contextSwitchCapability(capabilities[cpu], false);
+ contextSwitchCapability(getCapability(cpu), false);
#else
appendToRunQueue(cap,tso);
contextSwitchCapability(cap, false);
=====================================
rts/Stats.c
=====================================
@@ -1351,14 +1351,14 @@ stat_exitReport (void)
sum.bound_task_count = taskCount - workerCount;
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.created += getCapability(i)->spark_stats.created;
+ sum.sparks.dud += getCapability(i)->spark_stats.dud;
sum.sparks.overflowed+=
- capabilities[i]->spark_stats.overflowed;
+ getCapability(i)->spark_stats.overflowed;
sum.sparks.converted +=
- capabilities[i]->spark_stats.converted;
- sum.sparks.gcd += capabilities[i]->spark_stats.gcd;
- sum.sparks.fizzled += capabilities[i]->spark_stats.fizzled;
+ getCapability(i)->spark_stats.converted;
+ sum.sparks.gcd += getCapability(i)->spark_stats.gcd;
+ sum.sparks.fizzled += getCapability(i)->spark_stats.fizzled;
}
sum.sparks_count = sum.sparks.created
@@ -1650,10 +1650,10 @@ statDescribeGens(void)
mut = 0;
for (i = 0; i < getNumCapabilities(); i++) {
- mut += countOccupied(capabilities[i]->mut_lists[g]);
+ mut += countOccupied(getCapability(i)->mut_lists[g]);
// Add the pinned object block.
- bd = capabilities[i]->pinned_object_block;
+ bd = getCapability(i)->pinned_object_block;
if (bd != NULL) {
gen_live += bd->free - bd->start;
gen_blocks += bd->blocks;
=====================================
rts/include/rts/Config.h
=====================================
@@ -76,3 +76,9 @@ code.
#if defined(DEBUG)
#define PROF_SPIN
#endif
+
+#if defined(THREADED_RTS)
+#define MAX_N_CAPABILITIES 256
+#else
+#define MAX_N_CAPABILITIES 1
+#endif
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/de0a6eff379bc2c92717aec5e3513296b631305f...526e6fb85f29270337ad5b4d6761347a996bea03
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/de0a6eff379bc2c92717aec5e3513296b631305f...526e6fb85f29270337ad5b4d6761347a996bea03
You're receiving this email because of your account on gitlab.haskell.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/ghc-commits/attachments/20221115/1a441214/attachment-0001.html>
More information about the ghc-commits
mailing list