Skip to content

Commit dfca1b4

Browse files
committed
[GC] Only use per CPU arena if the number of running thread is 2x the number of cores.
1 parent a1a8c96 commit dfca1b4

File tree

2 files changed

+35
-5
lines changed

2 files changed

+35
-5
lines changed

sdlib/d/gc/tcache.d

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -650,16 +650,16 @@ private:
650650
}
651651

652652
void reassociateArena(bool force = false) {
653-
if (force) {
654-
associatedArena = -1;
655-
}
656-
657653
import d.gc.cpu, d.gc.thread;
658-
if (getRegisteredThreadCount() > getCoreCount()) {
654+
if (getRunningThreadCount() > 2 * getCoreCount()) {
659655
// When large number of thread are runnign, select arena
660656
// based on the CPU core this trhead runs on.
661657
associatedArena = -1;
662658
} else {
659+
if (force) {
660+
associatedArena = -1;
661+
}
662+
663663
// When the number of thread is low, pick and arena
664664
// and stick to it.
665665
associatedArena = selectArenaGroup();

sdlib/d/gc/thread.d

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,14 @@ uint getRegisteredThreadCount() {
4949
return gThreadState.getRegisteredThreadCount();
5050
}
5151

52+
uint getSuspendedThreadCount() {
53+
return gThreadState.getSuspendedThreadCount();
54+
}
55+
56+
uint getRunningThreadCount() {
57+
return gThreadState.getRunningThreadCount();
58+
}
59+
5260
void enterBusyState() {
5361
threadCache.state.enterBusyState();
5462
}
@@ -90,6 +98,7 @@ private:
9098
import d.sync.atomic;
9199
Atomic!uint startingThreadCount;
92100
uint registeredThreadCount = 0;
101+
uint suspendedThreadCount = 0;
93102

94103
RegisteredThreadRing registeredThreads;
95104

@@ -129,6 +138,21 @@ public:
129138
return (cast(ThreadState*) &this).registeredThreadCount;
130139
}
131140

141+
auto getSuspendedThreadCount() shared {
142+
mutex.lock();
143+
scope(exit) mutex.unlock();
144+
145+
return (cast(ThreadState*) &this).suspendedThreadCount;
146+
}
147+
148+
auto getRunningThreadCount() shared {
149+
mutex.lock();
150+
scope(exit) mutex.unlock();
151+
152+
auto state = cast(ThreadState*) &this;
153+
return state.registeredThreadCount - state.suspendedThreadCount;
154+
}
155+
132156
void stopTheWorld() shared {
133157
import d.gc.hooks;
134158
__sd_gc_pre_stop_the_world_hook();
@@ -182,6 +206,7 @@ private:
182206

183207
bool suspendRunningThreadsImpl() {
184208
bool retry = false;
209+
uint suspended = 0;
185210

186211
auto r = registeredThreads.range;
187212
while (!r.empty) {
@@ -195,6 +220,7 @@ private:
195220

196221
// If the thread isn't already stopped, we'll need to retry.
197222
auto ss = tc.state.suspendState;
223+
suspended += ss == SuspendState.Suspended;
198224
retry |= ss != SuspendState.Suspended;
199225

200226
// If the thread has already been signaled.
@@ -206,6 +232,7 @@ private:
206232
signalThreadSuspend(tc);
207233
}
208234

235+
suspendedThreadCount = suspended;
209236
return retry;
210237
}
211238

@@ -218,6 +245,7 @@ private:
218245

219246
bool resumeSuspendedThreadsImpl() {
220247
bool retry = false;
248+
uint suspended = 0;
221249

222250
auto r = registeredThreads.range;
223251
while (!r.empty) {
@@ -226,6 +254,7 @@ private:
226254

227255
// If the thread isn't already resumed, we'll need to retry.
228256
auto ss = tc.state.suspendState;
257+
suspended += ss == SuspendState.Suspended;
229258
retry |= ss != SuspendState.None;
230259

231260
// If the thread isn't suspended, move on.
@@ -237,6 +266,7 @@ private:
237266
signalThreadResume(tc);
238267
}
239268

269+
suspendedThreadCount = suspended;
240270
return retry;
241271
}
242272

0 commit comments

Comments
 (0)