diff options
author | Liang Qi <liang.qi@qt.io> | 2017-10-15 21:05:08 +0200 |
---|---|---|
committer | Orgad Shaneh <orgad.shaneh@audiocodes.com> | 2017-10-16 22:21:52 +0300 |
commit | 01afc8c810201b93a12fe7030344e03566d99001 (patch) | |
tree | 27727b38370209dc158856b4bb4d32ccd2e49fbe /src/corelib/thread/qthreadpool_p.h | |
parent | a090076e93487f8e461d9b866b9da1c0c21cb59b (diff) | |
parent | 49da5ce10034161017b261e000d4e9063d962401 (diff) |
Merge remote-tracking branch 'origin/5.9' into 5.10
Change-Id: I3cf73c53cf131d0babfb558c2507bed0e0fc5f08
Diffstat (limited to 'src/corelib/thread/qthreadpool_p.h')
-rw-r--r-- | src/corelib/thread/qthreadpool_p.h | 84 |
1 files changed, 83 insertions, 1 deletions
diff --git a/src/corelib/thread/qthreadpool_p.h b/src/corelib/thread/qthreadpool_p.h index 8b6a8cc476..d03ba9d77f 100644 --- a/src/corelib/thread/qthreadpool_p.h +++ b/src/corelib/thread/qthreadpool_p.h @@ -63,6 +63,87 @@ QT_BEGIN_NAMESPACE +class QueuePage { +public: + enum { + MaxPageSize = 256 + }; + + QueuePage(QRunnable *runnable, int pri) + : m_priority(pri) + { + push(runnable); + } + + bool isFull() { + return m_lastIndex >= MaxPageSize - 1; + } + + bool isFinished() { + return m_firstIndex > m_lastIndex; + } + + void push(QRunnable *runnable) { + Q_ASSERT(runnable != nullptr); + Q_ASSERT(!isFull()); + m_lastIndex += 1; + m_entries[m_lastIndex] = runnable; + } + + void skipToNextOrEnd() { + while (!isFinished() && m_entries[m_firstIndex] == nullptr) { + m_firstIndex += 1; + } + } + + QRunnable *first() { + Q_ASSERT(!isFinished()); + QRunnable *runnable = m_entries[m_firstIndex]; + Q_ASSERT(runnable); + return runnable; + } + + QRunnable *pop() { + Q_ASSERT(!isFinished()); + QRunnable *runnable = first(); + Q_ASSERT(runnable); + + // clear the entry although this should not be necessary + m_entries[m_firstIndex] = nullptr; + m_firstIndex += 1; + + // make sure the next runnable returned by first() is not a nullptr + skipToNextOrEnd(); + + return runnable; + } + + bool tryTake(QRunnable *runnable) { + Q_ASSERT(!isFinished()); + for (int i = m_firstIndex; i <= m_lastIndex; i++) { + if (m_entries[i] == runnable) { + m_entries[i] = nullptr; + if (i == m_firstIndex) { + // make sure first() does not return a nullptr + skipToNextOrEnd(); + } + return true; + } + } + return false; + } + + int priority() const { + return m_priority; + } + +private: + int m_priority = 0; + int m_firstIndex = 0; + int m_lastIndex = -1; + QRunnable *m_entries[MaxPageSize]; +}; + class QThreadPoolThread; class Q_CORE_EXPORT QThreadPoolPrivate : public QObjectPrivate { @@ -84,12 +165,13 @@ public: bool waitForDone(int msecs); void clear(); void stealAndRunRunnable(QRunnable *runnable); + void deletePageIfFinished(QueuePage *page); mutable QMutex mutex; QList<QThreadPoolThread *> allThreads; QQueue<QThreadPoolThread *> waitingThreads; QQueue<QThreadPoolThread *> expiredThreads; - QVector<QPair<QRunnable *, int> > queue; + QVector<QueuePage*> queue; QWaitCondition noActiveThreads; int expiryTimeout = 30000; |