From ab9fde6c0cd7c50efe52f2923e79470f05f8a1b1 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 10 Aug 2012 16:06:41 +0200 Subject: Split the futexFlags() function in two: a hot and a cold path We could mark the cold path with __attribute__((cold)) (since GCC 4.3), but quick tests locally indicate that the compiler is smart enough to determine that by itself. It will inline the hot path in _q_futex, which in turn is inlined in the lockInternal and unlockInternal functions, whereas the cold path is kept outside. Change-Id: I8ae7d851d4f050498bfb491ba87d3e25453a14f8 Reviewed-by: Olivier Goffart Reviewed-by: Marc Mutz --- src/corelib/thread/qmutex_linux.cpp | 44 ++++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 18 deletions(-) (limited to 'src/corelib/thread/qmutex_linux.cpp') diff --git a/src/corelib/thread/qmutex_linux.cpp b/src/corelib/thread/qmutex_linux.cpp index 3ccaeff4e3..3fb3db258f 100644 --- a/src/corelib/thread/qmutex_linux.cpp +++ b/src/corelib/thread/qmutex_linux.cpp @@ -59,34 +59,42 @@ QT_BEGIN_NAMESPACE -static inline int futexFlags() +static QBasicAtomicInt futexFlagSupport = Q_BASIC_ATOMIC_INITIALIZER(-1); + +static int checkFutexPrivateSupport() { int value = 0; #if defined(FUTEX_PRIVATE_FLAG) // check if the kernel supports extra futex flags // FUTEX_PRIVATE_FLAG appeared in v2.6.22 - static QBasicAtomicInt futexFlagSupport = Q_BASIC_ATOMIC_INITIALIZER(-1); - - value = futexFlagSupport.load(); - if (value == -1) { - // try an operation that has no side-effects: wake up 42 threads - // futex will return -1 (errno==ENOSYS) if the flag isn't supported - // there should be no other error conditions - value = syscall(__NR_futex, &futexFlagSupport, - FUTEX_WAKE | FUTEX_PRIVATE_FLAG, - 42, 0, 0, 0); - if (value != -1) { - value = FUTEX_PRIVATE_FLAG; - futexFlagSupport.store(value); - return value; - } + Q_STATIC_ASSERT(FUTEX_PRIVATE_FLAG != 0x80000000); + + // try an operation that has no side-effects: wake up 42 threads + // futex will return -1 (errno==ENOSYS) if the flag isn't supported + // there should be no other error conditions + value = syscall(__NR_futex, &futexFlagSupport, + FUTEX_WAKE | FUTEX_PRIVATE_FLAG, + 42, 0, 0, 0); + if (value != -1) + value = FUTEX_PRIVATE_FLAG; + else value = 0; - futexFlagSupport.store(value); - } + +#else + value = 0; #endif + futexFlagSupport.store(value); return value; } +static inline int futexFlags() +{ + int value = futexFlagSupport.load(); + if (Q_LIKELY(value != -1)) + return value; + return checkFutexPrivateSupport(); +} + static inline int _q_futex(void *addr, int op, int val, const struct timespec *timeout) Q_DECL_NOTHROW { volatile int *int_addr = reinterpret_cast(addr); -- cgit v1.2.3