fune/xpcom/threads/nsThreadPool.h
Jens Stutte 8963e87fce Bug 1891664 - Have a grace timeout before shutting down excess idle threads. r=xpcom-reviewers,necko-reviewers,dom-storage-reviewers,nika,janv,jesup#!xpcom-reviewers
Have idleThreadGraceTimeout and idleThreadMaximumTimeout instead of just idleThreadTimeout.
Clarify that idleThreadMaximumTimeout is only affecting allowed idle threads.
Make idle threads end only after at minimum idleThreadGraceTimeout even if they are in excess.
Remove the idleThreadTimeoutRegressive setting.

Introduce a "most recently used" priority for notifying idle threads to
avoid excessive round-robin through all available idle threads.
The management of the linked list has constant time, adding thus only
minimal overhead wrt to the previous wasIdle flags we had.

As a side effect (and coming from the investigations in bug 1891732) to
some extent this can help to improve the "logical thread affinity",
together with trying to keep events dispatched with NS_DISPATCH_AT_END
on the dispatching thread as much as possible, which should help
TaskQueue a lot with affinity.

Differential Revision: https://phabricator.services.mozilla.com/D209884
2024-06-01 09:05:53 +00:00

78 lines
2.7 KiB
C++

/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef nsThreadPool_h__
#define nsThreadPool_h__
#include "nsIThread.h"
#include "nsIThreadPool.h"
#include "nsIRunnable.h"
#include "nsCOMArray.h"
#include "nsCOMPtr.h"
#include "nsThreadUtils.h"
#include "mozilla/Atomics.h"
#include "mozilla/AlreadyAddRefed.h"
#include "mozilla/CondVar.h"
#include "mozilla/EventQueue.h"
#include "mozilla/LinkedList.h"
#include "mozilla/Mutex.h"
class nsIThread;
class nsThreadPool final : public mozilla::Runnable, public nsIThreadPool {
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIEVENTTARGET_FULL
NS_DECL_NSITHREADPOOL
NS_DECL_NSIRUNNABLE
nsThreadPool();
static void InitTLS();
static nsThreadPool* GetCurrentThreadPool();
private:
~nsThreadPool();
struct MRUIdleEntry; // forward declaration only, see nsThreadPool.cpp
void ShutdownThread(nsIThread* aThread);
nsresult PutEvent(nsIRunnable* aEvent);
nsresult PutEvent(already_AddRefed<nsIRunnable> aEvent, uint32_t aFlags);
void NotifyChangeToAllIdleThreads() MOZ_REQUIRES(mMutex);
#ifdef DEBUG
void DebugLogPoolStatus(mozilla::MutexAutoLock& aProofOfLock,
MRUIdleEntry* aWakingEntry = nullptr)
MOZ_REQUIRES(mMutex);
#endif
mozilla::Mutex mMutex;
nsCOMArray<nsIThread> mThreads MOZ_GUARDED_BY(mMutex);
mozilla::EventQueue mEvents MOZ_GUARDED_BY(mMutex);
uint32_t mThreadLimit MOZ_GUARDED_BY(mMutex);
uint32_t mIdleThreadLimit MOZ_GUARDED_BY(mMutex);
mozilla::TimeDuration mIdleThreadGraceTimeout MOZ_GUARDED_BY(mMutex);
mozilla::TimeDuration mIdleThreadMaxTimeout MOZ_GUARDED_BY(mMutex);
mozilla::LinkedList<MRUIdleEntry> mMRUIdleThreads MOZ_GUARDED_BY(mMutex);
nsIThread::QoSPriority mQoSPriority MOZ_GUARDED_BY(mMutex);
uint32_t mStackSize MOZ_GUARDED_BY(mMutex);
nsCOMPtr<nsIThreadPoolListener> mListener MOZ_GUARDED_BY(mMutex);
mozilla::Atomic<bool, mozilla::Relaxed> mShutdown;
mozilla::Atomic<bool, mozilla::Relaxed> mIsAPoolThreadFree;
// set once before we start threads
nsCString mName MOZ_GUARDED_BY(mMutex);
nsThreadPoolNaming mThreadNaming; // all data inside this is atomic
};
#define NS_THREADPOOL_CID \
{ /* 547ec2a8-315e-4ec4-888e-6e4264fe90eb */ \
0x547ec2a8, 0x315e, 0x4ec4, { \
0x88, 0x8e, 0x6e, 0x42, 0x64, 0xfe, 0x90, 0xeb \
} \
}
#endif // nsThreadPool_h__