summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMorten Sørvig <msorvig@trolltech.com>2009-06-24 13:58:33 (GMT)
committerMorten Sørvig <msorvig@trolltech.com>2009-06-24 13:58:33 (GMT)
commitfa47ad238fe7ee01f3c9f73c498c6290149ca21d (patch)
tree3daeb5bb6ebe72f706f67dfa1057eb198729e19c /src
parent055c9c41b3f659cbbf758d15e8350c5dd2b5faa1 (diff)
downloadQt-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.cpp89
-rw-r--r--src/corelib/concurrent/qtconcurrentthreadengine.h89
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;
}