qmutex_unix: use a semaphore when available
It makes tst_QMutex::contendedQMutex with no msleep 8 times faster Change-Id: Ic300e7618b4467e4e08b30f0213bd23c06d4d90a Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
parent
e0c8316e17
commit
c7ab816af1
@ -55,11 +55,14 @@
|
||||
|
||||
#if defined(Q_OS_MAC)
|
||||
# include <mach/semaphore.h>
|
||||
#endif
|
||||
|
||||
#if defined(Q_OS_LINUX) && !defined(QT_LINUXBASE)
|
||||
#elif defined(Q_OS_LINUX) && !defined(QT_LINUXBASE)
|
||||
// use Linux mutexes everywhere except for LSB builds
|
||||
# define QT_LINUX_FUTEX
|
||||
#elif defined(Q_OS_UNIX)
|
||||
# if _POSIX_VERSION-0 >= 200112L || _XOPEN_VERSION-0 >= 600
|
||||
# include <semaphore.h>
|
||||
# define QT_UNIX_SEMAPHORE
|
||||
# endif
|
||||
#endif
|
||||
|
||||
struct timespec;
|
||||
@ -120,6 +123,8 @@ public:
|
||||
//platform specific stuff
|
||||
#if defined(Q_OS_MAC)
|
||||
semaphore_t mach_semaphore;
|
||||
#elif defined(QT_UNIX_SEMAPHORE)
|
||||
sem_t semaphore;
|
||||
#elif defined(Q_OS_UNIX)
|
||||
bool wakeup;
|
||||
pthread_mutex_t mutex;
|
||||
|
@ -1,6 +1,7 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 The Qt Company Ltd.
|
||||
** Copyright (C) 2015 Olivier Goffart <ogoffart@woboq.com>
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the QtCore module of the Qt Toolkit.
|
||||
@ -42,6 +43,7 @@
|
||||
#include <errno.h>
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
#include "private/qcore_unix_p.h"
|
||||
|
||||
#if defined(Q_OS_VXWORKS) && defined(wakeup)
|
||||
#undef wakeup
|
||||
@ -55,6 +57,51 @@ static void report_error(int code, const char *where, const char *what)
|
||||
qWarning("%s: %s failure: %s", where, what, qPrintable(qt_error_string(code)));
|
||||
}
|
||||
|
||||
#ifdef QT_UNIX_SEMAPHORE
|
||||
|
||||
QMutexPrivate::QMutexPrivate()
|
||||
{
|
||||
report_error(sem_init(&semaphore, 0, 0), "QMutex", "sem_init");
|
||||
}
|
||||
|
||||
QMutexPrivate::~QMutexPrivate()
|
||||
{
|
||||
|
||||
report_error(sem_destroy(&semaphore), "QMutex", "sem_destroy");
|
||||
}
|
||||
|
||||
bool QMutexPrivate::wait(int timeout)
|
||||
{
|
||||
int errorCode;
|
||||
if (timeout < 0) {
|
||||
do {
|
||||
errorCode = sem_wait(&semaphore);
|
||||
} while (errorCode && errno == EINTR);
|
||||
report_error(errorCode, "QMutex::lock()", "sem_wait");
|
||||
} else {
|
||||
timespec ts;
|
||||
report_error(clock_gettime(CLOCK_REALTIME, &ts), "QMutex::lock()", "clock_gettime");
|
||||
ts.tv_sec += timeout / 1000;
|
||||
ts.tv_nsec += timeout % 1000 * Q_UINT64_C(1000) * 1000;
|
||||
normalizedTimespec(ts);
|
||||
do {
|
||||
errorCode = sem_timedwait(&semaphore, &ts);
|
||||
} while (errorCode && errno == EINTR);
|
||||
|
||||
if (errorCode && errno == ETIMEDOUT)
|
||||
return false;
|
||||
report_error(errorCode, "QMutex::lock()", "sem_timedwait");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void QMutexPrivate::wakeUp() Q_DECL_NOTHROW
|
||||
{
|
||||
report_error(sem_post(&semaphore), "QMutex::unlock", "sem_post");
|
||||
}
|
||||
|
||||
#else // QT_UNIX_SEMAPHORE
|
||||
|
||||
QMutexPrivate::QMutexPrivate()
|
||||
: wakeup(false)
|
||||
{
|
||||
@ -103,6 +150,7 @@ void QMutexPrivate::wakeUp() Q_DECL_NOTHROW
|
||||
report_error(pthread_mutex_unlock(&mutex), "QMutex::unlock", "mutex unlock");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user