mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-01 00:32:11 +00:00
Bug 1195767 - part 3 - modify nsThreadPool to use a non-reentrant monitor; r=gerald
There's no reason nsThreadPool needs to use a reentrant monitor for locking its event queue. Having it use a non-reentrant one should be slightly more efficient, both in the general operation of the monitor, and that we're not performing redundant locking in methods like nsThreadPool::Run. This change also eliminates the only usage of nsEventQueue::GetReentrantMonitor.
This commit is contained in:
parent
92e6eccda2
commit
aafe5d489a
@ -48,13 +48,15 @@ NS_IMPL_QUERY_INTERFACE_CI(nsThreadPool, nsIThreadPool, nsIEventTarget,
|
||||
NS_IMPL_CI_INTERFACE_GETTER(nsThreadPool, nsIThreadPool, nsIEventTarget)
|
||||
|
||||
nsThreadPool::nsThreadPool()
|
||||
: mThreadLimit(DEFAULT_THREAD_LIMIT)
|
||||
: mMonitor("[nsThreadPool.mMonitor]")
|
||||
, mThreadLimit(DEFAULT_THREAD_LIMIT)
|
||||
, mIdleThreadLimit(DEFAULT_IDLE_THREAD_LIMIT)
|
||||
, mIdleThreadTimeout(DEFAULT_IDLE_THREAD_TIMEOUT)
|
||||
, mIdleCount(0)
|
||||
, mStackSize(nsIThreadManager::DEFAULT_STACK_SIZE)
|
||||
, mShutdown(false)
|
||||
{
|
||||
LOG(("THRD-P(%p) constructor!!!\n", this));
|
||||
}
|
||||
|
||||
nsThreadPool::~nsThreadPool()
|
||||
@ -79,7 +81,7 @@ nsThreadPool::PutEvent(already_AddRefed<nsIRunnable>&& aEvent)
|
||||
bool spawnThread = false;
|
||||
uint32_t stackSize = 0;
|
||||
{
|
||||
ReentrantMonitorAutoEnter mon(mEvents.GetReentrantMonitor());
|
||||
MonitorAutoLock mon(mMonitor);
|
||||
|
||||
if (NS_WARN_IF(mShutdown)) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
@ -92,11 +94,11 @@ nsThreadPool::PutEvent(already_AddRefed<nsIRunnable>&& aEvent)
|
||||
if (mThreads.Count() < (int32_t)mThreadLimit &&
|
||||
// Spawn a new thread if we don't have enough idle threads to serve
|
||||
// pending events immediately.
|
||||
mEvents.Count() >= mIdleCount) {
|
||||
mEvents.Count(mon) >= mIdleCount) {
|
||||
spawnThread = true;
|
||||
}
|
||||
|
||||
mEvents.PutEvent(Move(aEvent));
|
||||
mEvents.PutEvent(Move(aEvent), mon);
|
||||
stackSize = mStackSize;
|
||||
}
|
||||
|
||||
@ -115,7 +117,7 @@ nsThreadPool::PutEvent(already_AddRefed<nsIRunnable>&& aEvent)
|
||||
|
||||
bool killThread = false;
|
||||
{
|
||||
ReentrantMonitorAutoEnter mon(mEvents.GetReentrantMonitor());
|
||||
MonitorAutoLock mon(mMonitor);
|
||||
if (mThreads.Count() < (int32_t)mThreadLimit) {
|
||||
mThreads.AppendObject(thread);
|
||||
} else {
|
||||
@ -157,10 +159,10 @@ nsThreadPool::ShutdownThread(nsIThread* aThread)
|
||||
NS_IMETHODIMP
|
||||
nsThreadPool::Run()
|
||||
{
|
||||
LOG(("THRD-P(%p) enter\n", this));
|
||||
|
||||
mThreadNaming.SetThreadPoolName(mName);
|
||||
|
||||
LOG(("THRD-P(%p) enter %s\n", this, mName.BeginReading()));
|
||||
|
||||
nsCOMPtr<nsIThread> current;
|
||||
nsThreadManager::get()->GetCurrentThread(getter_AddRefs(current));
|
||||
|
||||
@ -171,7 +173,7 @@ nsThreadPool::Run()
|
||||
|
||||
nsCOMPtr<nsIThreadPoolListener> listener;
|
||||
{
|
||||
ReentrantMonitorAutoEnter mon(mEvents.GetReentrantMonitor());
|
||||
MonitorAutoLock mon(mMonitor);
|
||||
listener = mListener;
|
||||
}
|
||||
|
||||
@ -182,8 +184,8 @@ nsThreadPool::Run()
|
||||
do {
|
||||
nsCOMPtr<nsIRunnable> event;
|
||||
{
|
||||
ReentrantMonitorAutoEnter mon(mEvents.GetReentrantMonitor());
|
||||
if (!mEvents.GetPendingEvent(getter_AddRefs(event))) {
|
||||
MonitorAutoLock mon(mMonitor);
|
||||
if (!mEvents.GetPendingEvent(getter_AddRefs(event), mon)) {
|
||||
PRIntervalTime now = PR_IntervalNow();
|
||||
PRIntervalTime timeout = PR_MillisecondsToInterval(mIdleThreadTimeout);
|
||||
|
||||
@ -215,8 +217,9 @@ nsThreadPool::Run()
|
||||
shutdownThreadOnExit = mThreads.RemoveObject(current);
|
||||
} else {
|
||||
PRIntervalTime delta = timeout - (now - idleSince);
|
||||
LOG(("THRD-P(%p) waiting [%d]\n", this, delta));
|
||||
LOG(("THRD-P(%p) %s waiting [%d]\n", this, mName.BeginReading(), delta));
|
||||
mon.Wait(delta);
|
||||
LOG(("THRD-P(%p) done waiting\n", this));
|
||||
}
|
||||
} else if (wasIdle) {
|
||||
wasIdle = false;
|
||||
@ -224,7 +227,7 @@ nsThreadPool::Run()
|
||||
}
|
||||
}
|
||||
if (event) {
|
||||
LOG(("THRD-P(%p) running [%p]\n", this, event.get()));
|
||||
LOG(("THRD-P(%p) %s running [%p]\n", this, mName.BeginReading(), event.get()));
|
||||
event->Run();
|
||||
}
|
||||
} while (!exitThread);
|
||||
@ -281,7 +284,7 @@ nsThreadPool::Dispatch(already_AddRefed<nsIRunnable>&& aEvent, uint32_t aFlags)
|
||||
NS_IMETHODIMP
|
||||
nsThreadPool::IsOnCurrentThread(bool* aResult)
|
||||
{
|
||||
ReentrantMonitorAutoEnter mon(mEvents.GetReentrantMonitor());
|
||||
MonitorAutoLock mon(mMonitor);
|
||||
if (NS_WARN_IF(mShutdown)) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
@ -303,7 +306,7 @@ nsThreadPool::Shutdown()
|
||||
nsCOMArray<nsIThread> threads;
|
||||
nsCOMPtr<nsIThreadPoolListener> listener;
|
||||
{
|
||||
ReentrantMonitorAutoEnter mon(mEvents.GetReentrantMonitor());
|
||||
MonitorAutoLock mon(mMonitor);
|
||||
mShutdown = true;
|
||||
mon.NotifyAll();
|
||||
|
||||
@ -336,7 +339,8 @@ nsThreadPool::GetThreadLimit(uint32_t* aValue)
|
||||
NS_IMETHODIMP
|
||||
nsThreadPool::SetThreadLimit(uint32_t aValue)
|
||||
{
|
||||
ReentrantMonitorAutoEnter mon(mEvents.GetReentrantMonitor());
|
||||
MonitorAutoLock mon(mMonitor);
|
||||
LOG(("THRD-P(%p) thread limit [%u]\n", this, aValue));
|
||||
mThreadLimit = aValue;
|
||||
if (mIdleThreadLimit > mThreadLimit) {
|
||||
mIdleThreadLimit = mThreadLimit;
|
||||
@ -358,7 +362,8 @@ nsThreadPool::GetIdleThreadLimit(uint32_t* aValue)
|
||||
NS_IMETHODIMP
|
||||
nsThreadPool::SetIdleThreadLimit(uint32_t aValue)
|
||||
{
|
||||
ReentrantMonitorAutoEnter mon(mEvents.GetReentrantMonitor());
|
||||
MonitorAutoLock mon(mMonitor);
|
||||
LOG(("THRD-P(%p) idle thread limit [%u]\n", this, aValue));
|
||||
mIdleThreadLimit = aValue;
|
||||
if (mIdleThreadLimit > mThreadLimit) {
|
||||
mIdleThreadLimit = mThreadLimit;
|
||||
@ -381,7 +386,7 @@ nsThreadPool::GetIdleThreadTimeout(uint32_t* aValue)
|
||||
NS_IMETHODIMP
|
||||
nsThreadPool::SetIdleThreadTimeout(uint32_t aValue)
|
||||
{
|
||||
ReentrantMonitorAutoEnter mon(mEvents.GetReentrantMonitor());
|
||||
MonitorAutoLock mon(mMonitor);
|
||||
uint32_t oldTimeout = mIdleThreadTimeout;
|
||||
mIdleThreadTimeout = aValue;
|
||||
|
||||
@ -395,7 +400,7 @@ nsThreadPool::SetIdleThreadTimeout(uint32_t aValue)
|
||||
NS_IMETHODIMP
|
||||
nsThreadPool::GetThreadStackSize(uint32_t* aValue)
|
||||
{
|
||||
ReentrantMonitorAutoEnter mon(mEvents.GetReentrantMonitor());
|
||||
MonitorAutoLock mon(mMonitor);
|
||||
*aValue = mStackSize;
|
||||
return NS_OK;
|
||||
}
|
||||
@ -403,7 +408,7 @@ nsThreadPool::GetThreadStackSize(uint32_t* aValue)
|
||||
NS_IMETHODIMP
|
||||
nsThreadPool::SetThreadStackSize(uint32_t aValue)
|
||||
{
|
||||
ReentrantMonitorAutoEnter mon(mEvents.GetReentrantMonitor());
|
||||
MonitorAutoLock mon(mMonitor);
|
||||
mStackSize = aValue;
|
||||
return NS_OK;
|
||||
}
|
||||
@ -411,7 +416,7 @@ nsThreadPool::SetThreadStackSize(uint32_t aValue)
|
||||
NS_IMETHODIMP
|
||||
nsThreadPool::GetListener(nsIThreadPoolListener** aListener)
|
||||
{
|
||||
ReentrantMonitorAutoEnter mon(mEvents.GetReentrantMonitor());
|
||||
MonitorAutoLock mon(mMonitor);
|
||||
NS_IF_ADDREF(*aListener = mListener);
|
||||
return NS_OK;
|
||||
}
|
||||
@ -421,7 +426,7 @@ nsThreadPool::SetListener(nsIThreadPoolListener* aListener)
|
||||
{
|
||||
nsCOMPtr<nsIThreadPoolListener> swappedListener(aListener);
|
||||
{
|
||||
ReentrantMonitorAutoEnter mon(mEvents.GetReentrantMonitor());
|
||||
MonitorAutoLock mon(mMonitor);
|
||||
mListener.swap(swappedListener);
|
||||
}
|
||||
return NS_OK;
|
||||
@ -431,7 +436,7 @@ NS_IMETHODIMP
|
||||
nsThreadPool::SetName(const nsACString& aName)
|
||||
{
|
||||
{
|
||||
ReentrantMonitorAutoEnter mon(mEvents.GetReentrantMonitor());
|
||||
MonitorAutoLock mon(mMonitor);
|
||||
if (mThreads.Count()) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "nsThreadUtils.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/AlreadyAddRefed.h"
|
||||
#include "mozilla/Monitor.h"
|
||||
|
||||
class nsThreadPool final
|
||||
: public nsIThreadPool
|
||||
@ -41,7 +42,8 @@ private:
|
||||
nsresult PutEvent(already_AddRefed<nsIRunnable>&& aEvent);
|
||||
|
||||
nsCOMArray<nsIThread> mThreads;
|
||||
nsEventQueue mEvents;
|
||||
mozilla::Monitor mMonitor;
|
||||
nsEventQueueBase<mozilla::Monitor> mEvents;
|
||||
uint32_t mThreadLimit;
|
||||
uint32_t mIdleThreadLimit;
|
||||
uint32_t mIdleThreadTimeout;
|
||||
|
Loading…
Reference in New Issue
Block a user