mirror of
https://sourceware.org/git/glibc.git
synced 2025-07-29 11:41:21 +03:00
FUTEX_*_REQUEUE_PI support for non-x86 code
Add FUTEX_*_REQUEUE_PI support for the default C code and also add implementations for s-390 and ppc.
This commit is contained in:
6
NEWS
6
NEWS
@ -9,9 +9,9 @@ Version 2.18
|
|||||||
|
|
||||||
* The following bugs are resolved with this release:
|
* The following bugs are resolved with this release:
|
||||||
|
|
||||||
11561, 13951, 14142, 14200, 14317, 14327, 14496, 14964, 14981, 14982,
|
11561, 13951, 14142, 14200, 14317, 14327, 14496, 14920, 14964, 14981,
|
||||||
14985, 14994, 14996, 15003, 15006, 15020, 15023, 15036, 15054, 15062,
|
14982, 14985, 14994, 14996, 15003, 15006, 15020, 15023, 15036, 15054,
|
||||||
15078.
|
15062, 15078.
|
||||||
|
|
||||||
|
|
||||||
Version 2.17
|
Version 2.17
|
||||||
|
@ -1,3 +1,33 @@
|
|||||||
|
2013-02-18 Siddhesh Poyarekar <siddhesh@redhat.com>
|
||||||
|
|
||||||
|
[BZ #14920]
|
||||||
|
* pthreadP.h (USE_REQUEUE_PI): New macro to check if mutex is
|
||||||
|
PI-aware.
|
||||||
|
* pthread_cond_broadcast.c (__pthread_cond_broadcast): Use
|
||||||
|
PI-aware futex operations if available and mutex is PI-aware.
|
||||||
|
* pthread_cond_signal.c (__pthread_cond_signal): Likewise.
|
||||||
|
* nptl/pthread_cond_timedwait.c (__pthread_cond_timedwait):
|
||||||
|
Likewise.
|
||||||
|
* pthread_cond_wait.c (__condvar_cleanup): Adjust lock if
|
||||||
|
cancellation occurred just after futex returned successfully
|
||||||
|
from a PI operation with the mutex held.
|
||||||
|
(__pthread_cond_wait): Use PI-aware futex operations if
|
||||||
|
available and mutex is PI-aware.
|
||||||
|
* sysdeps/unix/sysv/linux/powerpc/lowlevellock.h
|
||||||
|
(FUTEX_WAIT_REQUEUE_PI): Define.
|
||||||
|
(FUTEX_CMP_REQUEUE_PI): Likewise.
|
||||||
|
(lll_futex_wait_requeue_pi): Likewise.
|
||||||
|
(lll_futex_timed_wait_requeue_pi): Likewise.
|
||||||
|
(lll_futex_cmp_requeue_pi): Likewise.
|
||||||
|
* nptl/sysdeps/unix/sysv/linux/s390/lowlevellock.h
|
||||||
|
(FUTEX_WAIT_REQUEUE_PI): Define.
|
||||||
|
(FUTEX_CMP_REQUEUE_PI): Likewise.
|
||||||
|
(lll_futex_wait_requeue_pi): Likewise.
|
||||||
|
(lll_futex_timed_wait_requeue_pi): Likewise.
|
||||||
|
(lll_futex_cmp_requeue_pi): Likewise.
|
||||||
|
* sysdeps/unix/sysv/linux/kernel-features.h: Define
|
||||||
|
__ASSUME_REQUEUE_PI for Linux version higher than 2.6.31.
|
||||||
|
|
||||||
2013-02-04 Andreas Schwab <schwab@suse.de>
|
2013-02-04 Andreas Schwab <schwab@suse.de>
|
||||||
|
|
||||||
[BZ #14142]
|
[BZ #14142]
|
||||||
|
@ -577,4 +577,16 @@ extern void __wait_lookup_done (void) attribute_hidden;
|
|||||||
# define PTHREAD_STATIC_FN_REQUIRE(name) __asm (".globl " #name);
|
# define PTHREAD_STATIC_FN_REQUIRE(name) __asm (".globl " #name);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Test if the mutex is suitable for the FUTEX_WAIT_REQUEUE_PI operation. */
|
||||||
|
#if (defined lll_futex_wait_requeue_pi \
|
||||||
|
&& defined __ASSUME_REQUEUE_PI)
|
||||||
|
# define USE_REQUEUE_PI(mut) \
|
||||||
|
((mut) && (mut) != (void *) ~0l \
|
||||||
|
&& (((mut)->__data.__kind \
|
||||||
|
& (PTHREAD_MUTEX_PRIO_INHERIT_NP | PTHREAD_MUTEX_ROBUST_NORMAL_NP)) \
|
||||||
|
== PTHREAD_MUTEX_PRIO_INHERIT_NP))
|
||||||
|
#else
|
||||||
|
# define USE_REQUEUE_PI(mut) 0
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* pthreadP.h */
|
#endif /* pthreadP.h */
|
||||||
|
@ -53,34 +53,37 @@ __pthread_cond_broadcast (cond)
|
|||||||
/* We are done. */
|
/* We are done. */
|
||||||
lll_unlock (cond->__data.__lock, pshared);
|
lll_unlock (cond->__data.__lock, pshared);
|
||||||
|
|
||||||
/* Do not use requeue for pshared condvars. */
|
|
||||||
if (cond->__data.__mutex == (void *) ~0l)
|
|
||||||
goto wake_all;
|
|
||||||
|
|
||||||
/* Wake everybody. */
|
/* Wake everybody. */
|
||||||
pthread_mutex_t *mut = (pthread_mutex_t *) cond->__data.__mutex;
|
pthread_mutex_t *mut = (pthread_mutex_t *) cond->__data.__mutex;
|
||||||
|
|
||||||
/* XXX: Kernel so far doesn't support requeue to PI futex. */
|
/* Do not use requeue for pshared condvars. */
|
||||||
/* XXX: Kernel so far can only requeue to the same type of futex,
|
if (mut == (void *) ~0l
|
||||||
in this case private (we don't requeue for pshared condvars). */
|
|| PTHREAD_MUTEX_PSHARED (mut) & PTHREAD_MUTEX_PSHARED_BIT)
|
||||||
if (__builtin_expect (mut->__data.__kind
|
|
||||||
& (PTHREAD_MUTEX_PRIO_INHERIT_NP
|
|
||||||
| PTHREAD_MUTEX_PSHARED_BIT), 0))
|
|
||||||
goto wake_all;
|
goto wake_all;
|
||||||
|
|
||||||
/* lll_futex_requeue returns 0 for success and non-zero
|
#if (defined lll_futex_cmp_requeue_pi \
|
||||||
for errors. */
|
&& defined __ASSUME_REQUEUE_PI)
|
||||||
if (__builtin_expect (lll_futex_requeue (&cond->__data.__futex, 1,
|
int pi_flag = PTHREAD_MUTEX_PRIO_INHERIT_NP | PTHREAD_MUTEX_ROBUST_NP;
|
||||||
INT_MAX, &mut->__data.__lock,
|
pi_flag &= mut->__data.__kind;
|
||||||
futex_val, LLL_PRIVATE), 0))
|
|
||||||
{
|
|
||||||
/* The requeue functionality is not available. */
|
|
||||||
wake_all:
|
|
||||||
lll_futex_wake (&cond->__data.__futex, INT_MAX, pshared);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* That's all. */
|
if (pi_flag == PTHREAD_MUTEX_PRIO_INHERIT_NP)
|
||||||
return 0;
|
{
|
||||||
|
if (lll_futex_cmp_requeue_pi (&cond->__data.__futex, 1, INT_MAX,
|
||||||
|
&mut->__data.__lock, futex_val,
|
||||||
|
LLL_PRIVATE) == 0)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
/* lll_futex_requeue returns 0 for success and non-zero
|
||||||
|
for errors. */
|
||||||
|
if (!__builtin_expect (lll_futex_requeue (&cond->__data.__futex, 1,
|
||||||
|
INT_MAX, &mut->__data.__lock,
|
||||||
|
futex_val, LLL_PRIVATE), 0))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
wake_all:
|
||||||
|
lll_futex_wake (&cond->__data.__futex, INT_MAX, pshared);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We are done. */
|
/* We are done. */
|
||||||
|
@ -47,12 +47,35 @@ __pthread_cond_signal (cond)
|
|||||||
++cond->__data.__wakeup_seq;
|
++cond->__data.__wakeup_seq;
|
||||||
++cond->__data.__futex;
|
++cond->__data.__futex;
|
||||||
|
|
||||||
/* Wake one. */
|
#if (defined lll_futex_cmp_requeue_pi \
|
||||||
if (! __builtin_expect (lll_futex_wake_unlock (&cond->__data.__futex, 1,
|
&& defined __ASSUME_REQUEUE_PI)
|
||||||
1, &cond->__data.__lock,
|
int pi_flag = PTHREAD_MUTEX_PRIO_INHERIT_NP | PTHREAD_MUTEX_ROBUST_NP;
|
||||||
pshared), 0))
|
pthread_mutex_t *mut = cond->__data.__mutex;
|
||||||
return 0;
|
|
||||||
|
|
||||||
|
/* Do not use requeue for pshared condvars. */
|
||||||
|
if (mut != (void *) ~0l)
|
||||||
|
pi_flag &= mut->__data.__kind;
|
||||||
|
|
||||||
|
if (__builtin_expect (pi_flag == PTHREAD_MUTEX_PRIO_INHERIT_NP, 0)
|
||||||
|
/* This can only really fail with a ENOSYS, since nobody can modify
|
||||||
|
futex while we have the cond_lock. */
|
||||||
|
&& lll_futex_cmp_requeue_pi (&cond->__data.__futex, 1, 0,
|
||||||
|
&mut->__data.__lock,
|
||||||
|
cond->__data.__futex, pshared) == 0)
|
||||||
|
{
|
||||||
|
lll_unlock (cond->__data.__lock, pshared);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
/* Wake one. */
|
||||||
|
if (! __builtin_expect (lll_futex_wake_unlock (&cond->__data.__futex,
|
||||||
|
1, 1,
|
||||||
|
&cond->__data.__lock,
|
||||||
|
pshared), 0))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* Fallback if neither of them work. */
|
||||||
lll_futex_wake (&cond->__data.__futex, 1, pshared);
|
lll_futex_wake (&cond->__data.__futex, 1, pshared);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,6 +64,11 @@ __pthread_cond_timedwait (cond, mutex, abstime)
|
|||||||
int pshared = (cond->__data.__mutex == (void *) ~0l)
|
int pshared = (cond->__data.__mutex == (void *) ~0l)
|
||||||
? LLL_SHARED : LLL_PRIVATE;
|
? LLL_SHARED : LLL_PRIVATE;
|
||||||
|
|
||||||
|
#if (defined lll_futex_timed_wait_requeue_pi \
|
||||||
|
&& defined __ASSUME_REQUEUE_PI)
|
||||||
|
int pi_flag = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Make sure we are alone. */
|
/* Make sure we are alone. */
|
||||||
lll_lock (cond->__data.__lock, pshared);
|
lll_lock (cond->__data.__lock, pshared);
|
||||||
|
|
||||||
@ -155,17 +160,46 @@ __pthread_cond_timedwait (cond, mutex, abstime)
|
|||||||
/* Enable asynchronous cancellation. Required by the standard. */
|
/* Enable asynchronous cancellation. Required by the standard. */
|
||||||
cbuffer.oldtype = __pthread_enable_asynccancel ();
|
cbuffer.oldtype = __pthread_enable_asynccancel ();
|
||||||
|
|
||||||
|
/* REQUEUE_PI was implemented after FUTEX_CLOCK_REALTIME, so it is sufficient
|
||||||
|
to check just the former. */
|
||||||
|
#if (defined lll_futex_timed_wait_requeue_pi \
|
||||||
|
&& defined __ASSUME_REQUEUE_PI)
|
||||||
|
/* If pi_flag remained 1 then it means that we had the lock and the mutex
|
||||||
|
but a spurious waker raced ahead of us. Give back the mutex before
|
||||||
|
going into wait again. */
|
||||||
|
if (pi_flag)
|
||||||
|
{
|
||||||
|
__pthread_mutex_cond_lock_adjust (mutex);
|
||||||
|
__pthread_mutex_unlock_usercnt (mutex, 0);
|
||||||
|
}
|
||||||
|
pi_flag = USE_REQUEUE_PI (mutex);
|
||||||
|
|
||||||
|
if (pi_flag)
|
||||||
|
{
|
||||||
|
unsigned int clockbit = (cond->__data.__nwaiters & 1
|
||||||
|
? 0 : FUTEX_CLOCK_REALTIME);
|
||||||
|
err = lll_futex_timed_wait_requeue_pi (&cond->__data.__futex,
|
||||||
|
futex_val, abstime, clockbit,
|
||||||
|
&mutex->__data.__lock,
|
||||||
|
pshared);
|
||||||
|
pi_flag = (err == 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
|
||||||
|
{
|
||||||
#if (!defined __ASSUME_FUTEX_CLOCK_REALTIME \
|
#if (!defined __ASSUME_FUTEX_CLOCK_REALTIME \
|
||||||
|| !defined lll_futex_timed_wait_bitset)
|
|| !defined lll_futex_timed_wait_bitset)
|
||||||
/* Wait until woken by signal or broadcast. */
|
/* Wait until woken by signal or broadcast. */
|
||||||
err = lll_futex_timed_wait (&cond->__data.__futex,
|
err = lll_futex_timed_wait (&cond->__data.__futex,
|
||||||
futex_val, &rt, pshared);
|
futex_val, &rt, pshared);
|
||||||
#else
|
#else
|
||||||
unsigned int clockbit = (cond->__data.__nwaiters & 1
|
unsigned int clockbit = (cond->__data.__nwaiters & 1
|
||||||
? 0 : FUTEX_CLOCK_REALTIME);
|
? 0 : FUTEX_CLOCK_REALTIME);
|
||||||
err = lll_futex_timed_wait_bitset (&cond->__data.__futex, futex_val,
|
err = lll_futex_timed_wait_bitset (&cond->__data.__futex, futex_val,
|
||||||
abstime, clockbit, pshared);
|
abstime, clockbit, pshared);
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
/* Disable asynchronous cancellation. */
|
/* Disable asynchronous cancellation. */
|
||||||
__pthread_disable_asynccancel (cbuffer.oldtype);
|
__pthread_disable_asynccancel (cbuffer.oldtype);
|
||||||
@ -217,7 +251,16 @@ __pthread_cond_timedwait (cond, mutex, abstime)
|
|||||||
__pthread_cleanup_pop (&buffer, 0);
|
__pthread_cleanup_pop (&buffer, 0);
|
||||||
|
|
||||||
/* Get the mutex before returning. */
|
/* Get the mutex before returning. */
|
||||||
err = __pthread_mutex_cond_lock (mutex);
|
#if (defined lll_futex_timed_wait_requeue_pi \
|
||||||
|
&& defined __ASSUME_REQUEUE_PI)
|
||||||
|
if (pi_flag)
|
||||||
|
{
|
||||||
|
__pthread_mutex_cond_lock_adjust (mutex);
|
||||||
|
err = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
err = __pthread_mutex_cond_lock (mutex);
|
||||||
|
|
||||||
return err ?: result;
|
return err ?: result;
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,6 @@
|
|||||||
#include <shlib-compat.h>
|
#include <shlib-compat.h>
|
||||||
#include <stap-probe.h>
|
#include <stap-probe.h>
|
||||||
|
|
||||||
|
|
||||||
struct _condvar_cleanup_buffer
|
struct _condvar_cleanup_buffer
|
||||||
{
|
{
|
||||||
int oldtype;
|
int oldtype;
|
||||||
@ -85,8 +84,15 @@ __condvar_cleanup (void *arg)
|
|||||||
lll_futex_wake (&cbuffer->cond->__data.__futex, INT_MAX, pshared);
|
lll_futex_wake (&cbuffer->cond->__data.__futex, INT_MAX, pshared);
|
||||||
|
|
||||||
/* Get the mutex before returning unless asynchronous cancellation
|
/* Get the mutex before returning unless asynchronous cancellation
|
||||||
is in effect. */
|
is in effect. We don't try to get the mutex if we already own it. */
|
||||||
__pthread_mutex_cond_lock (cbuffer->mutex);
|
if (!(USE_REQUEUE_PI (cbuffer->mutex))
|
||||||
|
|| ((cbuffer->mutex->__data.__lock & FUTEX_TID_MASK)
|
||||||
|
!= THREAD_GETMEM (THREAD_SELF, tid)))
|
||||||
|
{
|
||||||
|
__pthread_mutex_cond_lock (cbuffer->mutex);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
__pthread_mutex_cond_lock_adjust (cbuffer->mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -101,6 +107,11 @@ __pthread_cond_wait (cond, mutex)
|
|||||||
int pshared = (cond->__data.__mutex == (void *) ~0l)
|
int pshared = (cond->__data.__mutex == (void *) ~0l)
|
||||||
? LLL_SHARED : LLL_PRIVATE;
|
? LLL_SHARED : LLL_PRIVATE;
|
||||||
|
|
||||||
|
#if (defined lll_futex_wait_requeue_pi \
|
||||||
|
&& defined __ASSUME_REQUEUE_PI)
|
||||||
|
int pi_flag = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
LIBC_PROBE (cond_wait, 2, cond, mutex);
|
LIBC_PROBE (cond_wait, 2, cond, mutex);
|
||||||
|
|
||||||
/* Make sure we are alone. */
|
/* Make sure we are alone. */
|
||||||
@ -144,15 +155,36 @@ __pthread_cond_wait (cond, mutex)
|
|||||||
do
|
do
|
||||||
{
|
{
|
||||||
unsigned int futex_val = cond->__data.__futex;
|
unsigned int futex_val = cond->__data.__futex;
|
||||||
|
|
||||||
/* Prepare to wait. Release the condvar futex. */
|
/* Prepare to wait. Release the condvar futex. */
|
||||||
lll_unlock (cond->__data.__lock, pshared);
|
lll_unlock (cond->__data.__lock, pshared);
|
||||||
|
|
||||||
/* Enable asynchronous cancellation. Required by the standard. */
|
/* Enable asynchronous cancellation. Required by the standard. */
|
||||||
cbuffer.oldtype = __pthread_enable_asynccancel ();
|
cbuffer.oldtype = __pthread_enable_asynccancel ();
|
||||||
|
|
||||||
/* Wait until woken by signal or broadcast. */
|
#if (defined lll_futex_wait_requeue_pi \
|
||||||
lll_futex_wait (&cond->__data.__futex, futex_val, pshared);
|
&& defined __ASSUME_REQUEUE_PI)
|
||||||
|
/* If pi_flag remained 1 then it means that we had the lock and the mutex
|
||||||
|
but a spurious waker raced ahead of us. Give back the mutex before
|
||||||
|
going into wait again. */
|
||||||
|
if (pi_flag)
|
||||||
|
{
|
||||||
|
__pthread_mutex_cond_lock_adjust (mutex);
|
||||||
|
__pthread_mutex_unlock_usercnt (mutex, 0);
|
||||||
|
}
|
||||||
|
pi_flag = USE_REQUEUE_PI (mutex);
|
||||||
|
|
||||||
|
if (pi_flag)
|
||||||
|
{
|
||||||
|
err = lll_futex_wait_requeue_pi (&cond->__data.__futex,
|
||||||
|
futex_val, &mutex->__data.__lock,
|
||||||
|
pshared);
|
||||||
|
|
||||||
|
pi_flag = (err == 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
/* Wait until woken by signal or broadcast. */
|
||||||
|
lll_futex_wait (&cond->__data.__futex, futex_val, pshared);
|
||||||
|
|
||||||
/* Disable asynchronous cancellation. */
|
/* Disable asynchronous cancellation. */
|
||||||
__pthread_disable_asynccancel (cbuffer.oldtype);
|
__pthread_disable_asynccancel (cbuffer.oldtype);
|
||||||
@ -189,8 +221,17 @@ __pthread_cond_wait (cond, mutex)
|
|||||||
/* The cancellation handling is back to normal, remove the handler. */
|
/* The cancellation handling is back to normal, remove the handler. */
|
||||||
__pthread_cleanup_pop (&buffer, 0);
|
__pthread_cleanup_pop (&buffer, 0);
|
||||||
|
|
||||||
/* Get the mutex before returning. */
|
/* Get the mutex before returning. Not needed for PI. */
|
||||||
return __pthread_mutex_cond_lock (mutex);
|
#if (defined lll_futex_wait_requeue_pi \
|
||||||
|
&& defined __ASSUME_REQUEUE_PI)
|
||||||
|
if (pi_flag)
|
||||||
|
{
|
||||||
|
__pthread_mutex_cond_lock_adjust (mutex);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
return __pthread_mutex_cond_lock (mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
versioned_symbol (libpthread, __pthread_cond_wait, pthread_cond_wait,
|
versioned_symbol (libpthread, __pthread_cond_wait, pthread_cond_wait,
|
||||||
|
@ -39,6 +39,8 @@
|
|||||||
#define FUTEX_TRYLOCK_PI 8
|
#define FUTEX_TRYLOCK_PI 8
|
||||||
#define FUTEX_WAIT_BITSET 9
|
#define FUTEX_WAIT_BITSET 9
|
||||||
#define FUTEX_WAKE_BITSET 10
|
#define FUTEX_WAKE_BITSET 10
|
||||||
|
#define FUTEX_WAIT_REQUEUE_PI 11
|
||||||
|
#define FUTEX_CMP_REQUEUE_PI 12
|
||||||
#define FUTEX_PRIVATE_FLAG 128
|
#define FUTEX_PRIVATE_FLAG 128
|
||||||
#define FUTEX_CLOCK_REALTIME 256
|
#define FUTEX_CLOCK_REALTIME 256
|
||||||
|
|
||||||
@ -149,6 +151,34 @@
|
|||||||
INTERNAL_SYSCALL_ERROR_P (__ret, __err); \
|
INTERNAL_SYSCALL_ERROR_P (__ret, __err); \
|
||||||
})
|
})
|
||||||
|
|
||||||
|
/* Priority Inheritance support. */
|
||||||
|
#define lll_futex_wait_requeue_pi(futexp, val, mutex, private) \
|
||||||
|
lll_futex_timed_wait_requeue_pi (futexp, val, NULL, 0, mutex, private)
|
||||||
|
|
||||||
|
#define lll_futex_timed_wait_requeue_pi(futexp, val, timespec, clockbit, \
|
||||||
|
mutex, private) \
|
||||||
|
({ \
|
||||||
|
INTERNAL_SYSCALL_DECL (__err); \
|
||||||
|
long int __ret; \
|
||||||
|
int __op = FUTEX_WAIT_REQUEUE_PI | clockbit; \
|
||||||
|
\
|
||||||
|
__ret = INTERNAL_SYSCALL (futex, __err, 5, (futexp), \
|
||||||
|
__lll_private_flag (__op, private), \
|
||||||
|
(val), (timespec), mutex); \
|
||||||
|
INTERNAL_SYSCALL_ERROR_P (__ret, __err) ? -__ret : __ret; \
|
||||||
|
})
|
||||||
|
|
||||||
|
#define lll_futex_cmp_requeue_pi(futexp, nr_wake, nr_move, mutex, val, priv) \
|
||||||
|
({ \
|
||||||
|
INTERNAL_SYSCALL_DECL (__err); \
|
||||||
|
long int __ret; \
|
||||||
|
\
|
||||||
|
__ret = INTERNAL_SYSCALL (futex, __err, 6, (futexp), \
|
||||||
|
__lll_private_flag (FUTEX_CMP_REQUEUE_PI, priv),\
|
||||||
|
(nr_wake), (nr_move), (mutex), (val)); \
|
||||||
|
INTERNAL_SYSCALL_ERROR_P (__ret, __err); \
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
#ifdef UP
|
#ifdef UP
|
||||||
# define __lll_acq_instr ""
|
# define __lll_acq_instr ""
|
||||||
|
@ -37,6 +37,8 @@
|
|||||||
#define FUTEX_TRYLOCK_PI 8
|
#define FUTEX_TRYLOCK_PI 8
|
||||||
#define FUTEX_WAIT_BITSET 9
|
#define FUTEX_WAIT_BITSET 9
|
||||||
#define FUTEX_WAKE_BITSET 10
|
#define FUTEX_WAKE_BITSET 10
|
||||||
|
#define FUTEX_WAIT_REQUEUE_PI 11
|
||||||
|
#define FUTEX_CMP_REQUEUE_PI 12
|
||||||
#define FUTEX_PRIVATE_FLAG 128
|
#define FUTEX_PRIVATE_FLAG 128
|
||||||
#define FUTEX_CLOCK_REALTIME 256
|
#define FUTEX_CLOCK_REALTIME 256
|
||||||
|
|
||||||
@ -141,6 +143,32 @@
|
|||||||
INTERNAL_SYSCALL_ERROR_P (__ret, __err); \
|
INTERNAL_SYSCALL_ERROR_P (__ret, __err); \
|
||||||
})
|
})
|
||||||
|
|
||||||
|
/* Priority Inheritance support. */
|
||||||
|
#define lll_futex_wait_requeue_pi(futexp, val, mutex, private) \
|
||||||
|
lll_futex_timed_wait_requeue_pi (futexp, val, NULL, 0, mutex, private)
|
||||||
|
|
||||||
|
#define lll_futex_timed_wait_requeue_pi(futexp, val, timespec, clockbit, \
|
||||||
|
mutex, private) \
|
||||||
|
({ \
|
||||||
|
INTERNAL_SYSCALL_DECL (__err); \
|
||||||
|
int __op = FUTEX_WAIT_REQUEUE_PI | clockbit; \
|
||||||
|
\
|
||||||
|
INTERNAL_SYSCALL (futex, __err, 5, (futexp), \
|
||||||
|
__lll_private_flag (__op, private), \
|
||||||
|
(val), (timespec), mutex); \
|
||||||
|
})
|
||||||
|
|
||||||
|
#define lll_futex_cmp_requeue_pi(futexp, nr_wake, nr_move, mutex, val, priv) \
|
||||||
|
({ \
|
||||||
|
INTERNAL_SYSCALL_DECL (__err); \
|
||||||
|
long int __ret; \
|
||||||
|
\
|
||||||
|
__ret = INTERNAL_SYSCALL (futex, __err, 6, (futexp), \
|
||||||
|
__lll_private_flag (FUTEX_CMP_REQUEUE_PI, priv),\
|
||||||
|
(nr_wake), (nr_move), (mutex), (val)); \
|
||||||
|
INTERNAL_SYSCALL_ERROR_P (__ret, __err); \
|
||||||
|
})
|
||||||
|
|
||||||
#define lll_compare_and_swap(futex, oldval, newval, operation) \
|
#define lll_compare_and_swap(futex, oldval, newval, operation) \
|
||||||
do { \
|
do { \
|
||||||
__typeof (futex) __futex = (futex); \
|
__typeof (futex) __futex = (futex); \
|
||||||
|
@ -187,6 +187,11 @@
|
|||||||
# define __ASSUME_PWRITEV 1
|
# define __ASSUME_PWRITEV 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Support for FUTEX_*_REQUEUE_PI was added in 2.6.31. */
|
||||||
|
#if __LINUX_KERNEL_VERSION >= 0x02061f
|
||||||
|
# define __ASSUME_REQUEUE_PI 1
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Support for F_GETOWN_EX was introduced in 2.6.32. */
|
/* Support for F_GETOWN_EX was introduced in 2.6.32. */
|
||||||
#if __LINUX_KERNEL_VERSION >= 0x020620
|
#if __LINUX_KERNEL_VERSION >= 0x020620
|
||||||
# define __ASSUME_F_GETOWN_EX 1
|
# define __ASSUME_F_GETOWN_EX 1
|
||||||
|
Reference in New Issue
Block a user