Skip to content
Snippets Groups Projects
Commit a433c908 authored by Ben Gamari's avatar Ben Gamari
Browse files

Fix #17289

parent 25b9c7f9
No related branches found
No related tags found
No related merge requests found
...@@ -418,36 +418,44 @@ void ...@@ -418,36 +418,44 @@ void
moreCapabilities (uint32_t from USED_IF_THREADS, uint32_t to USED_IF_THREADS) moreCapabilities (uint32_t from USED_IF_THREADS, uint32_t to USED_IF_THREADS)
{ {
#if defined(THREADED_RTS) #if defined(THREADED_RTS)
uint32_t i; Capability **new_capabilities = stgMallocBytes(to * sizeof(Capability*), "moreCapabilities");
Capability **old_capabilities = capabilities;
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
// array with a lock but this seems more expensive than necessary.
// See #17289.
stopTimer();
if (to == 1) { if (to == 1) {
// THREADED_RTS must work on builds that don't have a mutable // THREADED_RTS must work on builds that don't have a mutable
// BaseReg (eg. unregisterised), so in this case // BaseReg (eg. unregisterised), so in this case
// capabilities[0] must coincide with &MainCapability. // capabilities[0] must coincide with &MainCapability.
capabilities[0] = &MainCapability; new_capabilities[0] = &MainCapability;
initCapability(&MainCapability, 0); initCapability(&MainCapability, 0);
} }
else else
{ {
for (i = 0; i < to; i++) { for (uint32_t i = 0; i < to; i++) {
if (i < from) { if (i < from) {
capabilities[i] = old_capabilities[i]; new_capabilities[i] = capabilities[i];
} else { } else {
capabilities[i] = stgMallocBytes(sizeof(Capability), new_capabilities[i] = stgMallocBytes(sizeof(Capability),
"moreCapabilities"); "moreCapabilities");
initCapability(capabilities[i], i); initCapability(new_capabilities[i], i);
} }
} }
} }
debugTrace(DEBUG_sched, "allocated %d more capabilities", to - from); debugTrace(DEBUG_sched, "allocated %d more capabilities", to - from);
Capability **old_capabilities = ACQUIRE_LOAD(&capabilities);
RELEASE_STORE(&capabilities, new_capabilities);
if (old_capabilities != NULL) { if (old_capabilities != NULL) {
stgFree(old_capabilities); stgFree(old_capabilities);
} }
startTimer();
#endif #endif
} }
......
...@@ -55,7 +55,7 @@ handle_tick(int unused STG_UNUSED) ...@@ -55,7 +55,7 @@ handle_tick(int unused STG_UNUSED)
{ {
handleProfTick(); handleProfTick();
if (RtsFlags.ConcFlags.ctxtSwitchTicks > 0 if (RtsFlags.ConcFlags.ctxtSwitchTicks > 0
&& RELAXED_LOAD(&timer_disabled) == 0) && SEQ_CST_LOAD(&timer_disabled) == 0)
{ {
ticks_to_ctxt_switch--; ticks_to_ctxt_switch--;
if (ticks_to_ctxt_switch <= 0) { if (ticks_to_ctxt_switch <= 0) {
...@@ -119,7 +119,7 @@ initTimer(void) ...@@ -119,7 +119,7 @@ initTimer(void)
if (RtsFlags.MiscFlags.tickInterval != 0) { if (RtsFlags.MiscFlags.tickInterval != 0) {
initTicker(RtsFlags.MiscFlags.tickInterval, handle_tick); initTicker(RtsFlags.MiscFlags.tickInterval, handle_tick);
} }
RELAXED_STORE(&timer_disabled, 1); SEQ_CST_STORE(&timer_disabled, 1);
} }
void void
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment