Bug 1161405. Part 1 - improve parallelism of nsThreadPool by taking the number of pending events into account when spawning a new thread. r=nfroyd.

This commit is contained in:
JW Wang 2015-05-09 07:32:30 +08:00
parent d153127d04
commit 2730d56e7f
3 changed files with 42 additions and 1 deletions

View File

@ -119,3 +119,39 @@ nsEventQueue::PutEvent(nsIRunnable* aRunnable)
LOG(("EVENTQ(%p): notify\n", this));
mon.NotifyAll();
}
size_t
nsEventQueue::Count()
{
ReentrantMonitorAutoEnter mon(mReentrantMonitor);
// It is obvious count is 0 when the queue is empty.
if (!mHead) {
return 0;
}
/* How we count the number of events in the queue:
* 1. Let pageCount(x, y) denote the number of pages excluding the tail page
* where x is the index of head page and y is the index of the tail page.
* 2. Then we have pageCount(x, y) = y - x.
*
* Ex: pageCount(0, 0) = 0 where both head and tail pages point to page 0.
* pageCount(0, 1) = 1 where head points to page 0 and tail points page 1.
*
* 3. number of events = (EVENTS_PER_PAGE * pageCount(x, y))
* - (empty slots in head page) + (non-empty slots in tail page)
* = (EVENTS_PER_PAGE * pageCount(x, y)) - mOffsetHead + mOffsetTail
*/
int count = -mOffsetHead;
// Compute (EVENTS_PER_PAGE * pageCount(x, y))
for (Page* page = mHead; page != mTail; page = page->mNext) {
count += EVENTS_PER_PAGE;
}
count += mOffsetTail;
MOZ_ASSERT(count >= 0);
return count;
}

View File

@ -51,6 +51,8 @@ public:
return mReentrantMonitor;
}
size_t Count();
private:
bool IsEmpty()

View File

@ -82,7 +82,10 @@ nsThreadPool::PutEvent(nsIRunnable* aEvent)
MOZ_ASSERT(mIdleCount <= (uint32_t)mThreads.Count(), "oops");
// Make sure we have a thread to service this event.
if (mIdleCount == 0 && mThreads.Count() < (int32_t)mThreadLimit) {
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) {
spawnThread = true;
}