From: Thiago Macieira Date: Fri, 10 Aug 2012 14:06:41 +0000 (+0200) Subject: Split the futexFlags() function in two: a hot and a cold path X-Git-Tag: v5.0.0-beta1~39 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=ab9fde6c0cd7c50efe52f2923e79470f05f8a1b1;p=profile%2Fivi%2Fqtbase.git 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 --- diff --git a/src/corelib/thread/qmutex_linux.cpp b/src/corelib/thread/qmutex_linux.cpp index 3ccaeff..3fb3db2 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);