summaryrefslogtreecommitdiffstats
path: root/src/corelib/thread/qmutex_unix.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/thread/qmutex_unix.cpp')
-rw-r--r--src/corelib/thread/qmutex_unix.cpp116
1 files changed, 3 insertions, 113 deletions
diff --git a/src/corelib/thread/qmutex_unix.cpp b/src/corelib/thread/qmutex_unix.cpp
index 2a9d23c361..0bccad589d 100644
--- a/src/corelib/thread/qmutex_unix.cpp
+++ b/src/corelib/thread/qmutex_unix.cpp
@@ -46,142 +46,35 @@
#ifndef QT_NO_THREAD
#include "qatomic.h"
#include "qmutex_p.h"
-
#include <errno.h>
#if defined(Q_OS_VXWORKS) && defined(wakeup)
#undef wakeup
#endif
-#if defined(Q_OS_MAC)
-# include <mach/mach.h>
-# include <mach/task.h>
-#elif defined(Q_OS_LINUX)
-# include <linux/futex.h>
-# include <sys/syscall.h>
-# include <unistd.h>
-# include <QtCore/qelapsedtimer.h>
-#endif
-
QT_BEGIN_NAMESPACE
-#if !defined(Q_OS_MAC) && !defined(Q_OS_LINUX)
static void report_error(int code, const char *where, const char *what)
{
if (code != 0)
qWarning("%s: %s failure: %s", where, what, qPrintable(qt_error_string(code)));
}
-#endif
-
QMutexPrivate::QMutexPrivate(QMutex::RecursionMode mode)
- : QMutexData(mode), maximumSpinTime(MaximumSpinTimeThreshold), averageWaitTime(0), owner(0), count(0)
+ : recursive(mode == QMutex::Recursive), wakeup(false)
{
-#if defined(Q_OS_MAC)
- kern_return_t r = semaphore_create(mach_task_self(), &mach_semaphore, SYNC_POLICY_FIFO, 0);
- if (r != KERN_SUCCESS)
- qWarning("QMutex: failed to create semaphore, error %d", r);
-#elif !defined(Q_OS_LINUX)
- wakeup = false;
report_error(pthread_mutex_init(&mutex, NULL), "QMutex", "mutex init");
report_error(pthread_cond_init(&cond, NULL), "QMutex", "cv init");
-#endif
}
QMutexPrivate::~QMutexPrivate()
{
-#if defined(Q_OS_MAC)
- kern_return_t r = semaphore_destroy(mach_task_self(), mach_semaphore);
- if (r != KERN_SUCCESS)
- qWarning("QMutex: failed to destroy semaphore, error %d", r);
-#elif !defined(Q_OS_LINUX)
report_error(pthread_cond_destroy(&cond), "QMutex", "cv destroy");
report_error(pthread_mutex_destroy(&mutex), "QMutex", "mutex destroy");
-#endif
}
-#if defined(Q_OS_MAC)
-
bool QMutexPrivate::wait(int timeout)
{
- if (contenders.fetchAndAddAcquire(1) == 0) {
- // lock acquired without waiting
- return true;
- }
- kern_return_t r;
- if (timeout < 0) {
- do {
- r = semaphore_wait(mach_semaphore);
- } while (r == KERN_ABORTED);
- if (r != KERN_SUCCESS)
- qWarning("QMutex: infinite wait failed, error %d", r);
- } else {
- mach_timespec_t ts;
- ts.tv_nsec = ((timeout % 1000) * 1000) * 1000;
- ts.tv_sec = (timeout / 1000);
- r = semaphore_timedwait(mach_semaphore, ts);
- }
- contenders.deref();
- return r == KERN_SUCCESS;
-}
-
-void QMutexPrivate::wakeUp()
-{
- semaphore_signal(mach_semaphore);
-}
-
-#elif defined(Q_OS_LINUX)
-
-static inline int _q_futex(volatile int *addr, int op, int val, const struct timespec *timeout, int *addr2, int val2)
-{
- return syscall(SYS_futex, addr, op, val, timeout, addr2, val2);
-}
-
-bool QMutexPrivate::wait(int timeout)
-{
- struct timespec ts, *pts = 0;
- QElapsedTimer timer;
- if (timeout >= 0) {
- ts.tv_nsec = ((timeout % 1000) * 1000) * 1000;
- ts.tv_sec = (timeout / 1000);
- pts = &ts;
- timer.start();
- }
- while (contenders.fetchAndStoreAcquire(2) > 0) {
- int r = _q_futex(&contenders._q_value, FUTEX_WAIT, 2, pts, 0, 0);
- if (r != 0 && errno == ETIMEDOUT)
- return false;
-
- if (pts) {
- // recalculate the timeout
- qint64 xtimeout = timeout * 1000 * 1000;
- xtimeout -= timer.nsecsElapsed();
- if (xtimeout < 0) {
- // timer expired after we returned
- return false;
- }
-
- ts.tv_sec = xtimeout / Q_INT64_C(1000) / 1000 / 1000;
- ts.tv_nsec = xtimeout % (Q_INT64_C(1000) * 1000 * 1000);
- }
- }
- return true;
-}
-
-void QMutexPrivate::wakeUp()
-{
- (void) contenders.fetchAndStoreRelease(0);
- (void) _q_futex(&contenders._q_value, FUTEX_WAKE, 1, 0, 0, 0);
-}
-
-#else // !Q_OS_MAC && !Q_OS_LINUX
-
-bool QMutexPrivate::wait(int timeout)
-{
- if (contenders.fetchAndAddAcquire(1) == 0) {
- // lock acquired without waiting
- return true;
- }
report_error(pthread_mutex_lock(&mutex), "QMutex::lock", "mutex lock");
int errorCode = 0;
while (!wakeup) {
@@ -190,12 +83,10 @@ bool QMutexPrivate::wait(int timeout)
} else {
struct timeval tv;
gettimeofday(&tv, 0);
-
timespec ti;
ti.tv_nsec = (tv.tv_usec + (timeout % 1000) * 1000) * 1000;
ti.tv_sec = tv.tv_sec + (timeout / 1000) + (ti.tv_nsec / 1000000000);
ti.tv_nsec %= 1000000000;
-
errorCode = pthread_cond_timedwait(&cond, &mutex, &ti);
}
if (errorCode) {
@@ -207,10 +98,10 @@ bool QMutexPrivate::wait(int timeout)
report_error(errorCode, "QMutex::lock()", "cv wait");
}
}
+ bool ret = wakeup;
wakeup = false;
report_error(pthread_mutex_unlock(&mutex), "QMutex::lock", "mutex unlock");
- contenders.deref();
- return errorCode == 0;
+ return ret;
}
void QMutexPrivate::wakeUp()
@@ -221,7 +112,6 @@ void QMutexPrivate::wakeUp()
report_error(pthread_mutex_unlock(&mutex), "QMutex::unlock", "mutex unlock");
}
-#endif // !Q_OS_MAC && !Q_OS_LINUX
QT_END_NAMESPACE