This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Ping[3]: [PATCH][s390][ppc] Add REQUEUE_PI support


Hi,

there is an "INTERNAL_SYSCALL_DECL (__err);" missing in lll_futex_timed_wait_requeue_pi.
It is a NOP on s390 anyway but it probably is supposed to look the same for all archs.

Ok with that change. Thanks!

-Andreas-

On 12/02/13 10:14, Siddhesh Poyarekar wrote:
> Ping!
> 
> On Mon, Feb 04, 2013 at 05:16:26PM +0530, Siddhesh Poyarekar wrote:
>> Ping!
>>
>> On Tue, Jan 08, 2013 at 06:57:02PM +0530, Siddhesh Poyarekar wrote:
>>> Hi,
>>>
>>> Support for priority inheritance in pthread condition variables using
>>> FUTEX_WAIT_REQUEUE_PI and FUTEX_CMP_REQUEUE_PI have been in x86 code
>>> since some time, but the generic code was never updated to make this
>>> available for other architectures.  Attached patch modifies the
>>> generic code to make use of FUTEX_*REQUEUE_PI for condition variables
>>> backed by PI-aware mutexes whenever the underlying architecture
>>> supports it and also adds support for powerpc and s390.  I have
>>> verified that there are no regressions in the testsuite due to this
>>> patch on s390x and ppc64.  Once this goes in, other architectures can
>>> add this support by simply defining lll_futex_wait_requeue_pi,
>>> lll_futex_timed_wait_requeue_pi and lll_futex_cmp_requeue_pi, similar
>>> to the way I have done in s390 and ppc and compiling against a kernel
>>> newer than 2.6.31.  I'll send out a separate email on ports once the
>>> patch is in.
>>>
>>> Siddhesh
>>>
>>> nptl/ChangeLog:
>>>
>>> 	* 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.
>>>
>>> diff --git a/nptl/pthreadP.h b/nptl/pthreadP.h
>>> index 993a79e..d08b219 100644
>>> --- a/nptl/pthreadP.h
>>> +++ b/nptl/pthreadP.h
>>> @@ -577,4 +577,16 @@ extern void __wait_lookup_done (void) attribute_hidden;
>>>  # define PTHREAD_STATIC_FN_REQUIRE(name) __asm (".globl " #name);
>>>  #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 */
>>> diff --git a/nptl/pthread_cond_broadcast.c b/nptl/pthread_cond_broadcast.c
>>> index 968ee03..0702ec0 100644
>>> --- a/nptl/pthread_cond_broadcast.c
>>> +++ b/nptl/pthread_cond_broadcast.c
>>> @@ -53,34 +53,37 @@ __pthread_cond_broadcast (cond)
>>>        /* We are done.  */
>>>        lll_unlock (cond->__data.__lock, pshared);
>>>  
>>> -      /* Do not use requeue for pshared condvars.  */
>>> -      if (cond->__data.__mutex == (void *) ~0l)
>>> -	goto wake_all;
>>> -
>>>        /* Wake everybody.  */
>>>        pthread_mutex_t *mut = (pthread_mutex_t *) cond->__data.__mutex;
>>>  
>>> -      /* XXX: Kernel so far doesn't support requeue to PI futex.  */
>>> -      /* XXX: Kernel so far can only requeue to the same type of futex,
>>> -	 in this case private (we don't requeue for pshared condvars).  */
>>> -      if (__builtin_expect (mut->__data.__kind
>>> -			    & (PTHREAD_MUTEX_PRIO_INHERIT_NP
>>> -			       | PTHREAD_MUTEX_PSHARED_BIT), 0))
>>> +      /* Do not use requeue for pshared condvars.  */
>>> +      if (mut == (void *) ~0l
>>> +	  || PTHREAD_MUTEX_PSHARED (mut) & PTHREAD_MUTEX_PSHARED_BIT)
>>>  	goto wake_all;
>>>  
>>> -      /* 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))
>>> +#if (defined lll_futex_cmp_requeue_pi \
>>> +     && defined __ASSUME_REQUEUE_PI)
>>> +      int pi_flag = PTHREAD_MUTEX_PRIO_INHERIT_NP | PTHREAD_MUTEX_ROBUST_NP;
>>> +      pi_flag &= mut->__data.__kind;
>>> +
>>> +      if (pi_flag == PTHREAD_MUTEX_PRIO_INHERIT_NP)
>>>  	{
>>> -	  /* The requeue functionality is not available.  */
>>> -	wake_all:
>>> -	  lll_futex_wake (&cond->__data.__futex, INT_MAX, pshared);
>>> +	  if (lll_futex_cmp_requeue_pi (&cond->__data.__futex, 1, INT_MAX,
>>> +					&mut->__data.__lock, futex_val,
>>> +					LLL_PRIVATE) == 0)
>>> +	    return 0;
>>>  	}
>>> -
>>> -      /* That's all.  */
>>> -      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.  */
>>> diff --git a/nptl/pthread_cond_signal.c b/nptl/pthread_cond_signal.c
>>> index 908a2ac..102d0b3 100644
>>> --- a/nptl/pthread_cond_signal.c
>>> +++ b/nptl/pthread_cond_signal.c
>>> @@ -47,12 +47,35 @@ __pthread_cond_signal (cond)
>>>        ++cond->__data.__wakeup_seq;
>>>        ++cond->__data.__futex;
>>>  
>>> -      /* Wake one.  */
>>> -      if (! __builtin_expect (lll_futex_wake_unlock (&cond->__data.__futex, 1,
>>> -						     1, &cond->__data.__lock,
>>> -						     pshared), 0))
>>> -	return 0;
>>> +#if (defined lll_futex_cmp_requeue_pi \
>>> +     && defined __ASSUME_REQUEUE_PI)
>>> +      int pi_flag = PTHREAD_MUTEX_PRIO_INHERIT_NP | PTHREAD_MUTEX_ROBUST_NP;
>>> +      pthread_mutex_t *mut = cond->__data.__mutex;
>>>  
>>> +      /* 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);
>>>      }
>>>  
>>> diff --git a/nptl/pthread_cond_timedwait.c b/nptl/pthread_cond_timedwait.c
>>> index 0f52bd8..0a2d092 100644
>>> --- a/nptl/pthread_cond_timedwait.c
>>> +++ b/nptl/pthread_cond_timedwait.c
>>> @@ -64,6 +64,11 @@ __pthread_cond_timedwait (cond, mutex, abstime)
>>>    int pshared = (cond->__data.__mutex == (void *) ~0l)
>>>  		? 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.  */
>>>    lll_lock (cond->__data.__lock, pshared);
>>>  
>>> @@ -155,17 +160,46 @@ __pthread_cond_timedwait (cond, mutex, abstime)
>>>        /* Enable asynchronous cancellation.  Required by the standard.  */
>>>        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 \
>>>       || !defined lll_futex_timed_wait_bitset)
>>> -      /* Wait until woken by signal or broadcast.  */
>>> -      err = lll_futex_timed_wait (&cond->__data.__futex,
>>> -				  futex_val, &rt, pshared);
>>> +	  /* Wait until woken by signal or broadcast.  */
>>> +	  err = lll_futex_timed_wait (&cond->__data.__futex,
>>> +				      futex_val, &rt, pshared);
>>>  #else
>>> -      unsigned int clockbit = (cond->__data.__nwaiters & 1
>>> -			       ? 0 : FUTEX_CLOCK_REALTIME);
>>> -      err = lll_futex_timed_wait_bitset (&cond->__data.__futex, futex_val,
>>> -					 abstime, clockbit, pshared);
>>> +	  unsigned int clockbit = (cond->__data.__nwaiters & 1
>>> +				   ? 0 : FUTEX_CLOCK_REALTIME);
>>> +	  err = lll_futex_timed_wait_bitset (&cond->__data.__futex, futex_val,
>>> +					     abstime, clockbit, pshared);
>>>  #endif
>>> +	}
>>>  
>>>        /* Disable asynchronous cancellation.  */
>>>        __pthread_disable_asynccancel (cbuffer.oldtype);
>>> @@ -217,7 +251,16 @@ __pthread_cond_timedwait (cond, mutex, abstime)
>>>    __pthread_cleanup_pop (&buffer, 0);
>>>  
>>>    /* 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;
>>>  }
>>> diff --git a/nptl/pthread_cond_wait.c b/nptl/pthread_cond_wait.c
>>> index 0ae320c..01d42d7 100644
>>> --- a/nptl/pthread_cond_wait.c
>>> +++ b/nptl/pthread_cond_wait.c
>>> @@ -26,7 +26,6 @@
>>>  #include <shlib-compat.h>
>>>  #include <stap-probe.h>
>>>  
>>> -
>>>  struct _condvar_cleanup_buffer
>>>  {
>>>    int oldtype;
>>> @@ -85,8 +84,15 @@ __condvar_cleanup (void *arg)
>>>      lll_futex_wake (&cbuffer->cond->__data.__futex, INT_MAX, pshared);
>>>  
>>>    /* Get the mutex before returning unless asynchronous cancellation
>>> -     is in effect.  */
>>> -  __pthread_mutex_cond_lock (cbuffer->mutex);
>>> +     is in effect.  We don't try to get the mutex if we already own it.  */
>>> +  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)
>>>  		? 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);
>>>  
>>>    /* Make sure we are alone.  */
>>> @@ -144,15 +155,36 @@ __pthread_cond_wait (cond, mutex)
>>>    do
>>>      {
>>>        unsigned int futex_val = cond->__data.__futex;
>>> -
>>>        /* Prepare to wait.  Release the condvar futex.  */
>>>        lll_unlock (cond->__data.__lock, pshared);
>>>  
>>>        /* Enable asynchronous cancellation.  Required by the standard.  */
>>>        cbuffer.oldtype = __pthread_enable_asynccancel ();
>>>  
>>> -      /* Wait until woken by signal or broadcast.  */
>>> -      lll_futex_wait (&cond->__data.__futex, futex_val, pshared);
>>> +#if (defined lll_futex_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)
>>> +	{
>>> +	  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.  */
>>>        __pthread_disable_asynccancel (cbuffer.oldtype);
>>> @@ -189,8 +221,17 @@ __pthread_cond_wait (cond, mutex)
>>>    /* The cancellation handling is back to normal, remove the handler.  */
>>>    __pthread_cleanup_pop (&buffer, 0);
>>>  
>>> -  /* Get the mutex before returning.  */
>>> -  return __pthread_mutex_cond_lock (mutex);
>>> +  /* Get the mutex before returning.  Not needed for PI.  */
>>> +#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,
>>> diff --git a/nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h b/nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h
>>> index b4b1fd4..f33f703 100644
>>> --- a/nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h
>>> +++ b/nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h
>>> @@ -39,6 +39,8 @@
>>>  #define FUTEX_TRYLOCK_PI	8
>>>  #define FUTEX_WAIT_BITSET	9
>>>  #define FUTEX_WAKE_BITSET	10
>>> +#define FUTEX_WAIT_REQUEUE_PI   11
>>> +#define FUTEX_CMP_REQUEUE_PI    12
>>>  #define FUTEX_PRIVATE_FLAG	128
>>>  #define FUTEX_CLOCK_REALTIME	256
>>>  
>>> @@ -149,6 +151,34 @@
>>>      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
>>>  # define __lll_acq_instr	""
>>> diff --git a/nptl/sysdeps/unix/sysv/linux/s390/lowlevellock.h b/nptl/sysdeps/unix/sysv/linux/s390/lowlevellock.h
>>> index a0163d6..9f7391b 100644
>>> --- a/nptl/sysdeps/unix/sysv/linux/s390/lowlevellock.h
>>> +++ b/nptl/sysdeps/unix/sysv/linux/s390/lowlevellock.h
>>> @@ -37,6 +37,8 @@
>>>  #define FUTEX_TRYLOCK_PI	8
>>>  #define FUTEX_WAIT_BITSET	9
>>>  #define FUTEX_WAKE_BITSET	10
>>> +#define FUTEX_WAIT_REQUEUE_PI   11
>>> +#define FUTEX_CMP_REQUEUE_PI    12
>>>  #define FUTEX_PRIVATE_FLAG	128
>>>  #define FUTEX_CLOCK_REALTIME	256
>>>  
>>> @@ -141,6 +143,31 @@
>>>      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)			      \
>>> +  ({									      \
>>> +    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) \
>>>    do {									      \
>>>      __typeof (futex) __futex = (futex);					      \
>>> diff --git a/sysdeps/unix/sysv/linux/kernel-features.h b/sysdeps/unix/sysv/linux/kernel-features.h
>>> index 21eef43..8fdff7e 100644
>>> --- a/sysdeps/unix/sysv/linux/kernel-features.h
>>> +++ b/sysdeps/unix/sysv/linux/kernel-features.h
>>> @@ -187,6 +187,11 @@
>>>  # define __ASSUME_PWRITEV	1
>>>  #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.  */
>>>  #if __LINUX_KERNEL_VERSION >= 0x020620
>>>  # define __ASSUME_F_GETOWN_EX	1
> 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]