2003-03-21  Ulrich Drepper  <drepper@redhat.com>

	* cancellation.c: Adjust for new form of compare&exchange macros.
	* cleanup_defer.c: Likewise.
	* init.c: Likewise.
	* libc-cancellation.c: Likewise.
	* old_pthread_cond_broadcast.c: Likewise.
	* old_pthread_cond_signal.c: Likewise.
	* old_pthread_cond_timedwait.c: Likewise.
	* old_pthread_cond_wait.c: Likewise.
	* pthread_cancel.c: Likewise.
	* pthread_create.c: Likewise.
	* pthread_detach.c: Likewise.
	* pthread_join.c: Likewise.
	* pthread_key_delete.c: Likewise.
	* pthread_setcancelstate.c: Likewise.
	* pthread_setcanceltype.c: Likewise.
	* pthread_timedjoin.c: Likewise.
	* pthread_tryjoin.c: Likewise.
	* sysdeps/pthread/createthread.c: Likewise.
This commit is contained in:
Ulrich Drepper 2003-03-21 08:03:25 +00:00
parent 18627f615b
commit 5a3ab2fc18
29 changed files with 172 additions and 148 deletions

View File

@ -69,8 +69,8 @@ _MCOUNT_DECL(frompc, selfpc) /* _mcount; may be static, inline, etc */
* check that we are profiling * check that we are profiling
* and that we aren't recursively invoked. * and that we aren't recursively invoked.
*/ */
if (atomic_compare_and_exchange_acq (&p->state, GMON_PROF_BUSY, if (atomic_compare_and_exchange_bool_acq (&p->state, GMON_PROF_BUSY,
GMON_PROF_ON)) GMON_PROF_ON))
return; return;
/* /*

View File

@ -36,7 +36,7 @@ __libc_freeres (void)
protect for multiple executions since these are fatal. */ protect for multiple executions since these are fatal. */
static long int already_called; static long int already_called;
if (! atomic_compare_and_exchange_acq (&already_called, 1, 0)) if (! atomic_compare_and_exchange_bool_acq (&already_called, 1, 0))
{ {
void * const *p; void * const *p;

View File

@ -1,3 +1,24 @@
2003-03-21 Ulrich Drepper <drepper@redhat.com>
* cancellation.c: Adjust for new form of compare&exchange macros.
* cleanup_defer.c: Likewise.
* init.c: Likewise.
* libc-cancellation.c: Likewise.
* old_pthread_cond_broadcast.c: Likewise.
* old_pthread_cond_signal.c: Likewise.
* old_pthread_cond_timedwait.c: Likewise.
* old_pthread_cond_wait.c: Likewise.
* pthread_cancel.c: Likewise.
* pthread_create.c: Likewise.
* pthread_detach.c: Likewise.
* pthread_join.c: Likewise.
* pthread_key_delete.c: Likewise.
* pthread_setcancelstate.c: Likewise.
* pthread_setcanceltype.c: Likewise.
* pthread_timedjoin.c: Likewise.
* pthread_tryjoin.c: Likewise.
* sysdeps/pthread/createthread.c: Likewise.
2003-03-20 Ulrich Drepper <drepper@redhat.com> 2003-03-20 Ulrich Drepper <drepper@redhat.com>
* sysdeps/unix/sysv/linux/ia64/lowlevellock.h: Include <atomic.h>. * sysdeps/unix/sysv/linux/ia64/lowlevellock.h: Include <atomic.h>.

View File

@ -41,8 +41,8 @@ __pthread_enable_asynccancel (void)
if (newval == oldval) if (newval == oldval)
break; break;
if (atomic_compare_and_exchange_acq (&self->cancelhandling, newval, if (! atomic_compare_and_exchange_bool_acq (&self->cancelhandling,
oldval) == 0) newval, oldval))
{ {
if (CANCEL_ENABLED_AND_CANCELED_AND_ASYNCHRONOUS (newval)) if (CANCEL_ENABLED_AND_CANCELED_AND_ASYNCHRONOUS (newval))
{ {
@ -72,8 +72,8 @@ __pthread_enable_asynccancel_2 (int *oldvalp)
if (newval == oldval) if (newval == oldval)
break; break;
if (atomic_compare_and_exchange_acq (&self->cancelhandling, newval, if (! atomic_compare_and_exchange_bool_acq (&self->cancelhandling,
oldval) == 0) newval, oldval))
{ {
if (CANCEL_ENABLED_AND_CANCELED_AND_ASYNCHRONOUS (newval)) if (CANCEL_ENABLED_AND_CANCELED_AND_ASYNCHRONOUS (newval))
{ {
@ -106,8 +106,8 @@ __pthread_disable_asynccancel (int oldtype)
if (newval == oldval) if (newval == oldval)
break; break;
if (atomic_compare_and_exchange_acq (&self->cancelhandling, newval, if (! atomic_compare_and_exchange_bool_acq (&self->cancelhandling,
oldval) == 0) newval, oldval))
break; break;
} }
} }

View File

@ -41,10 +41,10 @@ _pthread_cleanup_push_defer (buffer, routine, arg)
/* Disable asynchronous cancellation for now. */ /* Disable asynchronous cancellation for now. */
if (__builtin_expect (cancelhandling & CANCELTYPE_BITMASK, 0)) if (__builtin_expect (cancelhandling & CANCELTYPE_BITMASK, 0))
{ {
while (atomic_compare_and_exchange_acq (&self->cancelhandling, while (atomic_compare_and_exchange_bool_acq (&self->cancelhandling,
cancelhandling cancelhandling
& ~CANCELTYPE_BITMASK, & ~CANCELTYPE_BITMASK,
cancelhandling) != 0) cancelhandling))
cancelhandling = self->cancelhandling; cancelhandling = self->cancelhandling;
} }
@ -70,10 +70,10 @@ _pthread_cleanup_pop_restore (buffer, execute)
&& ((cancelhandling = THREAD_GETMEM (self, cancelhandling)) && ((cancelhandling = THREAD_GETMEM (self, cancelhandling))
& CANCELTYPE_BITMASK) == 0) & CANCELTYPE_BITMASK) == 0)
{ {
while (atomic_compare_and_exchange_acq (&self->cancelhandling, while (atomic_compare_and_exchange_bool_acq (&self->cancelhandling,
cancelhandling cancelhandling
| CANCELTYPE_BITMASK, | CANCELTYPE_BITMASK,
cancelhandling) != 0) cancelhandling))
cancelhandling = self->cancelhandling; cancelhandling = self->cancelhandling;
CANCELLATION_P (self); CANCELLATION_P (self);

View File

@ -147,8 +147,8 @@ sigcancel_handler (int sig __attribute ((unused)))
/* Already canceled or exiting. */ /* Already canceled or exiting. */
break; break;
if (atomic_compare_and_exchange_acq (&self->cancelhandling, newval, if (! atomic_compare_and_exchange_bool_acq (&self->cancelhandling,
oldval) == 0) newval, oldval))
{ {
/* Set the return value. */ /* Set the return value. */
THREAD_SETMEM (self, result, PTHREAD_CANCELED); THREAD_SETMEM (self, result, PTHREAD_CANCELED);

View File

@ -34,11 +34,12 @@ __libc_enable_asynccancel (void)
{ {
struct pthread *self = THREAD_SELF; struct pthread *self = THREAD_SELF;
int oldval; int oldval;
int newval;
while (1) do
{ {
oldval = THREAD_GETMEM (self, cancelhandling); oldval = THREAD_GETMEM (self, cancelhandling);
int newval = oldval | CANCELTYPE_BITMASK; newval = oldval | CANCELTYPE_BITMASK;
if (__builtin_expect ((oldval & CANCELED_BITMASK) != 0, 0)) if (__builtin_expect ((oldval & CANCELED_BITMASK) != 0, 0))
{ {
@ -46,8 +47,8 @@ __libc_enable_asynccancel (void)
if ((oldval & EXITING_BITMASK) != 0) if ((oldval & EXITING_BITMASK) != 0)
break; break;
if (atomic_compare_and_exchange_acq (&self->cancelhandling, newval, if (atomic_compare_and_exchange_bool_acq (&self->cancelhandling,
oldval) != 0) newval, oldval))
/* Somebody else modified the word, try again. */ /* Somebody else modified the word, try again. */
continue; continue;
@ -60,11 +61,9 @@ __libc_enable_asynccancel (void)
/* NOTREACHED */ /* NOTREACHED */
} }
if (atomic_compare_and_exchange_acq (&self->cancelhandling, newval,
oldval) == 0)
break;
} }
while (atomic_compare_and_exchange_bool_acq (&self->cancelhandling,
newval, oldval));
return oldval; return oldval;
} }
@ -80,19 +79,19 @@ __libc_disable_asynccancel (int oldtype)
return; return;
struct pthread *self = THREAD_SELF; struct pthread *self = THREAD_SELF;
int oldval;
int newval;
while (1) do
{ {
int oldval = THREAD_GETMEM (self, cancelhandling); oldval = THREAD_GETMEM (self, cancelhandling);
int newval = oldval & ~CANCELTYPE_BITMASK; newval = oldval & ~CANCELTYPE_BITMASK;
if (newval == oldval) if (newval == oldval)
break; break;
if (atomic_compare_and_exchange_acq (&self->cancelhandling, newval,
oldval) == 0)
break;
} }
while (atomic_compare_and_exchange_bool_acq (&self->cancelhandling, newval,
oldval));
} }
#endif #endif

View File

@ -46,7 +46,7 @@ __pthread_cond_broadcast_2_0 (cond)
(void) pthread_cond_init (newcond, NULL); (void) pthread_cond_init (newcond, NULL);
#endif #endif
if (atomic_compare_and_exchange_acq (&cond->cond, newcond, NULL) != 0) if (atomic_compare_and_exchange_bool_acq (&cond->cond, newcond, NULL))
/* Somebody else just initialized the condvar. */ /* Somebody else just initialized the condvar. */
free (newcond); free (newcond);
} }

View File

@ -46,7 +46,7 @@ __pthread_cond_signal_2_0 (cond)
(void) pthread_cond_init (newcond, NULL); (void) pthread_cond_init (newcond, NULL);
#endif #endif
if (atomic_compare_and_exchange_acq (&cond->cond, newcond, NULL) != 0) if (atomic_compare_and_exchange_bool_acq (&cond->cond, newcond, NULL))
/* Somebody else just initialized the condvar. */ /* Somebody else just initialized the condvar. */
free (newcond); free (newcond);
} }

View File

@ -48,7 +48,7 @@ __pthread_cond_timedwait_2_0 (cond, mutex, abstime)
(void) pthread_cond_init (newcond, NULL); (void) pthread_cond_init (newcond, NULL);
#endif #endif
if (atomic_compare_and_exchange_acq (&cond->cond, newcond, NULL) != 0) if (atomic_compare_and_exchange_bool_acq (&cond->cond, newcond, NULL))
/* Somebody else just initialized the condvar. */ /* Somebody else just initialized the condvar. */
free (newcond); free (newcond);
} }

View File

@ -47,7 +47,7 @@ __pthread_cond_wait_2_0 (cond, mutex)
(void) pthread_cond_init (newcond, NULL); (void) pthread_cond_init (newcond, NULL);
#endif #endif
if (atomic_compare_and_exchange_acq (&cond->cond, newcond, NULL) != 0) if (atomic_compare_and_exchange_bool_acq (&cond->cond, newcond, NULL))
/* Somebody else just initialized the condvar. */ /* Somebody else just initialized the condvar. */
free (newcond); free (newcond);
} }

View File

@ -36,10 +36,12 @@ pthread_cancel (th)
return ESRCH; return ESRCH;
int result = 0; int result = 0;
while (1) int oldval;
int newval;
do
{ {
int oldval = pd->cancelhandling; oldval = pd->cancelhandling;
int newval = oldval | CANCELING_BITMASK | CANCELED_BITMASK; newval = oldval | CANCELING_BITMASK | CANCELED_BITMASK;
/* Avoid doing unnecessary work. The atomic operation can /* Avoid doing unnecessary work. The atomic operation can
potentially be expensive if the bug has to be locked and potentially be expensive if the bug has to be locked and
@ -66,13 +68,11 @@ pthread_cancel (th)
break; break;
} }
/* Mark the thread as canceled. This has to be done
atomically since other bits could be modified as well. */
if (atomic_compare_and_exchange_acq (&pd->cancelhandling, newval,
oldval) == 0)
break;
} }
/* Mark the thread as canceled. This has to be done
atomically since other bits could be modified as well. */
while (atomic_compare_and_exchange_bool_acq (&pd->cancelhandling, newval,
oldval));
return result; return result;
} }

View File

@ -260,8 +260,8 @@ start_thread (void *arg)
do do
pd->nextevent = __nptl_last_event; pd->nextevent = __nptl_last_event;
while (atomic_compare_and_exchange_acq (&__nptl_last_event, pd, while (atomic_compare_and_exchange_bool_acq (&__nptl_last_event,
pd->nextevent) != 0); pd, pd->nextevent));
} }
/* Now call the function to signal the event. */ /* Now call the function to signal the event. */

View File

@ -36,7 +36,7 @@ pthread_detach (th)
int result = 0; int result = 0;
/* Mark the thread as detached. */ /* Mark the thread as detached. */
if (atomic_compare_and_exchange_acq (&pd->joinid, pd, NULL) != 0) if (atomic_compare_and_exchange_bool_acq (&pd->joinid, pd, NULL))
{ {
/* There are two possibilities here. First, the thread might /* There are two possibilities here. First, the thread might
already be detached. In this case we return EINVAL. already be detached. In this case we return EINVAL.

View File

@ -66,8 +66,9 @@ pthread_join (threadid, thread_return)
/* Wait for the thread to finish. If it is already locked something /* Wait for the thread to finish. If it is already locked something
is wrong. There can only be one waiter. */ is wrong. There can only be one waiter. */
if (__builtin_expect (atomic_compare_and_exchange_acq (&pd->joinid, self, if (__builtin_expect (atomic_compare_and_exchange_bool_acq (&pd->joinid,
NULL) != 0, 0)) self,
NULL), 0))
/* There is already somebody waiting for the thread. */ /* There is already somebody waiting for the thread. */
return EINVAL; return EINVAL;

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2002 Free Software Foundation, Inc. /* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
@ -33,8 +33,8 @@ pthread_key_delete (key)
unsigned int seq = __pthread_keys[key].seq; unsigned int seq = __pthread_keys[key].seq;
if (__builtin_expect (! KEY_UNUSED (seq), 1) if (__builtin_expect (! KEY_UNUSED (seq), 1)
&& atomic_compare_and_exchange_acq (&__pthread_keys[key].seq, && ! atomic_compare_and_exchange_bool_acq (&__pthread_keys[key].seq,
seq + 1, seq) == 0) seq + 1, seq))
/* We deleted a valid key. */ /* We deleted a valid key. */
result = 0; result = 0;
} }

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2002 Free Software Foundation, Inc. /* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
@ -54,8 +54,8 @@ __pthread_setcancelstate (state, oldstate)
/* Update the cancel handling word. This has to be done /* Update the cancel handling word. This has to be done
atomically since other bits could be modified as well. */ atomically since other bits could be modified as well. */
if (atomic_compare_and_exchange_acq (&self->cancelhandling, newval, if (! atomic_compare_and_exchange_bool_acq (&self->cancelhandling,
oldval) == 0) newval, oldval))
{ {
if (CANCEL_ENABLED_AND_CANCELED_AND_ASYNCHRONOUS (newval)) if (CANCEL_ENABLED_AND_CANCELED_AND_ASYNCHRONOUS (newval))
__do_cancel (); __do_cancel ();

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2002 Free Software Foundation, Inc. /* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
@ -54,8 +54,8 @@ __pthread_setcanceltype (type, oldtype)
/* Update the cancel handling word. This has to be done /* Update the cancel handling word. This has to be done
atomically since other bits could be modified as well. */ atomically since other bits could be modified as well. */
if (atomic_compare_and_exchange_acq (&self->cancelhandling, newval, if (! atomic_compare_and_exchange_bool_acq (&self->cancelhandling,
oldval) == 0) newval, oldval))
{ {
if (CANCEL_ENABLED_AND_CANCELED_AND_ASYNCHRONOUS (newval)) if (CANCEL_ENABLED_AND_CANCELED_AND_ASYNCHRONOUS (newval))
{ {

View File

@ -63,8 +63,8 @@ pthread_timedjoin_np (threadid, thread_return, abstime)
/* Wait for the thread to finish. If it is already locked something /* Wait for the thread to finish. If it is already locked something
is wrong. There can only be one waiter. */ is wrong. There can only be one waiter. */
if (__builtin_expect (atomic_compare_and_exchange_acq (&pd->joinid, self, if (__builtin_expect (atomic_compare_and_exchange_bool_acq (&pd->joinid,
NULL) != 0, 0)) self, NULL), 0))
/* There is already somebody waiting for the thread. */ /* There is already somebody waiting for the thread. */
return EINVAL; return EINVAL;

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2002 Free Software Foundation, Inc. /* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
@ -59,7 +59,7 @@ pthread_tryjoin_np (threadid, thread_return)
/* Wait for the thread to finish. If it is already locked something /* Wait for the thread to finish. If it is already locked something
is wrong. There can only be one waiter. */ is wrong. There can only be one waiter. */
if (atomic_compare_and_exchange_acq (&pd->joinid, self, NULL) != 0) if (atomic_compare_and_exchange_bool_acq (&pd->joinid, self, NULL))
/* There is already somebody waiting for the thread. */ /* There is already somebody waiting for the thread. */
return EINVAL; return EINVAL;

View File

@ -100,8 +100,8 @@ create_thread (struct pthread *pd, STACK_VARIABLES_PARMS)
/* Enqueue the descriptor. */ /* Enqueue the descriptor. */
do do
pd->nextevent = __nptl_last_event; pd->nextevent = __nptl_last_event;
while (atomic_compare_and_exchange_acq (&__nptl_last_event, pd, while (atomic_compare_and_exchange_bool_acq (&__nptl_last_event, pd,
pd->nextevent) != 0); pd->nextevent) != 0);
/* Now call the function which signals the event. */ /* Now call the function which signals the event. */
__nptl_create_event (); __nptl_create_event ();

View File

@ -101,8 +101,8 @@ cache_add (int type, void *key, size_t len, const void *packet, size_t total,
/* Put the new entry in the first position. */ /* Put the new entry in the first position. */
do do
newp->next = table->array[hash]; newp->next = table->array[hash];
while (atomic_compare_and_exchange_acq (&table->array[hash], newp, while (atomic_compare_and_exchange_bool_acq (&table->array[hash], newp,
newp->next)); newp->next));
/* Update the statistics. */ /* Update the statistics. */
if (data == (void *) -1) if (data == (void *) -1)

View File

@ -36,8 +36,8 @@ __cxa_finalize (void *d)
for (f = &funcs->fns[funcs->idx - 1]; f >= &funcs->fns[0]; --f) for (f = &funcs->fns[funcs->idx - 1]; f >= &funcs->fns[0]; --f)
if ((d == NULL || d == f->func.cxa.dso_handle) if ((d == NULL || d == f->func.cxa.dso_handle)
/* We don't want to run this cleanup more than once. */ /* We don't want to run this cleanup more than once. */
&& (atomic_compare_and_exchange_acq (&f->flavor, ef_free, ef_cxa) && ! atomic_compare_and_exchange_bool_acq (&f->flavor, ef_free,
== 0)) ef_cxa))
(*f->func.cxa.fn) (f->func.cxa.arg, 0); (*f->func.cxa.fn) (f->func.cxa.arg, 0);
} }

View File

@ -55,23 +55,23 @@ typedef uintmax_t uatomic_max_t;
#endif #endif
#define __arch_compare_and_exchange_8_acq(mem, newval, oldval) \ #define __arch_compare_and_exchange_val_8_acq(mem, newval, oldval) \
({ unsigned char ret; \ ({ __typeof (*mem) ret; \
__asm __volatile (LOCK "cmpxchgb %b2, %1; setne %0" \ __asm __volatile (LOCK "cmpxchgb %b2, %1" \
: "=a" (ret), "=m" (*mem) \ : "=a" (ret), "=m" (*mem) \
: "q" (newval), "1" (*mem), "0" (oldval)); \ : "q" (newval), "1" (*mem), "0" (oldval)); \
ret; }) ret; })
#define __arch_compare_and_exchange_16_acq(mem, newval, oldval) \ #define __arch_compare_and_exchange_val_16_acq(mem, newval, oldval) \
({ unsigned char ret; \ ({ __typeof (*mem) ret; \
__asm __volatile (LOCK "cmpxchgw %w2, %1; setne %0" \ __asm __volatile (LOCK "cmpxchgw %w2, %1" \
: "=a" (ret), "=m" (*mem) \ : "=a" (ret), "=m" (*mem) \
: "r" (newval), "1" (*mem), "0" (oldval)); \ : "r" (newval), "1" (*mem), "0" (oldval)); \
ret; }) ret; })
#define __arch_compare_and_exchange_32_acq(mem, newval, oldval) \ #define __arch_compare_and_exchange_val_32_acq(mem, newval, oldval) \
({ unsigned char ret; \ ({ __typeof (*mem) ret; \
__asm __volatile (LOCK "cmpxchgl %2, %1; setne %0" \ __asm __volatile (LOCK "cmpxchgl %2, %1" \
: "=a" (ret), "=m" (*mem) \ : "=a" (ret), "=m" (*mem) \
: "r" (newval), "1" (*mem), "0" (oldval)); \ : "r" (newval), "1" (*mem), "0" (oldval)); \
ret; }) ret; })
@ -83,37 +83,34 @@ typedef uintmax_t uatomic_max_t;
really going to be used the code below can be used on Intel Pentium really going to be used the code below can be used on Intel Pentium
and later, but NOT on i486. */ and later, but NOT on i486. */
#if 1 #if 1
# define __arch_compare_and_exchange_64_acq(mem, newval, oldval) \ # define __arch_compare_and_exchange_val_64_acq(mem, newval, oldval) \
(abort (), 0) (abort (), 0)
#else #else
# ifdef __PIC__ # ifdef __PIC__
# define __arch_compare_and_exchange_64_acq(mem, newval, oldval) \ # define __arch_compare_and_exchange_val_64_acq(mem, newval, oldval) \
({ unsigned char ret; \ ({ __typeof (*mem) ret; \
int ignore; \ __asm __volatile ("xchgl %2, %%ebx\n\t" \
__asm __volatile ("xchgl %3, %%ebx\n\t" \ LOCK "cmpxchg8b %1\n\t" \
LOCK "cmpxchg8b %2, %1\n\t" \ "xchgl %2, %%ebx" \
"setne %0\n\t" \ : "=A" (ret), "=m" (*mem) \
"xchgl %3, %%ebx" \
: "=a" (ret), "=m" (*mem), "=d" (ignore) \
: "DS" (((unsigned long long int) (newval)) \ : "DS" (((unsigned long long int) (newval)) \
& 0xffffffff), \ & 0xffffffff), \
"c" (((unsigned long long int) (newval)) >> 32), \ "c" (((unsigned long long int) (newval)) >> 32), \
"1" (*mem), "0" (((unsigned long long int) (oldval)) \ "1" (*mem), "a" (((unsigned long long int) (oldval)) \
& 0xffffffff), \ & 0xffffffff), \
"2" (((unsigned long long int) (oldval)) >> 32)); \ "d" (((unsigned long long int) (oldval)) >> 32)); \
ret; }) ret; })
# else # else
# define __arch_compare_and_exchange_64_acq(mem, newval, oldval) \ # define __arch_compare_and_exchange_64_acq(mem, newval, oldval) \
({ unsigned char ret; \ ({ __typeof (*mem) ret; \
int ignore; \ __asm __volatile (LOCK "cmpxchg8b %1" \
__asm __volatile (LOCK "cmpxchg8b %2, %1; setne %0" \ : "=A" (ret), "=m" (*mem) \
: "=a" (ret), "=m" (*mem), "=d" (ignore) \
: "b" (((unsigned long long int) (newval)) \ : "b" (((unsigned long long int) (newval)) \
& 0xffffffff), \ & 0xffffffff), \
"c" (((unsigned long long int) (newval)) >> 32), \ "c" (((unsigned long long int) (newval)) >> 32), \
"1" (*mem), "0" (((unsigned long long int) (oldval)) \ "1" (*mem), "a" (((unsigned long long int) (oldval)) \
& 0xffffffff), \ & 0xffffffff), \
"2" (((unsigned long long int) (oldval)) >> 32)); \ "d" (((unsigned long long int) (oldval)) >> 32)); \
ret; }) ret; })
# endif # endif
#endif #endif

View File

@ -45,25 +45,31 @@ typedef intmax_t atomic_max_t;
typedef uintmax_t uatomic_max_t; typedef uintmax_t uatomic_max_t;
#define __arch_compare_and_exchange_8_acq(mem, newval, oldval) \ #define __arch_compare_and_exchange_bool_8_acq(mem, newval, oldval) \
(abort (), 0) (abort (), 0)
#define __arch_compare_and_exchange_16_acq(mem, newval, oldval) \ #define __arch_compare_and_exchange_bool_16_acq(mem, newval, oldval) \
(abort (), 0) (abort (), 0)
#define __arch_compare_and_exchange_32_acq(mem, newval, oldval) \ #define __arch_compare_and_exchange_bool_32_acq(mem, newval, oldval) \
(!__sync_bool_compare_and_swap_si ((int *) (mem), (int) (long) (oldval), \ (!__sync_bool_compare_and_swap_si ((int *) (mem), (int) (long) (oldval), \
(int) (long) (newval))) (int) (long) (newval)))
#define __arch_compare_and_exchange_64_acq(mem, newval, oldval) \ #define __arch_compare_and_exchange_bool_64_acq(mem, newval, oldval) \
(!__sync_bool_compare_and_swap_di ((long *) (mem), (long) (oldval), \ (!__sync_bool_compare_and_swap_di ((long *) (mem), (long) (oldval), \
(long) (newval))) (long) (newval)))
#define __arch_compare_and_exchange_32_val_acq(mem, newval, oldval) \ #define __arch_compare_and_exchange_val_8_acq(mem, newval, oldval) \
(abort (), 0)
#define __arch_compare_and_exchange_val_16_acq(mem, newval, oldval) \
(abort (), 0)
#define __arch_compare_and_exchange_val_32_acq(mem, newval, oldval) \
__sync_val_compare_and_swap_si ((int *) (mem), (int) (long) (oldval), \ __sync_val_compare_and_swap_si ((int *) (mem), (int) (long) (oldval), \
(int) (long) (newval)) (int) (long) (newval))
#define __arch_compare_and_exchange_64_val_acq(mem, newval, oldval) \ #define __arch_compare_and_exchange_val_64_acq(mem, newval, oldval) \
__sync_val_compare_and_swap_di ((long *) (mem), (long) (oldval), \ __sync_val_compare_and_swap_di ((long *) (mem), (long) (oldval), \
(long) (newval)) (long) (newval))

View File

@ -46,10 +46,10 @@ typedef intmax_t atomic_max_t;
typedef uintmax_t uatomic_max_t; typedef uintmax_t uatomic_max_t;
#define __arch_compare_and_exchange_8_acq(mem, newval, oldval) \ #define __arch_compare_and_exchange_bool_8_acq(mem, newval, oldval) \
(abort (), 0) (abort (), 0)
#define __arch_compare_and_exchange_16_acq(mem, newval, oldval) \ #define __arch_compare_and_exchange_bool_16_acq(mem, newval, oldval) \
(abort (), 0) (abort (), 0)
#ifdef UP #ifdef UP
@ -69,41 +69,41 @@ typedef uintmax_t uatomic_max_t;
* XXX this may not work properly on 64-bit if the register * XXX this may not work properly on 64-bit if the register
* containing oldval has the high half non-zero for some reason. * containing oldval has the high half non-zero for some reason.
*/ */
#define __arch_compare_and_exchange_32_acq(mem, newval, oldval) \ #define __arch_compare_and_exchange_bool_32_acq(mem, newval, oldval) \
({ \ ({ \
unsigned int __tmp; \ unsigned int __tmp; \
__asm __volatile (__ARCH_REL_INSTR "\n" \ __asm __volatile (__ARCH_REL_INSTR "\n" \
"1: lwarx %0,0,%1\n" \ "1: lwarx %0,0,%1\n" \
" subf. %0,%2,%0\n" \ " subf. %0,%2,%0\n" \
" bne 2f\n" \ " bne 2f\n" \
" stwcx. %3,0,%1\n" \ " stwcx. %3,0,%1\n" \
" bne- 1b\n" \ " bne- 1b\n" \
"2: " __ARCH_ACQ_INSTR \ "2: " __ARCH_ACQ_INSTR \
: "=&r" (__tmp) \ : "=&r" (__tmp) \
: "r" (mem), "r" (oldval), "r" (newval) \ : "r" (mem), "r" (oldval), "r" (newval) \
: "cr0", "memory"); \ : "cr0", "memory"); \
__tmp != 0; \ __tmp != 0; \
}) })
#ifdef __powerpc64__ #ifdef __powerpc64__
# define __arch_compare_and_exchange_64_acq(mem, newval, oldval)\ # define __arch_compare_and_exchange_bool_64_acq(mem, newval, oldval) \
({ \ ({ \
unsigned long __tmp; \ unsigned long __tmp; \
__asm __volatile (__ARCH_REL_INSTR "\n" \ __asm __volatile (__ARCH_REL_INSTR "\n" \
"1: ldarx %0,0,%1\n" \ "1: ldarx %0,0,%1\n" \
" subf. %0,%2,%0\n" \ " subf. %0,%2,%0\n" \
" bne 2f\n" \ " bne 2f\n" \
" stdcx. %3,0,%1\n" \ " stdcx. %3,0,%1\n" \
" bne- 1b\n" \ " bne- 1b\n" \
"2: " __ARCH_ACQ_INSTR \ "2: " __ARCH_ACQ_INSTR \
: "=&r" (__tmp) \ : "=&r" (__tmp) \
: "r" (mem), "r" (oldval), "r" (newval) \ : "r" (mem), "r" (oldval), "r" (newval) \
: "cr0", "memory"); \ : "cr0", "memory"); \
__tmp != 0; \ __tmp != 0; \
}) })
#else /* powerpc32 */ #else /* powerpc32 */
# define __arch_compare_and_exchange_64_acq(mem, newval, oldval) \ # define __arch_compare_and_exchange_bool_64_acq(mem, newval, oldval) \
(abort (), 0) (abort (), 0)
#endif #endif

View File

@ -45,13 +45,13 @@ typedef intmax_t atomic_max_t;
typedef uintmax_t uatomic_max_t; typedef uintmax_t uatomic_max_t;
#define __arch_compare_and_exchange_8_acq(mem, newval, oldval) \ #define __arch_compare_and_exchange_bool_8_acq(mem, newval, oldval) \
(abort (), 0) (abort (), 0)
#define __arch_compare_and_exchange_16_acq(mem, newval, oldval) \ #define __arch_compare_and_exchange_bool_16_acq(mem, newval, oldval) \
(abort (), 0) (abort (), 0)
#define __arch_compare_and_exchange_32_acq(mem, newval, oldval) \ #define __arch_compare_and_exchange_bool_32_acq(mem, newval, oldval) \
({ unsigned int *__mem = (unsigned int *) (mem); \ ({ unsigned int *__mem = (unsigned int *) (mem); \
unsigned int __old = (unsigned int) (oldval); \ unsigned int __old = (unsigned int) (oldval); \
unsigned int __cmp = __old; \ unsigned int __cmp = __old; \
@ -61,7 +61,7 @@ typedef uintmax_t uatomic_max_t;
__cmp != __old; }) __cmp != __old; })
#ifdef __s390x__ #ifdef __s390x__
# define __arch_compare_and_exchange_64_acq(mem, newval, oldval) \ # define __arch_compare_and_exchange_bool_64_acq(mem, newval, oldval) \
({ unsigned long int *__mem = (unsigned long int *) (mem); \ ({ unsigned long int *__mem = (unsigned long int *) (mem); \
unsigned long int __old = (unsigned long int) (oldval); \ unsigned long int __old = (unsigned long int) (oldval); \
unsigned long int __cmp = __old; \ unsigned long int __cmp = __old; \
@ -73,6 +73,6 @@ typedef uintmax_t uatomic_max_t;
/* For 31 bit we do not really need 64-bit compare-and-exchange. We can /* For 31 bit we do not really need 64-bit compare-and-exchange. We can
implement them by use of the csd instruction. The straightforward implement them by use of the csd instruction. The straightforward
implementation causes warnings so we skip the definition for now. */ implementation causes warnings so we skip the definition for now. */
# define __arch_compare_and_exchange_64_acq(mem, newval, oldval) \ # define __arch_compare_and_exchange_bool_64_acq(mem, newval, oldval) \
(abort (), 0) (abort (), 0)
#endif #endif

View File

@ -85,7 +85,7 @@ get_proc_path (char *buffer, size_t bufsize)
/* Now store the copied value. But do it atomically. */ /* Now store the copied value. But do it atomically. */
assert (sizeof (long int) == sizeof (void *__unbounded)); assert (sizeof (long int) == sizeof (void *__unbounded));
if (atomic_compare_and_exchange_acq (&mount_proc, copy_result, NULL) == 0) if (! atomic_compare_and_exchange_bool_acq (&mount_proc, copy_result, NULL))
/* Replacing the value failed. This means another thread was /* Replacing the value failed. This means another thread was
faster and we don't need the copy anymore. */ faster and we don't need the copy anymore. */
free (copy_result); free (copy_result);

View File

@ -55,29 +55,29 @@ typedef uintmax_t uatomic_max_t;
#endif #endif
#define __arch_compare_and_exchange_8_acq(mem, newval, oldval) \ #define __arch_compare_and_exchange_val_8_acq(mem, newval, oldval) \
({ unsigned char ret; \ ({ __typeof (*mem) ret; \
__asm __volatile (LOCK "cmpxchgb %b2, %1; setne %0" \ __asm __volatile (LOCK "cmpxchgb %b2, %1; setne %0" \
: "=a" (ret), "=m" (*mem) \ : "=a" (ret), "=m" (*mem) \
: "q" (newval), "1" (*mem), "0" (oldval)); \ : "q" (newval), "1" (*mem), "0" (oldval)); \
ret; }) ret; })
#define __arch_compare_and_exchange_16_acq(mem, newval, oldval) \ #define __arch_compare_and_exchange_val_16_acq(mem, newval, oldval) \
({ unsigned char ret; \ ({ __typeof (*mem) ret; \
__asm __volatile (LOCK "cmpxchgw %w2, %1; setne %0" \ __asm __volatile (LOCK "cmpxchgw %w2, %1; setne %0" \
: "=a" (ret), "=m" (*mem) \ : "=a" (ret), "=m" (*mem) \
: "r" (newval), "1" (*mem), "0" (oldval)); \ : "r" (newval), "1" (*mem), "0" (oldval)); \
ret; }) ret; })
#define __arch_compare_and_exchange_32_acq(mem, newval, oldval) \ #define __arch_compare_and_exchange_val_32_acq(mem, newval, oldval) \
({ unsigned char ret; \ ({ __typeof (*mem) ret; \
__asm __volatile (LOCK "cmpxchgl %2, %1; setne %0" \ __asm __volatile (LOCK "cmpxchgl %2, %1; setne %0" \
: "=a" (ret), "=m" (*mem) \ : "=a" (ret), "=m" (*mem) \
: "r" (newval), "1" (*mem), "0" (oldval)); \ : "r" (newval), "1" (*mem), "0" (oldval)); \
ret; }) ret; })
#define __arch_compare_and_exchange_64_acq(mem, newval, oldval) \ #define __arch_compare_and_exchange_val_64_acq(mem, newval, oldval) \
({ unsigned char ret; \ ({ __typeof (*mem) ret; \
__asm __volatile (LOCK "cmpxchgq %q2, %1; setne %0" \ __asm __volatile (LOCK "cmpxchgq %q2, %1; setne %0" \
: "=a" (ret), "=m" (*mem) \ : "=a" (ret), "=m" (*mem) \
: "r" (newval), "1" (*mem), "0" (oldval)); \ : "r" (newval), "1" (*mem), "0" (oldval)); \