diff options
author | Morten Sørvig <msorvig@trolltech.com> | 2009-06-24 13:58:33 (GMT) |
---|---|---|
committer | Morten Sørvig <msorvig@trolltech.com> | 2009-06-24 13:58:33 (GMT) |
commit | fa47ad238fe7ee01f3c9f73c498c6290149ca21d (patch) | |
tree | 3daeb5bb6ebe72f706f67dfa1057eb198729e19c /src | |
parent | 055c9c41b3f659cbbf758d15e8350c5dd2b5faa1 (diff) | |
download | Qt-fa47ad238fe7ee01f3c9f73c498c6290149ca21d.zip Qt-fa47ad238fe7ee01f3c9f73c498c6290149ca21d.tar.gz Qt-fa47ad238fe7ee01f3c9f73c498c6290149ca21d.tar.bz2 |
Rename ThreadEngineSemaphore -> ThreadEngineBarrier
Also move the implementation to the .cpp file.
Diffstat (limited to 'src')
-rw-r--r-- | src/corelib/concurrent/qtconcurrentthreadengine.cpp | 89 | ||||
-rw-r--r-- | src/corelib/concurrent/qtconcurrentthreadengine.h | 89 |
2 files changed, 93 insertions, 85 deletions
diff --git a/src/corelib/concurrent/qtconcurrentthreadengine.cpp b/src/corelib/concurrent/qtconcurrentthreadengine.cpp index 5356e82..150540a 100644 --- a/src/corelib/concurrent/qtconcurrentthreadengine.cpp +++ b/src/corelib/concurrent/qtconcurrentthreadengine.cpp @@ -47,6 +47,81 @@ QT_BEGIN_NAMESPACE namespace QtConcurrent { +ThreadEngineBarrier::ThreadEngineBarrier() +:count(0) { } + +void ThreadEngineBarrier::acquire() +{ + forever { + int localCount = int(count); + if (localCount < 0) { + if (count.testAndSetOrdered(localCount, localCount -1)) + return; + } else { + if (count.testAndSetOrdered(localCount, localCount + 1)) + return; + } + } +} + +int ThreadEngineBarrier::release() +{ + forever { + int localCount = int(count); + if (localCount == -1) { + if (count.testAndSetOrdered(-1, 0)) { + semaphore.release(); + return 0; + } + } else if (localCount < 0) { + if (count.testAndSetOrdered(localCount, localCount + 1)) + return qAbs(localCount + 1); + } else { + if (count.testAndSetOrdered(localCount, localCount - 1)) + return localCount - 1; + } + } +} + +// Wait until all threads have been released +void ThreadEngineBarrier::wait() +{ + forever { + int localCount = int(count); + if (localCount == 0) + return; + + Q_ASSERT(localCount > 0); // multiple waiters are not allowed. + if (count.testAndSetOrdered(localCount, -localCount)) { + semaphore.acquire(); + return; + } + } +} + +int ThreadEngineBarrier::currentCount() +{ + return int(count); +} + +// releases a thread, unless this is the last thread. +// returns true if the thread was released. +bool ThreadEngineBarrier::releaseUnlessLast() +{ + forever { + int localCount = int(count); + if (qAbs(localCount) == 1) { + return false; + } else if (localCount < 0) { + if (count.testAndSetOrdered(localCount, localCount + 1)) + return true; + } else { + if (count.testAndSetOrdered(localCount, localCount - 1)) + return true; + } + } +} + ThreadEngineBase::ThreadEngineBase() :futureInterface(0), threadPool(QThreadPool::globalInstance()) { @@ -66,7 +141,7 @@ void ThreadEngineBase::startSingleThreaded() void ThreadEngineBase::startBlocking() { start(); - semaphore.acquire(); + barrier.acquire(); startThreads(); bool throttled = false; @@ -88,10 +163,10 @@ void ThreadEngineBase::startBlocking() #endif if (throttled == false) { - semaphore.release(); + barrier.release(); } - semaphore.wait(); + barrier.wait(); finish(); exceptionStore.throwPossibleException(); } @@ -138,9 +213,9 @@ bool ThreadEngineBase::startThreadInternal() if (this->isCanceled()) return false; - semaphore.acquire(); + barrier.acquire(); if (!threadPool->tryStart(this)) { - semaphore.release(); + barrier.release(); return false; } return true; @@ -155,7 +230,7 @@ void ThreadEngineBase::startThreads() void ThreadEngineBase::threadExit() { const bool asynchronous = futureInterface != 0; - const int lastThread = (semaphore.release() == 0); + const int lastThread = (barrier.release() == 0); if (lastThread && asynchronous) this->asynchronousFinish(); @@ -166,7 +241,7 @@ void ThreadEngineBase::threadExit() // this function returns one. bool ThreadEngineBase::threadThrottleExit() { - return semaphore.releaseUnlessLast(); + return barrier.releaseUnlessLast(); } void ThreadEngineBase::run() // implements QRunnable. diff --git a/src/corelib/concurrent/qtconcurrentthreadengine.h b/src/corelib/concurrent/qtconcurrentthreadengine.h index 21a3a28..286c2b8 100644 --- a/src/corelib/concurrent/qtconcurrentthreadengine.h +++ b/src/corelib/concurrent/qtconcurrentthreadengine.h @@ -63,91 +63,24 @@ QT_MODULE(Core) namespace QtConcurrent { -// The ThreadEngineSemaphore counts worker threads, and allows one +// The ThreadEngineBarrier counts worker threads, and allows one // thread to wait for all others to finish. Tested for its use in // QtConcurrent, requires more testing for use as a general class. -class ThreadEngineSemaphore +class ThreadEngineBarrier { private: // The thread count is maintained as an integer in the count atomic // variable. The count can be either positive or negative - a negative - // count signals that a thread is waiting on the semaphore. + // count signals that a thread is waiting on the barrier. QAtomicInt count; QSemaphore semaphore; public: - ThreadEngineSemaphore() - :count(0) { } - - void acquire() - { - forever { - int localCount = int(count); - if (localCount < 0) { - if (count.testAndSetOrdered(localCount, localCount -1)) - return; - } else { - if (count.testAndSetOrdered(localCount, localCount + 1)) - return; - } - } - } - - int release() - { - forever { - int localCount = int(count); - if (localCount == -1) { - if (count.testAndSetOrdered(-1, 0)) { - semaphore.release(); - return 0; - } - } else if (localCount < 0) { - if (count.testAndSetOrdered(localCount, localCount + 1)) - return qAbs(localCount + 1); - } else { - if (count.testAndSetOrdered(localCount, localCount - 1)) - return localCount - 1; - } - } - } - - // Wait until all threads have been released - void wait() - { - forever { - int localCount = int(count); - if (localCount == 0) - return; - - if (count.testAndSetOrdered(localCount, -localCount)) { - semaphore.acquire(); - return; - } - } - } - - int currentCount() - { - return int(count); - } - - // releases a thread, unless this is the last thread. - // returns true if the thread was released. - bool releaseUnlessLast() - { - forever { - int localCount = int(count); - if (qAbs(localCount) == 1) { - return false; - } else if (localCount < 0) { - if (count.testAndSetOrdered(localCount, localCount + 1)) - return true; - } else { - if (count.testAndSetOrdered(localCount, localCount - 1)) - return true; - } - } - } + ThreadEngineBarrier(); + void acquire(); + int release(); + void wait(); + int currentCount(); + bool releaseUnlessLast(); }; enum ThreadFunctionResult { ThrottleThread, ThreadFinished }; @@ -190,7 +123,7 @@ private: protected: QFutureInterfaceBase *futureInterface; QThreadPool *threadPool; - ThreadEngineSemaphore semaphore; + ThreadEngineBarrier barrier; QtConcurrent::internal::ExceptionStore exceptionStore; }; @@ -237,7 +170,7 @@ public: QFuture<T> future = QFuture<T>(futureInterfaceTyped()); start(); - semaphore.acquire(); + barrier.acquire(); threadPool->start(this); return future; } |