Bug 1817757 - Part 2: Increase helper thread ceiling for parallel marking r=sfink

Add two extra threads to the requested thread count above those for parallel
marking to ensure we can start the number of marking tasks requested.

Depends on D170375

Differential Revision: https://phabricator.services.mozilla.com/D170376
This commit is contained in:
Jon Coppeard 2023-02-22 08:56:28 +00:00
Родитель 624da0ed61
Коммит 6b1af3aba1
3 изменённых файлов: 21 добавлений и 6 удалений

Просмотреть файл

@ -1317,6 +1317,13 @@ void GCRuntime::updateHelperThreadCount() {
return;
}
// Number of extra threads required during parallel marking to ensure we can
// start the necessary marking tasks. Background free and background
// allocation may already be running and we want to avoid these tasks blocking
// marking. In real configurations there will be enough threads that this
// won't affect anything.
static constexpr size_t SpareThreadsDuringParallelMarking = 2;
// The count of helper threads used for GC tasks is process wide. Don't set it
// for worker JS runtimes.
if (rt->parentRuntime) {
@ -1330,9 +1337,11 @@ void GCRuntime::updateHelperThreadCount() {
size_t(1), maxHelperThreads.ref());
// Calculate the overall target thread count taking into account the separate
// parameter for parallel marking threads.
// parameter for parallel marking threads. Add spare threads to avoid blocking
// parallel marking when there is other GC work happening.
size_t targetCount =
std::max(helperThreadCount.ref(), markingThreadCount.ref());
std::max(helperThreadCount.ref(),
markingThreadCount.ref() + SpareThreadsDuringParallelMarking);
// Attempt to create extra threads if possible. This is not supported when
// using an external thread pool.
@ -1342,9 +1351,12 @@ void GCRuntime::updateHelperThreadCount() {
// Limit all thread counts based on the number of threads available, which may
// be fewer than requested.
size_t availableThreadCount = GetHelperThreadCount();
MOZ_ASSERT(availableThreadCount != 0);
targetCount = std::min(targetCount, availableThreadCount);
helperThreadCount = std::min(helperThreadCount.ref(), availableThreadCount);
markingThreadCount = std::min(markingThreadCount.ref(), availableThreadCount);
markingThreadCount =
std::min(markingThreadCount.ref(),
availableThreadCount - SpareThreadsDuringParallelMarking);
// Update the maximum number of threads that will be used for GC work.
HelperThreadState().setGCParallelThreadCount(targetCount, lock);

Просмотреть файл

@ -22,6 +22,10 @@ bool ParallelMarker::mark(SliceBudget& sliceBudget) {
{
AutoLockHelperThreadState lock;
MOZ_ASSERT(workerCount() <= HelperThreadState().maxGCParallelThreads(lock));
// TODO: Even if the thread limits checked above are correct, there may not
// be enough threads available to start our mark tasks immediately due to
// other runtimes in the same process running GC.
}
#endif

Просмотреть файл

@ -1,13 +1,12 @@
// |jit-test| skip-if: helperThreadCount() === 0
let initialHelperThreadCount = helperThreadCount();
let initialGCHelperThreadCount = gcparam('helperThreadCount');
let prevHelperThreadCount = initialHelperThreadCount;
let prevHelperThreadCount = helperThreadCount();
for (let i of [0, 1, 4, 8, 4, 0]) {
gcparam('markingThreadCount', i);
assertEq(gcparam('markingThreadCount'), i);
assertEq(gcparam('helperThreadCount'), initialGCHelperThreadCount);
assertEq(helperThreadCount(), Math.max(prevHelperThreadCount, i));
assertEq(true, helperThreadCount() >= Math.max(prevHelperThreadCount, i));
prevHelperThreadCount = helperThreadCount();
}