View | Details | Raw Unified | Return to bug 11588 | Differences between
and this patch

Collapse All | Expand All

(-)a/Versions.def (+1 lines)
Lines 92-97 libpthread { Link Here
92
  GLIBC_2.6
92
  GLIBC_2.6
93
  GLIBC_2.11
93
  GLIBC_2.11
94
  GLIBC_2.12
94
  GLIBC_2.12
95
  GLIBC_2.13
95
  GLIBC_PRIVATE
96
  GLIBC_PRIVATE
96
}
97
}
97
libresolv {
98
libresolv {
(-)a/nptl/Makefile (+1 lines)
Lines 75-80 libpthread-routines = nptl-init vars events version \ Link Here
75
		      old_pthread_cond_signal old_pthread_cond_broadcast \
75
		      old_pthread_cond_signal old_pthread_cond_broadcast \
76
		      pthread_condattr_init pthread_condattr_destroy \
76
		      pthread_condattr_init pthread_condattr_destroy \
77
		      pthread_condattr_getpshared pthread_condattr_setpshared \
77
		      pthread_condattr_getpshared pthread_condattr_setpshared \
78
		      pthread_condattr_getprotocol_np pthread_condattr_setprotocol_np \
78
		      pthread_condattr_getclock pthread_condattr_setclock \
79
		      pthread_condattr_getclock pthread_condattr_setclock \
79
		      pthread_spin_init pthread_spin_destroy \
80
		      pthread_spin_init pthread_spin_destroy \
80
		      pthread_spin_lock pthread_spin_trylock \
81
		      pthread_spin_lock pthread_spin_trylock \
(-)a/nptl/Versions (+4 lines)
Lines 251-256 libpthread { Link Here
251
    pthread_setname_np; pthread_getname_np;
251
    pthread_setname_np; pthread_getname_np;
252
  };
252
  };
253
253
254
  GLIBC_2.13 {
255
    pthread_condattr_getprotocol_np; pthread_condattr_setprotocol_np;
256
  }
257
254
  GLIBC_PRIVATE {
258
  GLIBC_PRIVATE {
255
    __pthread_initialize_minimal;
259
    __pthread_initialize_minimal;
256
    __pthread_clock_gettime; __pthread_clock_settime;
260
    __pthread_clock_gettime; __pthread_clock_settime;
(-)a/nptl/pthread_cond_broadcast.c (-22 / +37 lines)
Lines 1-4 Link Here
1
/* Copyright (C) 2003, 2004, 2006, 2007 Free Software Foundation, Inc.
1
/* Copyright (C) 2003, 2004, 2006, 2007, 2010 Free Software Foundation, Inc.
2
   This file is part of the GNU C Library.
2
   This file is part of the GNU C Library.
3
   Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>, 2003.
3
   Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>, 2003.
4
4
Lines 27-32 Link Here
27
#include <shlib-compat.h>
27
#include <shlib-compat.h>
28
#include <kernel-features.h>
28
#include <kernel-features.h>
29
29
30
#include "cond-lock.h"
31
 
30
32
31
int
33
int
32
__pthread_cond_broadcast (cond)
34
__pthread_cond_broadcast (cond)
Lines 34-41 __pthread_cond_broadcast (cond) Link Here
34
{
36
{
35
  int pshared = (cond->__data.__mutex == (void *) ~0l)
37
  int pshared = (cond->__data.__mutex == (void *) ~0l)
36
		? LLL_SHARED : LLL_PRIVATE;
38
		? LLL_SHARED : LLL_PRIVATE;
39
37
  /* Make sure we are alone.  */
40
  /* Make sure we are alone.  */
38
  lll_lock (cond->__data.__lock, pshared);
41
  cond_lock(cond, pshared);
39
42
40
  /* Are there any waiters to be woken?  */
43
  /* Are there any waiters to be woken?  */
41
  if (cond->__data.__total_seq > cond->__data.__wakeup_seq)
44
  if (cond->__data.__total_seq > cond->__data.__wakeup_seq)
Lines 45-80 __pthread_cond_broadcast (cond) Link Here
45
      cond->__data.__woken_seq = cond->__data.__total_seq;
48
      cond->__data.__woken_seq = cond->__data.__total_seq;
46
      cond->__data.__futex = (unsigned int) cond->__data.__total_seq * 2;
49
      cond->__data.__futex = (unsigned int) cond->__data.__total_seq * 2;
47
      int futex_val = cond->__data.__futex;
50
      int futex_val = cond->__data.__futex;
51
      pthread_mutex_t *mut = (pthread_mutex_t *) cond->__data.__mutex;
52
      int err;
48
      /* Signal that a broadcast happened.  */
53
      /* Signal that a broadcast happened.  */
49
      ++cond->__data.__broadcast_seq;
54
      ++cond->__data.__broadcast_seq;
50
55
51
      /* We are done.  */
56
      /* We are done.  */
52
      lll_unlock (cond->__data.__lock, pshared);
57
      cond_unlock(cond, pshared);
53
58
54
      /* Do not use requeue for pshared condvars.  */
59
      /* Do not use requeue for pshared condvars.  */
55
      if (cond->__data.__mutex == (void *) ~0l)
60
      if (cond->__data.__mutex == (void *) ~0l)
56
	goto wake_all;
61
	goto wake_all;
57
62
58
      /* Wake everybody.  */
63
      /* We don't requeue for pshared condvars  */
59
      pthread_mutex_t *mut = (pthread_mutex_t *) cond->__data.__mutex;
60
61
      /* XXX: Kernel so far doesn't support requeue to PI futex.  */
62
      /* XXX: Kernel so far can only requeue to the same type of futex,
63
	 in this case private (we don't requeue for pshared condvars).  */
64
      if (__builtin_expect (mut->__data.__kind
64
      if (__builtin_expect (mut->__data.__kind
65
			    & (PTHREAD_MUTEX_PRIO_INHERIT_NP
65
			    & PTHREAD_MUTEX_PSHARED_BIT, 0))
66
			       | PTHREAD_MUTEX_PSHARED_BIT), 0))
66
 	goto wake_all;
67
	goto wake_all;
67
 
68
68
      if (__builtin_expect (mut->__data.__kind
69
      /* lll_futex_requeue returns 0 for success and non-zero
69
 			    & PTHREAD_MUTEX_PRIO_INHERIT_NP, 0))
70
	 for errors.  */
70
	{
71
      if (__builtin_expect (lll_futex_requeue (&cond->__data.__futex, 1,
71
	 /* lll_futex_requeue_pi returns the number of tasks requeue'd on
72
					       INT_MAX, &mut->__data.__lock,
72
	    success and negative for errors.  */
73
					       futex_val, LLL_PRIVATE), 0))
73
         err = lll_futex_requeue_pi (&cond->__data.__futex, 1, INT_MAX, 
74
				     &mut->__data.__lock, futex_val,
75
				     LLL_PRIVATE);
76
	 /* The requeue_pi functionality is not available.  */
77
	 if (__builtin_expect (err == -ENOSYS, 0))
78
	   goto wake_all;
79
	}
80
      else
74
	{
81
	{
75
	  /* The requeue functionality is not available.  */
82
	 /* lll_futex_requeue_pi returns the number of tasks requeue'd on
76
	wake_all:
83
	    success and negative for errors.  */
77
	  lll_futex_wake (&cond->__data.__futex, INT_MAX, pshared);
84
	 err = lll_futex_requeue (&cond->__data.__futex, 1, INT_MAX,
85
				  &mut->__data.__lock, futex_val,
86
				  LLL_PRIVATE);
87
	 if (__builtin_expect (err == -ENOSYS, 0))
88
	   {
89
	    /* The requeue functionality is not available.  */
90
	   wake_all:
91
	    lll_futex_wake (&cond->__data.__futex, INT_MAX, pshared);
92
	   }
78
	}
93
	}
79
94
80
      /* That's all.  */
95
      /* That's all.  */
Lines 82-88 __pthread_cond_broadcast (cond) Link Here
82
    }
97
    }
83
98
84
  /* We are done.  */
99
  /* We are done.  */
85
  lll_unlock (cond->__data.__lock, pshared);
100
  cond_unlock(cond, pshared);
86
101
87
  return 0;
102
  return 0;
88
}
103
}
(-)a/nptl/pthread_cond_init.c (-3 / +20 lines)
Lines 1-4 Link Here
1
/* Copyright (C) 2002, 2003, 2004, 2005, 2007, 2008
1
/* Copyright (C) 2002, 2003, 2004, 2005, 2007, 2008, 2010
2
   Free Software Foundation, Inc.
2
   Free Software Foundation, Inc.
3
   This file is part of the GNU C Library.
3
   This file is part of the GNU C Library.
4
   Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
4
   Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
Lines 32-40 __pthread_cond_init (cond, cond_attr) Link Here
32
  cond->__data.__lock = LLL_LOCK_INITIALIZER;
32
  cond->__data.__lock = LLL_LOCK_INITIALIZER;
33
  cond->__data.__futex = 0;
33
  cond->__data.__futex = 0;
34
  cond->__data.__nwaiters = (icond_attr != NULL
34
  cond->__data.__nwaiters = (icond_attr != NULL
35
			     ? ((icond_attr->value >> 1)
35
			     ? ((icond_attr->value >> CONDATTR_CLOCKID_SHIFT)
36
				& ((1 << COND_NWAITERS_SHIFT) - 1))
36
				& ((1 << COND_PROTOCOL_SHIFT) - 1))
37
			     : CLOCK_REALTIME);
37
			     : CLOCK_REALTIME);
38
  if (icond_attr != NULL)
39
   {
40
    switch (icond_attr->value & CONDATTR_PROTOCOL_MASK)
41
     {
42
     case PTHREAD_PRIO_INHERIT << CONDATTR_PROTOCOL_SHIFT:
43
       cond->__data.__nwaiters |= COND_PRIO_INHERIT;
44
       break;
45
46
     case PTHREAD_PRIO_PROTECT << CONDATTR_PROTOCOL_SHIFT:
47
       cond->__data.__nwaiters |= COND_PRIO_PROTECT;
48
       break;
49
50
     default:
51
       break;
52
     }
53
   }
54
38
  cond->__data.__total_seq = 0;
55
  cond->__data.__total_seq = 0;
39
  cond->__data.__wakeup_seq = 0;
56
  cond->__data.__wakeup_seq = 0;
40
  cond->__data.__woken_seq = 0;
57
  cond->__data.__woken_seq = 0;
(-)a/nptl/pthread_cond_signal.c (-7 / +30 lines)
Lines 27-42 Link Here
27
#include <shlib-compat.h>
27
#include <shlib-compat.h>
28
#include <kernel-features.h>
28
#include <kernel-features.h>
29
29
30
#include "cond-lock.h"
31
30
32
31
int
33
int
32
__pthread_cond_signal (cond)
34
__pthread_cond_signal (cond)
33
     pthread_cond_t *cond;
35
     pthread_cond_t *cond;
34
{
36
{
35
  int pshared = (cond->__data.__mutex == (void *) ~0l)
37
  int err, futex_val;
36
		? LLL_SHARED : LLL_PRIVATE;
38
  pthread_mutex_t *mutex = (pthread_mutex_t *) cond->__data.__mutex;
39
  int pshared = (mutex == (void *) ~0l) ? LLL_SHARED : LLL_PRIVATE;
37
40
38
  /* Make sure we are alone.  */
41
  /* Make sure we are alone.  */
39
  lll_lock (cond->__data.__lock, pshared);
42
  cond_lock(cond, pshared);
40
43
41
  /* Are there any waiters to be woken?  */
44
  /* Are there any waiters to be woken?  */
42
  if (cond->__data.__total_seq > cond->__data.__wakeup_seq)
45
  if (cond->__data.__total_seq > cond->__data.__wakeup_seq)
Lines 44-61 __pthread_cond_signal (cond) Link Here
44
      /* Yes.  Mark one of them as woken.  */
47
      /* Yes.  Mark one of them as woken.  */
45
      ++cond->__data.__wakeup_seq;
48
      ++cond->__data.__wakeup_seq;
46
      ++cond->__data.__futex;
49
      ++cond->__data.__futex;
50
      futex_val = cond->__data.__futex;
51
      pthread_mutex_t *mut = (pthread_mutex_t *) cond->__data.__mutex;
47
52
53
      /* We dont do requeue-pi for pshared mutexes */
54
      if (pshared == LLL_PRIVATE &&
55
	  mut->__data.__kind & PTHREAD_MUTEX_PRIO_INHERIT_NP)
56
        {
57
	 /* lll_futex_requeue_pi returns the number of tasks requeue'd on
58
	    success and negative for errors.  */
59
         err = lll_futex_requeue_pi (&cond->__data.__futex, 1, 0, 
60
				     &mut->__data.__lock, futex_val,
61
				     pshared);
62
	 /* The requeue_pi functionality is not available.  */
63
	 if (__builtin_expect (err != -ENOSYS, 0))
64
           goto done;
65
        }
66
#if 0
67
      /* This is not needed for the x86_64 or i686 arches */
48
      /* Wake one.  */
68
      /* Wake one.  */
49
      if (! __builtin_expect (lll_futex_wake_unlock (&cond->__data.__futex, 1,
69
      else if (! __builtin_expect (lll_futex_wake_unlock (&cond->__data.__futex,
50
						     1, &cond->__data.__lock,
70
							  1, 1,
51
						     pshared), 0))
71
							  &cond->__data.__lock,
72
						          pshared), 0))
52
	return 0;
73
	return 0;
74
#endif
53
75
54
      lll_futex_wake (&cond->__data.__futex, 1, pshared);
76
      lll_futex_wake (&cond->__data.__futex, 1, pshared);
55
    }
77
    }
56
78
79
done:
57
  /* We are done.  */
80
  /* We are done.  */
58
  lll_unlock (cond->__data.__lock, pshared);
81
  cond_unlock(cond, pshared);
59
82
60
  return 0;
83
  return 0;
61
}
84
}
(-)a/nptl/pthread_cond_timedwait.c (-9 / +31 lines)
Lines 27-32 Link Here
27
27
28
#include <shlib-compat.h>
28
#include <shlib-compat.h>
29
29
30
#include "cond-lock.h"
31
30
#ifndef HAVE_CLOCK_GETTIME_VSYSCALL
32
#ifndef HAVE_CLOCK_GETTIME_VSYSCALL
31
# undef INTERNAL_VSYSCALL
33
# undef INTERNAL_VSYSCALL
32
# define INTERNAL_VSYSCALL INTERNAL_SYSCALL
34
# define INTERNAL_VSYSCALL INTERNAL_SYSCALL
Lines 57-62 __pthread_cond_timedwait (cond, mutex, abstime) Link Here
57
  struct _pthread_cleanup_buffer buffer;
59
  struct _pthread_cleanup_buffer buffer;
58
  struct _condvar_cleanup_buffer cbuffer;
60
  struct _condvar_cleanup_buffer cbuffer;
59
  int result = 0;
61
  int result = 0;
62
  int pi_requeued;
60
63
61
  /* Catch invalid parameters.  */
64
  /* Catch invalid parameters.  */
62
  if (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)
65
  if (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)
Lines 65-78 __pthread_cond_timedwait (cond, mutex, abstime) Link Here
65
  int pshared = (cond->__data.__mutex == (void *) ~0l)
68
  int pshared = (cond->__data.__mutex == (void *) ~0l)
66
		? LLL_SHARED : LLL_PRIVATE;
69
		? LLL_SHARED : LLL_PRIVATE;
67
70
68
  /* Make sure we are along.  */
71
  /* Make sure we are alone.  */
69
  lll_lock (cond->__data.__lock, pshared);
72
  cond_lock(cond, pshared);
70
73
71
  /* Now we can release the mutex.  */
74
  /* Now we can release the mutex.  */
72
  int err = __pthread_mutex_unlock_usercnt (mutex, 0);
75
  int err = __pthread_mutex_unlock_usercnt (mutex, 0);
73
  if (err)
76
  if (err)
74
    {
77
    {
75
      lll_unlock (cond->__data.__lock, pshared);
78
      cond_unlock(cond, pshared);
76
      return err;
79
      return err;
77
    }
80
    }
78
81
Lines 105-110 __pthread_cond_timedwait (cond, mutex, abstime) Link Here
105
108
106
  while (1)
109
  while (1)
107
    {
110
    {
111
      pi_requeued = 0;
108
      struct timespec rt;
112
      struct timespec rt;
109
      {
113
      {
110
#ifdef __NR_clock_gettime
114
#ifdef __NR_clock_gettime
Lines 112-118 __pthread_cond_timedwait (cond, mutex, abstime) Link Here
112
	int ret;
116
	int ret;
113
	ret = INTERNAL_VSYSCALL (clock_gettime, err, 2,
117
	ret = INTERNAL_VSYSCALL (clock_gettime, err, 2,
114
				(cond->__data.__nwaiters
118
				(cond->__data.__nwaiters
115
				 & ((1 << COND_NWAITERS_SHIFT) - 1)),
119
				 & ((1 << COND_PROTOCOL_SHIFT) - 1)),
116
				&rt);
120
				&rt);
117
# ifndef __ASSUME_POSIX_TIMERS
121
# ifndef __ASSUME_POSIX_TIMERS
118
	if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (ret, err), 0))
122
	if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (ret, err), 0))
Lines 158-177 __pthread_cond_timedwait (cond, mutex, abstime) Link Here
158
      unsigned int futex_val = cond->__data.__futex;
162
      unsigned int futex_val = cond->__data.__futex;
159
163
160
      /* Prepare to wait.  Release the condvar futex.  */
164
      /* Prepare to wait.  Release the condvar futex.  */
161
      lll_unlock (cond->__data.__lock, pshared);
165
      cond_unlock(cond, pshared);
162
166
163
      /* Enable asynchronous cancellation.  Required by the standard.  */
167
      /* Enable asynchronous cancellation.  Required by the standard.  */
164
      cbuffer.oldtype = __pthread_enable_asynccancel ();
168
      cbuffer.oldtype = __pthread_enable_asynccancel ();
165
169
170
      if (mutex->__data.__kind & PTHREAD_MUTEX_PRIO_INHERIT_NP)
171
        {
172
	  /* Try requeueing to the PI mutex, if no support in the kernel
173
	     try the non-requeue syscall.  */
174
          err = lll_futex_timed_wait_requeue_pi (cond, futex_val, abstime,
175
						 &mutex->__data.__lock,
176
						 pshared);
177
          if (__builtin_expect (!err, 1))
178
	       pi_requeued = 1;
179
          if (__builtin_expect (err != -ENOSYS, 0))
180
	       goto woken;
181
	}
182
166
      /* Wait until woken by signal or broadcast.  */
183
      /* Wait until woken by signal or broadcast.  */
167
      err = lll_futex_timed_wait (&cond->__data.__futex,
184
      err = lll_futex_timed_wait (&cond->__data.__futex,
168
				  futex_val, &rt, pshared);
185
				  futex_val, &rt, pshared);
169
186
187
woken:
170
      /* Disable asynchronous cancellation.  */
188
      /* Disable asynchronous cancellation.  */
171
      __pthread_disable_asynccancel (cbuffer.oldtype);
189
      __pthread_disable_asynccancel (cbuffer.oldtype);
172
190
173
      /* We are going to look at shared data again, so get the lock.  */
191
      /* We are going to look at shared data again, so get the lock.  */
174
      lll_lock (cond->__data.__lock, pshared);
192
      cond_lock(cond, pshared);
175
193
176
      /* If a broadcast happened, we are done.  */
194
      /* If a broadcast happened, we are done.  */
177
      if (cbuffer.bc_seq != cond->__data.__broadcast_seq)
195
      if (cbuffer.bc_seq != cond->__data.__broadcast_seq)
Lines 211-223 __pthread_cond_timedwait (cond, mutex, abstime) Link Here
211
    lll_futex_wake (&cond->__data.__nwaiters, 1, pshared);
229
    lll_futex_wake (&cond->__data.__nwaiters, 1, pshared);
212
230
213
  /* We are done with the condvar.  */
231
  /* We are done with the condvar.  */
214
  lll_unlock (cond->__data.__lock, pshared);
232
  cond_unlock(cond, pshared);
215
233
216
  /* The cancellation handling is back to normal, remove the handler.  */
234
  /* The cancellation handling is back to normal, remove the handler.  */
217
  __pthread_cleanup_pop (&buffer, 0);
235
  __pthread_cleanup_pop (&buffer, 0);
218
236
219
  /* Get the mutex before returning.  */
237
  /* Get the mutex before returning. If the requeue_pi call above was successful,
220
  err = __pthread_mutex_cond_lock (mutex);
238
     the lock is already held in the kernel, so just return to the application.  */
239
  if (pi_requeued)
240
    __pthread_mutex_cond_lock_adjust (mutex);
241
  else
242
    err = __pthread_mutex_cond_lock (mutex);
221
243
222
  return err ?: result;
244
  return err ?: result;
223
}
245
}
(-)a/nptl/pthread_cond_wait.c (-12 / +77 lines)
Lines 17-31 Link Here
17
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
17
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18
   02111-1307 USA.  */
18
   02111-1307 USA.  */
19
19
20
#include <assert.h>
20
#include <endian.h>
21
#include <endian.h>
21
#include <errno.h>
22
#include <errno.h>
22
#include <sysdep.h>
23
#include <sysdep.h>
23
#include <lowlevellock.h>
24
#include <lowlevellock.h>
25
#include <not-cancel.h>
24
#include <pthread.h>
26
#include <pthread.h>
25
#include <pthreadP.h>
27
#include <pthreadP.h>
26
28
27
#include <shlib-compat.h>
29
#include <shlib-compat.h>
28
30
31
#include "cond-lock.h"
32
 
29
33
30
struct _condvar_cleanup_buffer
34
struct _condvar_cleanup_buffer
31
{
35
{
Lines 38-53 struct _condvar_cleanup_buffer Link Here
38
42
39
void
43
void
40
__attribute__ ((visibility ("hidden")))
44
__attribute__ ((visibility ("hidden")))
45
lll_pi_lock(int *futexp, int private)
46
{
47
  pid_t id = THREAD_GETMEM (THREAD_SELF, tid);
48
  int newval = id;
49
  int ret;
50
51
  newval |= FUTEX_WAITERS; 
52
  ret = atomic_compare_and_exchange_val_acq (futexp, newval, 0);
53
54
  if (ret != 0)
55
    {
56
      /* The mutex is locked.  The kernel will now take care of
57
	 everything.  */
58
      INTERNAL_SYSCALL_DECL (__err);
59
      int e = INTERNAL_SYSCALL (futex, __err, 4, futexp,
60
				__lll_private_flag (FUTEX_LOCK_PI, private),
61
				1, 0);
62
    }
63
}
64
65
66
void
67
__attribute__ ((visibility ("hidden")))
68
lll_pi_unlock(int *futexp, int private)
69
{
70
71
  if ((*futexp & FUTEX_WAITERS) != 0
72
      || atomic_compare_and_exchange_bool_acq (futexp, 0,
73
					       THREAD_GETMEM (THREAD_SELF,
74
							      tid)))
75
    {
76
      INTERNAL_SYSCALL_DECL (__err);
77
      INTERNAL_SYSCALL (futex, __err, 2, futexp,
78
			__lll_private_flag (FUTEX_UNLOCK_PI, private));
79
    }
80
}
81
82
 
83
void
84
__attribute__ ((visibility ("hidden")))
41
__condvar_cleanup (void *arg)
85
__condvar_cleanup (void *arg)
42
{
86
{
43
  struct _condvar_cleanup_buffer *cbuffer =
87
  struct _condvar_cleanup_buffer *cbuffer =
44
    (struct _condvar_cleanup_buffer *) arg;
88
    (struct _condvar_cleanup_buffer *) arg;
45
  unsigned int destroying;
89
  unsigned int destroying;
46
  int pshared = (cbuffer->cond->__data.__mutex == (void *) ~0l)
90
  int pshared = (cbuffer->mutex == (void *) ~0l) ? LLL_SHARED : LLL_PRIVATE;
47
  		? LLL_SHARED : LLL_PRIVATE;
48
91
49
  /* We are going to modify shared data.  */
92
  /* We are going to modify shared data.  */
50
  lll_lock (cbuffer->cond->__data.__lock, pshared);
93
  cond_lock(cbuffer->cond, pshared);
51
94
52
  if (cbuffer->bc_seq == cbuffer->cond->__data.__broadcast_seq)
95
  if (cbuffer->bc_seq == cbuffer->cond->__data.__broadcast_seq)
53
    {
96
    {
Lines 78-84 __condvar_cleanup (void *arg) Link Here
78
    }
121
    }
79
122
80
  /* We are done.  */
123
  /* We are done.  */
81
  lll_unlock (cbuffer->cond->__data.__lock, pshared);
124
  cond_unlock(cbuffer->cond, pshared);
82
125
83
  /* Wake everybody to make sure no condvar signal gets lost.  */
126
  /* Wake everybody to make sure no condvar signal gets lost.  */
84
  if (! destroying)
127
  if (! destroying)
Lines 97-114 __pthread_cond_wait (cond, mutex) Link Here
97
{
140
{
98
  struct _pthread_cleanup_buffer buffer;
141
  struct _pthread_cleanup_buffer buffer;
99
  struct _condvar_cleanup_buffer cbuffer;
142
  struct _condvar_cleanup_buffer cbuffer;
100
  int err;
101
  int pshared = (cond->__data.__mutex == (void *) ~0l)
143
  int pshared = (cond->__data.__mutex == (void *) ~0l)
102
  		? LLL_SHARED : LLL_PRIVATE;
144
  		? LLL_SHARED : LLL_PRIVATE;
145
  int pi_requeued;
146
  int err;
103
147
104
  /* Make sure we are along.  */
148
  /* Make sure we are along.  */
105
  lll_lock (cond->__data.__lock, pshared);
149
  cond_lock(cond, pshared);
106
150
107
  /* Now we can release the mutex.  */
151
  /* Now we can release the mutex.  */
108
  err = __pthread_mutex_unlock_usercnt (mutex, 0);
152
  err = __pthread_mutex_unlock_usercnt (mutex, 0);
109
  if (__builtin_expect (err, 0))
153
  if (__builtin_expect (err, 0))
110
    {
154
    {
111
      lll_unlock (cond->__data.__lock, pshared);
155
      cond_unlock(cond, pshared);
112
      return err;
156
      return err;
113
    }
157
    }
114
158
Lines 142-162 __pthread_cond_wait (cond, mutex) Link Here
142
  do
186
  do
143
    {
187
    {
144
      unsigned int futex_val = cond->__data.__futex;
188
      unsigned int futex_val = cond->__data.__futex;
189
      pi_requeued = 0;
145
190
146
      /* Prepare to wait.  Release the condvar futex.  */
191
      /* Prepare to wait.  Release the condvar futex.  */
147
      lll_unlock (cond->__data.__lock, pshared);
192
      cond_unlock(cond, pshared);
148
193
149
      /* Enable asynchronous cancellation.  Required by the standard.  */
194
      /* Enable asynchronous cancellation.  Required by the standard.  */
150
      cbuffer.oldtype = __pthread_enable_asynccancel ();
195
      cbuffer.oldtype = __pthread_enable_asynccancel ();
151
196
197
      if (mutex->__data.__kind & PTHREAD_MUTEX_PRIO_INHERIT_NP)
198
	{
199
	  /* Try requeueing to the PI mutex, if no support in the kernel
200
             try the non-requeue syscall.  */
201
          err = lll_futex_wait_requeue_pi (cond, futex_val, 
202
					   &mutex->__data.__lock, pshared);
203
          if (__builtin_expect (!err, 1))
204
	       pi_requeued = 1;
205
          if (__builtin_expect (err != -ENOSYS, 0))
206
	       goto woken;
207
	}
208
          
152
      /* Wait until woken by signal or broadcast.  */
209
      /* Wait until woken by signal or broadcast.  */
153
      lll_futex_wait (&cond->__data.__futex, futex_val, pshared);
210
      lll_futex_wait (&cond->__data.__futex, futex_val, pshared);
154
211
212
woken:
155
      /* Disable asynchronous cancellation.  */
213
      /* Disable asynchronous cancellation.  */
156
      __pthread_disable_asynccancel (cbuffer.oldtype);
214
      __pthread_disable_asynccancel (cbuffer.oldtype);
157
215
158
      /* We are going to look at shared data again, so get the lock.  */
216
      /* We are going to look at shared data again, so get the lock.  */
159
      lll_lock (cond->__data.__lock, pshared);
217
      cond_lock(cond, pshared);
160
218
161
      /* If a broadcast happened, we are done.  */
219
      /* If a broadcast happened, we are done.  */
162
      if (cbuffer.bc_seq != cond->__data.__broadcast_seq)
220
      if (cbuffer.bc_seq != cond->__data.__broadcast_seq)
Lines 182-194 __pthread_cond_wait (cond, mutex) Link Here
182
    lll_futex_wake (&cond->__data.__nwaiters, 1, pshared);
240
    lll_futex_wake (&cond->__data.__nwaiters, 1, pshared);
183
241
184
  /* We are done with the condvar.  */
242
  /* We are done with the condvar.  */
185
  lll_unlock (cond->__data.__lock, pshared);
243
  cond_unlock(cond, pshared);
186
244
187
  /* The cancellation handling is back to normal, remove the handler.  */
245
  /* The cancellation handling is back to normal, remove the handler.  */
188
  __pthread_cleanup_pop (&buffer, 0);
246
  __pthread_cleanup_pop (&buffer, 0);
189
247
190
  /* Get the mutex before returning.  */
248
  /* Get the mutex before returning. If the requeue_pi call above was successful,
191
  return __pthread_mutex_cond_lock (mutex);
249
     the lock is already held in the kernel, so just return 0 to application.  */
250
  if (pi_requeued)
251
    {
252
      __pthread_mutex_cond_lock_adjust (mutex);
253
      return 0;
254
    }
255
  else
256
    return __pthread_mutex_cond_lock (mutex);
192
}
257
}
193
258
194
versioned_symbol (libpthread, __pthread_cond_wait, pthread_cond_wait,
259
versioned_symbol (libpthread, __pthread_cond_wait, pthread_cond_wait,
(-)a/nptl/pthread_condattr_getclock.c (-3 / +4 lines)
Lines 1-4 Link Here
1
/* Copyright (C) 2003, 2004, 2007 Free Software Foundation, Inc.
1
/* Copyright (C) 2003,2004,2007,2010 Free Software Foundation, Inc.
2
   This file is part of the GNU C Library.
2
   This file is part of the GNU C Library.
3
   Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
3
   Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
4
4
Lines 25-31 pthread_condattr_getclock (attr, clock_id) Link Here
25
     const pthread_condattr_t *attr;
25
     const pthread_condattr_t *attr;
26
     clockid_t *clock_id;
26
     clockid_t *clock_id;
27
{
27
{
28
  *clock_id = (((((const struct pthread_condattr *) attr)->value) >> 1)
28
  *clock_id = (((((const struct pthread_condattr *) attr)->value)
29
	       & ((1 << COND_NWAITERS_SHIFT) - 1));
29
	       >> CONDATTR_CLOCKID_SHIFT)
30
	       & ((1 << COND_PROTOCOL_SHIFT) - 1));
30
  return 0;
31
  return 0;
31
}
32
}
(-)a/nptl/pthread_condattr_getprotocol_np.c (+34 lines)
Line 0 Link Here
1
/* Copyright (C) 2010 Free Software Foundation, Inc.
2
   This file is part of the GNU C Library.
3
   Contributed by Dinakar Guniguntala <dino@in.ibm.com>, 2010.
4
5
   The GNU C Library is free software; you can redistribute it and/or
6
   modify it under the terms of the GNU Lesser General Public
7
   License as published by the Free Software Foundation; either
8
   version 2.1 of the License, or (at your option) any later version.
9
10
   The GNU C Library is distributed in the hope that it will be useful,
11
   but WITHOUT ANY WARRANTY; without even the implied warranty of
12
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13
   Lesser General Public License for more details.
14
15
   You should have received a copy of the GNU Lesser General Public
16
   License along with the GNU C Library; if not, write to the Free
17
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18
   02111-1307 USA.  */
19
20
#include "pthreadP.h"
21
22
23
int
24
pthread_condattr_getprotocol_np (attr, protocol)
25
     const pthread_condattr_t *attr;
26
     int *protocol;
27
{
28
  *protocol = ((const struct pthread_condattr *) attr)->value;
29
30
  *protocol = ((*protocol & CONDATTR_PROTOCOL_MASK)
31
	       >> CONDATTR_PROTOCOL_SHIFT);
32
33
  return 0;
34
}
(-)a/nptl/pthread_condattr_setclock.c (-3 / +3 lines)
Lines 1-4 Link Here
1
/* Copyright (C) 2003, 2004, 2007, 2008 Free Software Foundation, Inc.
1
/* Copyright (C) 2003,2004,2007,2008,2010 Free Software Foundation, Inc.
2
   This file is part of the GNU C Library.
2
   This file is part of the GNU C Library.
3
   Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
3
   Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
4
4
Lines 62-72 pthread_condattr_setclock (attr, clock_id) Link Here
62
    return EINVAL;
62
    return EINVAL;
63
63
64
  /* Make sure the value fits in the bits we reserved.  */
64
  /* Make sure the value fits in the bits we reserved.  */
65
  assert (clock_id < (1 << COND_NWAITERS_SHIFT));
65
  assert (clock_id < (1 << COND_PROTOCOL_SHIFT));
66
66
67
  int *valuep = &((struct pthread_condattr *) attr)->value;
67
  int *valuep = &((struct pthread_condattr *) attr)->value;
68
68
69
  *valuep = ((*valuep & ~(((1 << COND_NWAITERS_SHIFT) - 1) << 1))
69
  *valuep = ((*valuep & ~(((1 << COND_PROTOCOL_SHIFT) - 1) << 1))
70
	     | (clock_id << 1));
70
	     | (clock_id << 1));
71
71
72
  return 0;
72
  return 0;
(-)a/nptl/pthread_condattr_setprotocol_np.c (+39 lines)
Line 0 Link Here
1
/* Copyright (C) 2010 Free Software Foundation, Inc.
2
   This file is part of the GNU C Library.
3
   Contributed by Dinakar Guniguntala <dino@in.ibm.com>, 2010.
4
5
   The GNU C Library is free software; you can redistribute it and/or
6
   modify it under the terms of the GNU Lesser General Public
7
   License as published by the Free Software Foundation; either
8
   version 2.1 of the License, or (at your option) any later version.
9
10
   The GNU C Library is distributed in the hope that it will be useful,
11
   but WITHOUT ANY WARRANTY; without even the implied warranty of
12
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13
   Lesser General Public License for more details.
14
15
   You should have received a copy of the GNU Lesser General Public
16
   License along with the GNU C Library; if not, write to the Free
17
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18
   02111-1307 USA.  */
19
20
#include <errno.h>
21
#include <pthreadP.h>
22
23
int
24
pthread_condattr_setprotocol_np (attr, protocol)
25
     pthread_condattr_t *attr;
26
     int protocol;
27
{
28
  if (protocol != PTHREAD_PRIO_NONE
29
      && protocol != PTHREAD_PRIO_INHERIT
30
      && __builtin_expect (protocol != PTHREAD_PRIO_PROTECT, 0))
31
    return EINVAL;
32
33
  int *valuep = &((struct pthread_condattr *) attr)->value;
34
35
  *valuep = ((*valuep & ~CONDATTR_PROTOCOL_MASK)
36
	     | (protocol << CONDATTR_PROTOCOL_SHIFT));
37
38
  return 0;
39
}
(-)a/nptl/sysdeps/pthread/cond-lock.h (+58 lines)
Line 0 Link Here
1
/* Copyright (C) 2010 Free Software Foundation, Inc.
2
   This file is part of the GNU C Library.
3
4
   The GNU C Library is free software; you can redistribute it and/or
5
   modify it under the terms of the GNU Lesser General Public
6
   License as published by the Free Software Foundation; either
7
   version 2.1 of the License, or (at your option) any later version.
8
9
   The GNU C Library is distributed in the hope that it will be useful,
10
   but WITHOUT ANY WARRANTY; without even the implied warranty of
11
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
   Lesser General Public License for more details.
13
14
   You should have received a copy of the GNU Lesser General Public
15
   License along with the GNU C Library; if not, write to the Free
16
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
17
   02111-1307 USA.  */
18
19
#ifndef _COND_LOCK_H
20
#define _COND_LOCK_H 1
21
22
23
extern void lll_pi_lock (int *futex, int pshared)
24
     __attribute__ ((visibility ("hidden")));
25
extern void lll_pi_unlock (int *futex, int pshared)
26
     __attribute__ ((visibility ("hidden")));
27
28
static inline void cond_lock(pthread_cond_t *cond,
29
			     int pshared);
30
31
static inline void cond_unlock(pthread_cond_t *cond,
32
			       int pshared);
33
34
static inline void cond_lock(cond, pshared)
35
     pthread_cond_t *cond;
36
     int pshared;
37
{
38
  if (pshared == LLL_PRIVATE
39
      && ((cond->__data.__nwaiters & COND_PROTOCOL_MASK)
40
	  == COND_PRIO_INHERIT))
41
    lll_pi_lock (&cond->__data.__lock, pshared);
42
  else
43
    lll_lock (cond->__data.__lock, pshared);
44
}
45
46
static inline void cond_unlock(cond, pshared)
47
     pthread_cond_t *cond;
48
     int pshared;
49
{
50
  if (pshared == LLL_PRIVATE
51
      && ((cond->__data.__nwaiters & COND_PROTOCOL_MASK)
52
	  == COND_PRIO_INHERIT))
53
    lll_pi_unlock (&cond->__data.__lock, pshared);
54
  else
55
    lll_unlock (cond->__data.__lock, pshared);
56
}
57
 
58
#endif
(-)a/nptl/sysdeps/pthread/pthread.h (+12 lines)
Lines 1006-1011 extern int pthread_condattr_getpshared (__const pthread_condattr_t * Link Here
1006
extern int pthread_condattr_setpshared (pthread_condattr_t *__attr,
1006
extern int pthread_condattr_setpshared (pthread_condattr_t *__attr,
1007
					int __pshared) __THROW __nonnull ((1));
1007
					int __pshared) __THROW __nonnull ((1));
1008
1008
1009
/* Get the protocol flag of the condition variable attribute ATTR.  */
1010
extern int pthread_condattr_getprotocol_np (__const pthread_condattr_t *
1011
                                            __restrict __attr,
1012
                                            int *__restrict __protocol)
1013
     __THROW __nonnull ((1, 2));
1014
1015
/* Set the cond protocol attribute in ATTR to protocol (one of
1016
   PTHREAD_PRIO_NONE, PTHREAD_PRIO_INHERIT or PTHREAD_PRIO_PROTECT).  */
1017
extern int pthread_condattr_setprotocol_np (pthread_condattr_t *__attr,
1018
                                            int __protocol)
1019
     __THROW __nonnull ((1));
1020
1009
#ifdef __USE_XOPEN2K
1021
#ifdef __USE_XOPEN2K
1010
/* Get the clock selected for the conditon variable attribute ATTR.  */
1022
/* Get the clock selected for the conditon variable attribute ATTR.  */
1011
extern int pthread_condattr_getclock (__const pthread_condattr_t *
1023
extern int pthread_condattr_getclock (__const pthread_condattr_t *
(-)a/nptl/sysdeps/unix/sysv/linux/i386/lowlevellock.h (-1 / +87 lines)
Lines 1-4 Link Here
1
/* Copyright (C) 2002-2004, 2006-2008, 2009 Free Software Foundation, Inc.
1
/* Copyright (C) 2002,2003,2004,2006,2007,2008,2010
2
   Free Software Foundation, Inc.
2
   This file is part of the GNU C Library.
3
   This file is part of the GNU C Library.
3
   Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
4
   Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
4
5
Lines 238-243 LLL_STUB_UNWIND_INFO_END Link Here
238
  } while (0)
239
  } while (0)
239
240
240
241
242
#define lll_futex_wait_requeue_pi(cond, val, mutex, private) \
243
  lll_futex_timed_wait_requeue_pi (cond, val, NULL, mutex, private)
244
245
246
#define lll_futex_timed_wait_requeue_pi(cond, val, time, mutex, private) \
247
  ({									      \
248
    INTERNAL_SYSCALL_DECL (__err);					      \
249
    long int __ret;							      \
250
    unsigned int *__futexp = &cond->__data.__futex;			      \
251
    int __flag = FUTEX_WAIT_REQUEUE_PI;					      \
252
    __flag = (cond->__data.__nwaiters & COND_CLOCK_MASK) ?		      \
253
	      __flag  : __flag | FUTEX_CLOCK_REALTIME;			      \
254
    __ret = INTERNAL_SYSCALL (futex, __err, 5,				      \
255
			      (__futexp),				      \
256
			      __lll_private_flag (__flag, private),	      \
257
			      (val), time,				      \
258
			      (mutex));					      \
259
    INTERNAL_SYSCALL_ERROR_P (__ret, __err)? -__ret : __ret;		      \
260
  })
261
262
263
#define lll_futex_requeue(futex, nr_wake, nr_move, mutex, val, private) \
264
  ({									      \
265
    int __status;							      \
266
    int __save_ebx;							      \
267
    int __dummy;							      \
268
    int __flag = FUTEX_CMP_REQUEUE;					      \
269
    register __typeof (nr_move) _nr_move asm ("esi") = (nr_move);	      \
270
    __asm __volatile ("mov %%ebx, %0\n\t"				      \
271
		      "mov %1, %%ebx\n\t"				      \
272
		      LLL_EBX_LOAD					      \
273
		      "pushl %%ebp\n\t"					      \
274
		      "mov %3, %%ebp\n\t"				      \
275
		      : "=m" (__save_ebx)				      \
276
		      : "c" (mutex), LLL_EBX_REG (futex),		      \
277
		        "a" (val));					      \
278
    __asm __volatile (LLL_ENTER_KERNEL					      \
279
		      "popl %%ebp\n\t"					      \
280
		      : "=a" (__status)					      \
281
		      : "0" (SYS_futex), 				      \
282
			"c" (__lll_private_flag (__flag, private)),	      \
283
			"d" (nr_wake), "S" (_nr_move),			      \
284
			"i" (0) /* phony, to align next arg's number */,      \
285
			"i" (offsetof (tcbhead_t, sysinfo))		      \
286
		      : "memory");					      \
287
    __asm __volatile (LLL_EBX_LOAD					      \
288
		      "mov %1, %%ebx\n\t"				      \
289
		      : "=m" (__dummy)					      \
290
		      : "m" (__save_ebx), LLL_EBX_REG (futex));		      \
291
    __status;								      \
292
  })
293
294
295
#define lll_futex_requeue_pi(futex, nr_wake, nr_move, mutex, val, private) \
296
  ({									      \
297
    int __status;							      \
298
    int __save_ebx;							      \
299
    int __dummy;							      \
300
    int __flag = FUTEX_CMP_REQUEUE_PI;					      \
301
    register __typeof (nr_move) _nr_move asm ("esi") = (nr_move);	      \
302
    __asm __volatile ("mov %%ebx, %0\n\t"				      \
303
		      "mov %1, %%ebx\n\t"				      \
304
		      LLL_EBX_LOAD					      \
305
		      "pushl %%ebp\n\t"					      \
306
		      "mov %3, %%ebp\n\t"				      \
307
		      : "=m" (__save_ebx)				      \
308
		      : "c" (mutex), LLL_EBX_REG (futex),		      \
309
		        "a" (val));					      \
310
    __asm __volatile (LLL_ENTER_KERNEL					      \
311
		      "popl %%ebp\n\t"					      \
312
		      : "=a" (__status)					      \
313
		      : "0" (SYS_futex), 				      \
314
			"c" (__lll_private_flag (__flag, private)),	      \
315
			"d" (nr_wake), "S" (_nr_move),			      \
316
			"i" (0) /* phony, to align next arg's number */,      \
317
			"i" (offsetof (tcbhead_t, sysinfo))		      \
318
		      : "memory");					      \
319
    __asm __volatile (LLL_EBX_LOAD					      \
320
		      "mov %1, %%ebx\n\t"				      \
321
		      : "=m" (__dummy)					      \
322
		      : "m" (__save_ebx), LLL_EBX_REG (futex));		      \
323
    __status;								      \
324
  })
325
326
241
/* NB: in the lll_trylock macro we simply return the value in %eax
327
/* NB: in the lll_trylock macro we simply return the value in %eax
242
   after the cmpxchg instruction.  In case the operation succeded this
328
   after the cmpxchg instruction.  In case the operation succeded this
243
   value is zero.  In case the operation failed, the cmpxchg instruction
329
   value is zero.  In case the operation failed, the cmpxchg instruction
(-)a/nptl/sysdeps/unix/sysv/linux/internaltypes.h (-6 / +24 lines)
Lines 67-86 struct pthread_condattr Link Here
67
{
67
{
68
  /* Combination of values:
68
  /* Combination of values:
69
69
70
     Bit 0  : flag whether coditional variable will be shareable between
70
     Bit 0  : flag whether conditional variable will be shareable between
71
	      processes.
71
	      processes.
72
72
73
     Bit 1-7: clock ID.  */
73
     Bit 1-7: clock ID.
74
     Bit 8-9: protocol. One of PTHREAD_PRIO_NONE, PTHREAD_PRIO_INHERIT
75
              or PTHREAD_PRIO_PROTECT.  */
74
  int value;
76
  int value;
75
};
77
};
76
78
77
79
80
#define CONDATTR_PSHARED_MASK	0x00000001
81
#define CONDATTR_CLOCKID_MASK	0x000000FE
82
#define CONDATTR_CLOCKID_SHIFT	1
83
#define CONDATTR_PROTOCOL_MASK	0x00000300
84
#define CONDATTR_PROTOCOL_SHIFT	8
85
86
87
enum {
88
  COND_PRIO_INHERIT = 2,
89
  COND_PRIO_PROTECT
90
};
91
92
78
/* The __NWAITERS field is used as a counter and to house the number
93
/* The __NWAITERS field is used as a counter and to house the number
79
   of bits for other purposes.  COND_CLOCK_BITS is the number
94
   of bits for other purposes.  COND_CLOCK_MASK defines the bits used
80
   of bits needed to represent the ID of the clock.  COND_NWAITERS_SHIFT
95
   to represent the ID of the clock.  COND_PROTOCOL_MASK defines the
96
   bits used to represent cond protocol attrbutes. COND_NWAITERS_SHIFT
81
   is the number of bits reserved for other purposes like the clock.  */
97
   is the number of bits reserved for other purposes like the clock.  */
82
#define COND_CLOCK_BITS		1
98
#define COND_CLOCK_MASK		0x00000001
83
#define COND_NWAITERS_SHIFT	1
99
#define COND_PROTOCOL_SHIFT	1
100
#define COND_PROTOCOL_MASK	0x00000006
101
#define COND_NWAITERS_SHIFT	3
84
102
85
103
86
/* Read-write lock variable attribute data structure.  */
104
/* Read-write lock variable attribute data structure.  */
(-)a/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h (-1 / +40 lines)
Lines 223-228 LLL_STUB_UNWIND_INFO_END Link Here
223
  })
223
  })
224
224
225
225
226
#define lll_futex_wait_requeue_pi(cond, val, mutex, private) \
227
  lll_futex_timed_wait_requeue_pi(cond, val, NULL, mutex, private)
228
229
230
#define lll_futex_timed_wait_requeue_pi(cond, val, timeout, mutex, private) \
231
  ({									      \
232
    register const struct timespec *__to __asm ("r10") = timeout;	      \
233
    register void *__mutex __asm  ("r8") = mutex;			      \
234
    unsigned int *__futexp = &cond->__data.__futex;			      \
235
    int __flag = FUTEX_WAIT_REQUEUE_PI;					      \
236
    __flag = (cond->__data.__nwaiters & COND_CLOCK_MASK) ?		      \
237
		      __flag  : __flag | FUTEX_CLOCK_REALTIME;		      \
238
    int __status;							      \
239
    register __typeof (val) _val __asm ("edx") = (val);			      \
240
    __asm __volatile ("syscall"						      \
241
		      : "=a" (__status)					      \
242
		      : "0" (SYS_futex), "D" (__futexp),		      \
243
			"S" (__lll_private_flag (__flag, private)),	      \
244
			"d" (_val), "r" (__to),				      \
245
			"r" (__mutex)					      \
246
		      : "memory", "cc", "r11", "cx");			      \
247
    __status;								      \
248
  })
249
250
226
#define lll_futex_wake(futex, nr, private) \
251
#define lll_futex_wake(futex, nr, private) \
227
  do {									      \
252
  do {									      \
228
    int __ignore;							      \
253
    int __ignore;							      \
Lines 554-559 LLL_STUB_UNWIND_INFO_END Link Here
554
		       : "cx", "r11", "cc", "memory");			      \
579
		       : "cx", "r11", "cc", "memory");			      \
555
     __res < 0; })
580
     __res < 0; })
556
581
582
/* Returns non-zero if error happened, zero if success.  */
583
#define lll_futex_requeue_pi(ftx, nr_wake, nr_move, mutex, val, private) \
584
  ({ int __res;								      \
585
     register int __nr_move __asm ("r10") = nr_move;			      \
586
     register void *__mutex __asm ("r8") = mutex;			      \
587
     register int __val __asm ("r9") = val;				      \
588
     __asm __volatile ("syscall"					      \
589
		       : "=a" (__res)					      \
590
		       : "0" (__NR_futex), "D" ((void *) ftx),		      \
591
			 "S" (__lll_private_flag (FUTEX_CMP_REQUEUE_PI,	      \
592
						  private)), "d" (nr_wake),   \
593
			 "r" (__nr_move), "r" (__mutex), "r" (__val)	      \
594
		       : "cx", "r11", "cc", "memory");			      \
595
     __res < 0; })
596
557
#define lll_islocked(futex) \
597
#define lll_islocked(futex) \
558
  (futex != LLL_LOCK_INITIALIZER)
598
  (futex != LLL_LOCK_INITIALIZER)
559
599
560
- 

Return to bug 11588