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 <ogoffart@woboq.com>
Reviewed-by: Marc Mutz <marc.mutz@kdab.com>
This commit is contained in:
Thiago Macieira 2012-08-10 16:06:41 +02:00 committed by Qt by Nokia
parent c28204066c
commit ab9fde6c0c

View File

@ -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);
Q_STATIC_ASSERT(FUTEX_PRIVATE_FLAG != 0x80000000);
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) {
if (value != -1)
value = FUTEX_PRIVATE_FLAG;
futexFlagSupport.store(value);
return value;
}
else
value = 0;
#else
value = 0;
futexFlagSupport.store(value);
}
#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<volatile int *>(addr);