2006-10-17  Jakub Jelinek  <jakub@redhat.com>
	* sunrpc/xdr_mem.c (xdrmem_setpos): Don't compare addresses
	as signed longs, check for x_base + pos overflow.
	* sunrpc/Makefile (tests): Add tst-xdrmem2.
	* sunrpc/tst-xdrmem2.c: New test.

2006-10-18  Ulrich Drepper  <drepper@redhat.com>

	* elf/dl-lookup.c (_dl_lookup_symbol_x): Add warning to
	_dl_lookup_symbol_x code.

2006-10-17  Jakub Jelinek  <jakub@redhat.com>

	* elf/dl-runtime.c: Include sysdep-cancel.h.
	(_dl_fixup, _dl_profile_fixup): Use __rtld_mrlock_* and
	scoperec->nusers only if !SINGLE_THREAD_P.  Use atomic_*
	instead of catomic_* macros.
	* elf/dl-sym.c: Include sysdep-cancel.h.
	(do_sym): Use __rtld_mrlock_* and scoperec->nusers only
	if !SINGLE_THREAD_P.  Use atomic_* instead of catomic_* macros.
	* elf/dl-close.c: Include sysdep-cancel.h.
	(_dl_close): Use __rtld_mrlock_* and scoperec->nusers only
	if !SINGLE_THREAD_P.  Use atomic_* instead of catomic_* macros.
	* elf/dl-open.c: Include sysdep-cancel.h.
	(dl_open_worker): Use __rtld_mrlock_* and scoperec->nusers only
	if !SINGLE_THREAD_P.  Use atomic_* instead of catomic_* macros.

2006-10-17  Jakub Jelinek  <jakub@redhat.com>

	[BZ #3313]
	* malloc/malloc.c (malloc_consolidate): Set maxfb to address of last
	fastbin rather than end of fastbin array.

2006-10-18  Ulrich Drepper  <drepper@redhat.com>

	* sysdeps/i386/i486/bits/atomic.h (catomic_decrement): Use correct
	body macro.
	* sysdeps/x86_64/bits/atomic.h
	(__arch_c_compare_and_exchange_val_64_acq): Add missing casts.
	(catomic_decrement): Use correct body macro.

2006-10-17  Jakub Jelinek  <jakub@redhat.com>

	* include/atomic.h: Add a unique prefix to all local variables
	in macros.
	* csu/tst-atomic.c (do_test): Test also catomic_* macros.

	* include/link.h: Include <rtld-lowlevel.h>.  Define struct
This commit is contained in:
Ulrich Drepper 2006-10-18 19:26:30 +00:00
parent 4a85a8ee31
commit 609cf61467
16 changed files with 491 additions and 193 deletions

View File

@ -1,3 +1,51 @@
2006-10-17 Jakub Jelinek <jakub@redhat.com>
* sunrpc/xdr_mem.c (xdrmem_setpos): Don't compare addresses
as signed longs, check for x_base + pos overflow.
* sunrpc/Makefile (tests): Add tst-xdrmem2.
* sunrpc/tst-xdrmem2.c: New test.
2006-10-18 Ulrich Drepper <drepper@redhat.com>
* elf/dl-lookup.c (_dl_lookup_symbol_x): Add warning to
_dl_lookup_symbol_x code.
2006-10-17 Jakub Jelinek <jakub@redhat.com>
* elf/dl-runtime.c: Include sysdep-cancel.h.
(_dl_fixup, _dl_profile_fixup): Use __rtld_mrlock_* and
scoperec->nusers only if !SINGLE_THREAD_P. Use atomic_*
instead of catomic_* macros.
* elf/dl-sym.c: Include sysdep-cancel.h.
(do_sym): Use __rtld_mrlock_* and scoperec->nusers only
if !SINGLE_THREAD_P. Use atomic_* instead of catomic_* macros.
* elf/dl-close.c: Include sysdep-cancel.h.
(_dl_close): Use __rtld_mrlock_* and scoperec->nusers only
if !SINGLE_THREAD_P. Use atomic_* instead of catomic_* macros.
* elf/dl-open.c: Include sysdep-cancel.h.
(dl_open_worker): Use __rtld_mrlock_* and scoperec->nusers only
if !SINGLE_THREAD_P. Use atomic_* instead of catomic_* macros.
2006-10-17 Jakub Jelinek <jakub@redhat.com>
[BZ #3313]
* malloc/malloc.c (malloc_consolidate): Set maxfb to address of last
fastbin rather than end of fastbin array.
2006-10-18 Ulrich Drepper <drepper@redhat.com>
* sysdeps/i386/i486/bits/atomic.h (catomic_decrement): Use correct
body macro.
* sysdeps/x86_64/bits/atomic.h
(__arch_c_compare_and_exchange_val_64_acq): Add missing casts.
(catomic_decrement): Use correct body macro.
2006-10-17 Jakub Jelinek <jakub@redhat.com>
* include/atomic.h: Add a unique prefix to all local variables
in macros.
* csu/tst-atomic.c (do_test): Test also catomic_* macros.
2006-10-16 Ulrich Drepper <drepper@redhat.com>
[BZ #3369]
@ -108,7 +156,7 @@
* elf/dl-load.c: Likewise.
* elf/dl-object.c: Likewise.
* elf/rtld.c: Likewise.
* include/link.h: Inlcude <rtld-lowlevel.h>. Define struct
* include/link.h: Include <rtld-lowlevel.h>. Define struct
r_scoperec. Replace r_scope with pointer to r_scoperec structure.
Add l_scoperec_lock.
* sysdeps/generic/ldsodefs.h: Include <rtld-lowlevel.h>.

View File

@ -1,5 +1,5 @@
/* Tests for atomic.h macros.
Copyright (C) 2003, 2004 Free Software Foundation, Inc.
Copyright (C) 2003, 2004, 2006 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
@ -379,6 +379,117 @@ do_test (void)
}
#endif
#ifdef catomic_compare_and_exchange_val_acq
mem = 24;
if (catomic_compare_and_exchange_val_acq (&mem, 35, 24) != 24
|| mem != 35)
{
puts ("catomic_compare_and_exchange_val_acq test 1 failed");
ret = 1;
}
mem = 12;
if (catomic_compare_and_exchange_val_acq (&mem, 10, 15) != 12
|| mem != 12)
{
puts ("catomic_compare_and_exchange_val_acq test 2 failed");
ret = 1;
}
mem = -15;
if (catomic_compare_and_exchange_val_acq (&mem, -56, -15) != -15
|| mem != -56)
{
puts ("catomic_compare_and_exchange_val_acq test 3 failed");
ret = 1;
}
mem = -1;
if (catomic_compare_and_exchange_val_acq (&mem, 17, 0) != -1
|| mem != -1)
{
puts ("catomic_compare_and_exchange_val_acq test 4 failed");
ret = 1;
}
#endif
mem = 24;
if (catomic_compare_and_exchange_bool_acq (&mem, 35, 24)
|| mem != 35)
{
puts ("catomic_compare_and_exchange_bool_acq test 1 failed");
ret = 1;
}
mem = 12;
if (! catomic_compare_and_exchange_bool_acq (&mem, 10, 15)
|| mem != 12)
{
puts ("catomic_compare_and_exchange_bool_acq test 2 failed");
ret = 1;
}
mem = -15;
if (catomic_compare_and_exchange_bool_acq (&mem, -56, -15)
|| mem != -56)
{
puts ("catomic_compare_and_exchange_bool_acq test 3 failed");
ret = 1;
}
mem = -1;
if (! catomic_compare_and_exchange_bool_acq (&mem, 17, 0)
|| mem != -1)
{
puts ("catomic_compare_and_exchange_bool_acq test 4 failed");
ret = 1;
}
mem = 2;
if (catomic_exchange_and_add (&mem, 11) != 2
|| mem != 13)
{
puts ("catomic_exchange_and_add test failed");
ret = 1;
}
mem = -21;
catomic_add (&mem, 22);
if (mem != 1)
{
puts ("catomic_add test failed");
ret = 1;
}
mem = -1;
catomic_increment (&mem);
if (mem != 0)
{
puts ("catomic_increment test failed");
ret = 1;
}
mem = 2;
if (catomic_increment_val (&mem) != 3)
{
puts ("catomic_increment_val test failed");
ret = 1;
}
mem = 17;
catomic_decrement (&mem);
if (mem != 16)
{
puts ("catomic_decrement test failed");
ret = 1;
}
if (catomic_decrement_val (&mem) != 15)
{
puts ("catomic_decrement_val test failed");
ret = 1;
}
return ret;
}

View File

@ -30,6 +30,7 @@
#include <ldsodefs.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <sysdep-cancel.h>
/* Type of the constructor functions. */
@ -419,16 +420,21 @@ _dl_close (void *_map)
struct r_scoperec *old = imap->l_scoperec;
__rtld_mrlock_change (imap->l_scoperec_lock);
imap->l_scoperec = newp;
__rtld_mrlock_done (imap->l_scoperec_lock);
if (catomic_increment_val (&old->nusers) != 1)
if (SINGLE_THREAD_P)
imap->l_scoperec = newp;
else
{
old->remove_after_use = true;
old->notify = true;
if (catomic_decrement_val (&old->nusers) != 0)
__rtld_waitzero (old->nusers);
__rtld_mrlock_change (imap->l_scoperec_lock);
imap->l_scoperec = newp;
__rtld_mrlock_done (imap->l_scoperec_lock);
if (atomic_increment_val (&old->nusers) != 1)
{
old->remove_after_use = true;
old->notify = true;
if (atomic_decrement_val (&old->nusers) != 0)
__rtld_waitzero (old->nusers);
}
}
/* No user anymore, we can free it now. */

View File

@ -207,7 +207,11 @@ _dl_debug_bindings (const char *undef_name, struct link_map *undef_map,
/* Search loaded objects' symbol tables for a definition of the symbol
UNDEF_NAME, perhaps with a requested version for the symbol. */
UNDEF_NAME, perhaps with a requested version for the symbol.
We must never have calls to the audit functions inside this function
or in any function which gets called. If this would happen the audit
code might create a thread which can throw off all the scope locking. */
lookup_t
internal_function
_dl_lookup_symbol_x (const char *undef_name, struct link_map *undef_map,

View File

@ -31,6 +31,7 @@
#include <ldsodefs.h>
#include <bp-sym.h>
#include <caller.h>
#include <sysdep-cancel.h>
#include <dl-dst.h>
@ -423,15 +424,20 @@ dl_open_worker (void *a)
if (old == &imap->l_scoperec_mem)
imap->l_scoperec = newp;
else if (SINGLE_THREAD_P)
{
imap->l_scoperec = newp;
free (old);
}
else
{
__rtld_mrlock_change (imap->l_scoperec_lock);
imap->l_scoperec = newp;
__rtld_mrlock_done (imap->l_scoperec_lock);
catomic_increment (&old->nusers);
atomic_increment (&old->nusers);
old->remove_after_use = true;
if (catomic_decrement_val (&old->nusers) == 0)
if (atomic_decrement_val (&old->nusers) == 0)
/* No user, we can free it here and now. */
free (old);
}

View File

@ -24,6 +24,7 @@
#include <unistd.h>
#include <sys/param.h>
#include <ldsodefs.h>
#include <sysdep-cancel.h>
#include "dynamic-link.h"
#if (!defined ELF_MACHINE_NO_RELA && !defined ELF_MACHINE_PLT_REL) \
@ -93,11 +94,11 @@ _dl_fixup (
}
struct r_scoperec *scoperec = l->l_scoperec;
if (l->l_type == lt_loaded)
if (l->l_type == lt_loaded && !SINGLE_THREAD_P)
{
__rtld_mrlock_lock (l->l_scoperec_lock);
scoperec = l->l_scoperec;
catomic_increment (&scoperec->nusers);
atomic_increment (&scoperec->nusers);
__rtld_mrlock_unlock (l->l_scoperec_lock);
}
@ -106,8 +107,8 @@ _dl_fixup (
ELF_RTYPE_CLASS_PLT,
DL_LOOKUP_ADD_DEPENDENCY, NULL);
if (l->l_type == lt_loaded
&& catomic_decrement_val (&scoperec->nusers) == 0
if (l->l_type == lt_loaded && !SINGLE_THREAD_P
&& atomic_decrement_val (&scoperec->nusers) == 0
&& __builtin_expect (scoperec->remove_after_use, 0))
{
if (scoperec->notify)
@ -195,11 +196,11 @@ _dl_profile_fixup (
}
struct r_scoperec *scoperec = l->l_scoperec;
if (l->l_type == lt_loaded)
if (l->l_type == lt_loaded && !SINGLE_THREAD_P)
{
__rtld_mrlock_lock (l->l_scoperec_lock);
scoperec = l->l_scoperec;
catomic_increment (&scoperec->nusers);
atomic_increment (&scoperec->nusers);
__rtld_mrlock_unlock (l->l_scoperec_lock);
}
@ -208,8 +209,8 @@ _dl_profile_fixup (
ELF_RTYPE_CLASS_PLT,
DL_LOOKUP_ADD_DEPENDENCY, NULL);
if (l->l_type == lt_loaded
&& catomic_decrement_val (&scoperec->nusers) == 0
if (l->l_type == lt_loaded && !SINGLE_THREAD_P
&& atomic_decrement_val (&scoperec->nusers) == 0
&& __builtin_expect (scoperec->remove_after_use, 0))
{
if (scoperec->notify)

View File

@ -25,6 +25,7 @@
#include <dlfcn.h>
#include <ldsodefs.h>
#include <dl-hash.h>
#include <sysdep-cancel.h>
#ifdef USE_TLS
# include <dl-tls.h>
#endif
@ -115,7 +116,7 @@ do_sym (void *handle, const char *name, void *who,
the initial binary. And then the more complex part
where the object is dynamically loaded and the scope
array can change. */
if (match->l_type != lt_loaded)
if (match->l_type != lt_loaded || SINGLE_THREAD_P)
result = GLRO(dl_lookup_symbol_x) (name, match, &ref,
match->l_scoperec->scope, vers, 0,
flags | DL_LOOKUP_ADD_DEPENDENCY,
@ -124,7 +125,7 @@ do_sym (void *handle, const char *name, void *who,
{
__rtld_mrlock_lock (match->l_scoperec_lock);
struct r_scoperec *scoperec = match->l_scoperec;
catomic_increment (&scoperec->nusers);
atomic_increment (&scoperec->nusers);
__rtld_mrlock_unlock (match->l_scoperec_lock);
struct call_dl_lookup_args args;
@ -141,7 +142,7 @@ do_sym (void *handle, const char *name, void *who,
int err = GLRO(dl_catch_error) (&objname, &errstring, &malloced,
call_dl_lookup, &args);
if (catomic_decrement_val (&scoperec->nusers) == 0
if (atomic_decrement_val (&scoperec->nusers) == 0
&& __builtin_expect (scoperec->remove_after_use, 0))
{
if (scoperec->notify)

View File

@ -39,7 +39,12 @@
Architectures must provide a few lowlevel macros (the compare
and exchange definitions). All others are optional. They
should only be provided if the architecture has specific
support for the operation. */
support for the operation.
As <atomic.h> macros are usually heavily nested and often use local
variables to make sure side-effects are evaluated properly, use for
macro local variables a per-macro unique prefix. This file uses
__atgN_ prefix where N is different in each macro. */
#include <stdlib.h>
@ -50,33 +55,33 @@
and following args. */
#define __atomic_val_bysize(pre, post, mem, ...) \
({ \
__typeof (*mem) __result; \
__typeof (*mem) __atg1_result; \
if (sizeof (*mem) == 1) \
__result = pre##_8_##post (mem, __VA_ARGS__); \
__atg1_result = pre##_8_##post (mem, __VA_ARGS__); \
else if (sizeof (*mem) == 2) \
__result = pre##_16_##post (mem, __VA_ARGS__); \
__atg1_result = pre##_16_##post (mem, __VA_ARGS__); \
else if (sizeof (*mem) == 4) \
__result = pre##_32_##post (mem, __VA_ARGS__); \
__atg1_result = pre##_32_##post (mem, __VA_ARGS__); \
else if (sizeof (*mem) == 8) \
__result = pre##_64_##post (mem, __VA_ARGS__); \
__atg1_result = pre##_64_##post (mem, __VA_ARGS__); \
else \
abort (); \
__result; \
__atg1_result; \
})
#define __atomic_bool_bysize(pre, post, mem, ...) \
({ \
int __result; \
int __atg2_result; \
if (sizeof (*mem) == 1) \
__result = pre##_8_##post (mem, __VA_ARGS__); \
__atg2_result = pre##_8_##post (mem, __VA_ARGS__); \
else if (sizeof (*mem) == 2) \
__result = pre##_16_##post (mem, __VA_ARGS__); \
__atg2_result = pre##_16_##post (mem, __VA_ARGS__); \
else if (sizeof (*mem) == 4) \
__result = pre##_32_##post (mem, __VA_ARGS__); \
__atg2_result = pre##_32_##post (mem, __VA_ARGS__); \
else if (sizeof (*mem) == 8) \
__result = pre##_64_##post (mem, __VA_ARGS__); \
__atg2_result = pre##_64_##post (mem, __VA_ARGS__); \
else \
abort (); \
__result; \
__atg2_result; \
})
@ -124,8 +129,9 @@
# define atomic_compare_and_exchange_bool_acq(mem, newval, oldval) \
({ /* Cannot use __oldval here, because macros later in this file might \
call this macro with __oldval argument. */ \
__typeof (oldval) __old = (oldval); \
atomic_compare_and_exchange_val_acq (mem, newval, __old) != __old; \
__typeof (oldval) __atg3_old = (oldval); \
atomic_compare_and_exchange_val_acq (mem, newval, __atg3_old) \
!= __atg3_old; \
})
# endif
#endif
@ -140,8 +146,9 @@
# define catomic_compare_and_exchange_bool_acq(mem, newval, oldval) \
({ /* Cannot use __oldval here, because macros later in this file might \
call this macro with __oldval argument. */ \
__typeof (oldval) __old = (oldval); \
catomic_compare_and_exchange_val_acq (mem, newval, __old) != __old; \
__typeof (oldval) __atg4_old = (oldval); \
catomic_compare_and_exchange_val_acq (mem, newval, __atg4_old) \
!= __atg4_old; \
})
# endif
#endif
@ -162,18 +169,17 @@
/* Store NEWVALUE in *MEM and return the old value. */
#ifndef atomic_exchange_acq
# define atomic_exchange_acq(mem, newvalue) \
({ __typeof (*(mem)) __oldval; \
__typeof (mem) __memp = (mem); \
__typeof (*(mem)) __value = (newvalue); \
({ __typeof (*(mem)) __atg5_oldval; \
__typeof (mem) __atg5_memp = (mem); \
__typeof (*(mem)) __atg5_value = (newvalue); \
\
do \
__oldval = *__memp; \
while (__builtin_expect (atomic_compare_and_exchange_bool_acq (__memp, \
__value, \
__oldval),\
0)); \
__atg5_oldval = *__atg5_memp; \
while (__builtin_expect \
(atomic_compare_and_exchange_bool_acq (__atg5_memp, __atg5_value, \
__atg5_oldval), 0)); \
\
__oldval; })
__atg5_oldval; })
#endif
#ifndef atomic_exchange_rel
@ -184,54 +190,53 @@
/* Add VALUE to *MEM and return the old value of *MEM. */
#ifndef atomic_exchange_and_add
# define atomic_exchange_and_add(mem, value) \
({ __typeof (*(mem)) __oldval; \
__typeof (mem) __memp = (mem); \
__typeof (*(mem)) __value = (value); \
({ __typeof (*(mem)) __atg6_oldval; \
__typeof (mem) __atg6_memp = (mem); \
__typeof (*(mem)) __atg6_value = (value); \
\
do \
__oldval = *__memp; \
while (__builtin_expect (atomic_compare_and_exchange_bool_acq (__memp, \
__oldval \
+ __value,\
__oldval),\
0)); \
__atg6_oldval = *__atg6_memp; \
while (__builtin_expect \
(atomic_compare_and_exchange_bool_acq (__atg6_memp, \
__atg6_oldval \
+ __atg6_value, \
__atg6_oldval), 0)); \
\
__oldval; })
__atg6_oldval; })
#endif
#ifndef catomic_exchange_and_add
# define catomic_exchange_and_add(mem, value) \
({ __typeof (*(mem)) __oldv; \
__typeof (mem) __memp = (mem); \
__typeof (*(mem)) __value = (value); \
({ __typeof (*(mem)) __atg7_oldv; \
__typeof (mem) __atg7_memp = (mem); \
__typeof (*(mem)) __atg7_value = (value); \
\
do \
__oldv = *__memp; \
while (__builtin_expect (catomic_compare_and_exchange_bool_acq (__memp, \
__oldv \
+ __value,\
__oldv), \
0)); \
__atg7_oldv = *__atg7_memp; \
while (__builtin_expect \
(catomic_compare_and_exchange_bool_acq (__atg7_memp, \
__atg7_oldv \
+ __atg7_value, \
__atg7_oldv), 0)); \
\
__oldv; })
__atg7_oldv; })
#endif
#ifndef atomic_max
# define atomic_max(mem, value) \
do { \
__typeof (*(mem)) __oldval; \
__typeof (mem) __memp = (mem); \
__typeof (*(mem)) __value = (value); \
__typeof (*(mem)) __atg8_oldval; \
__typeof (mem) __atg8_memp = (mem); \
__typeof (*(mem)) __atg8_value = (value); \
do { \
__oldval = *__memp; \
if (__oldval >= __value) \
__atg8_oldval = *__atg8_memp; \
if (__atg8_oldval >= __atg8_value) \
break; \
} while (__builtin_expect (atomic_compare_and_exchange_bool_acq (__memp, \
__value, \
__oldval),\
0)); \
} while (__builtin_expect \
(atomic_compare_and_exchange_bool_acq (__atg8_memp, __atg8_value,\
__atg8_oldval), 0)); \
} while (0)
#endif
@ -239,17 +244,17 @@
#ifndef catomic_max
# define catomic_max(mem, value) \
do { \
__typeof (*(mem)) __oldv; \
__typeof (mem) __memp = (mem); \
__typeof (*(mem)) __value = (value); \
__typeof (*(mem)) __atg9_oldv; \
__typeof (mem) __atg9_memp = (mem); \
__typeof (*(mem)) __atg9_value = (value); \
do { \
__oldv = *__memp; \
if (__oldv >= __value) \
__atg9_oldv = *__atg9_memp; \
if (__atg9_oldv >= __atg9_value) \
break; \
} while (__builtin_expect (catomic_compare_and_exchange_bool_acq (__memp, \
__value,\
__oldv),\
0)); \
} while (__builtin_expect \
(catomic_compare_and_exchange_bool_acq (__atg9_memp, \
__atg9_value, \
__atg9_oldv), 0)); \
} while (0)
#endif
@ -257,17 +262,17 @@
#ifndef atomic_min
# define atomic_min(mem, value) \
do { \
__typeof (*(mem)) __oldval; \
__typeof (mem) __memp = (mem); \
__typeof (*(mem)) __value = (value); \
__typeof (*(mem)) __atg10_oldval; \
__typeof (mem) __atg10_memp = (mem); \
__typeof (*(mem)) __atg10_value = (value); \
do { \
__oldval = *__memp; \
if (__oldval <= __value) \
__atg10_oldval = *__atg10_memp; \
if (__atg10_oldval <= __atg10_value) \
break; \
} while (__builtin_expect (atomic_compare_and_exchange_bool_acq (__memp, \
__value, \
__oldval),\
0)); \
} while (__builtin_expect \
(atomic_compare_and_exchange_bool_acq (__atg10_memp, \
__atg10_value, \
__atg10_oldval), 0)); \
} while (0)
#endif
@ -340,35 +345,34 @@
/* Decrement *MEM if it is > 0, and return the old value. */
#ifndef atomic_decrement_if_positive
# define atomic_decrement_if_positive(mem) \
({ __typeof (*(mem)) __oldval; \
__typeof (mem) __memp = (mem); \
({ __typeof (*(mem)) __atg11_oldval; \
__typeof (mem) __atg11_memp = (mem); \
\
do \
{ \
__oldval = *__memp; \
if (__builtin_expect (__oldval <= 0, 0)) \
__atg11_oldval = *__atg11_memp; \
if (__builtin_expect (__atg11_oldval <= 0, 0)) \
break; \
} \
while (__builtin_expect (atomic_compare_and_exchange_bool_acq (__memp, \
__oldval \
- 1, \
__oldval),\
0));\
__oldval; })
while (__builtin_expect \
(atomic_compare_and_exchange_bool_acq (__atg11_memp, \
__atg11_oldval - 1, \
__atg11_oldval), 0)); \
__atg11_oldval; })
#endif
#ifndef atomic_add_negative
# define atomic_add_negative(mem, value) \
({ __typeof (value) __aan_value = (value); \
atomic_exchange_and_add (mem, __aan_value) < -__aan_value; })
({ __typeof (value) __atg12_value = (value); \
atomic_exchange_and_add (mem, __atg12_value) < -__atg12_value; })
#endif
#ifndef atomic_add_zero
# define atomic_add_zero(mem, value) \
({ __typeof (value) __aaz_value = (value); \
atomic_exchange_and_add (mem, __aaz_value) == -__aaz_value; })
({ __typeof (value) __atg13_value = (value); \
atomic_exchange_and_add (mem, __atg13_value) == -__atg13_value; })
#endif
@ -380,108 +384,102 @@
#ifndef atomic_bit_test_set
# define atomic_bit_test_set(mem, bit) \
({ __typeof (*(mem)) __oldval; \
__typeof (mem) __memp = (mem); \
__typeof (*(mem)) __mask = ((__typeof (*(mem))) 1 << (bit)); \
({ __typeof (*(mem)) __atg14_old; \
__typeof (mem) __atg14_memp = (mem); \
__typeof (*(mem)) __atg14_mask = ((__typeof (*(mem))) 1 << (bit)); \
\
do \
__oldval = (*__memp); \
while (__builtin_expect (atomic_compare_and_exchange_bool_acq (__memp, \
__oldval \
| __mask, \
__oldval),\
0)); \
__atg14_old = (*__atg14_memp); \
while (__builtin_expect \
(atomic_compare_and_exchange_bool_acq (__atg14_memp, \
__atg14_old | __atg14_mask,\
__atg14_old), 0)); \
\
__oldval & __mask; })
__atg14_old & __atg14_mask; })
#endif
/* Atomically *mem &= mask. */
#ifndef atomic_and
# define atomic_and(mem, mask) \
do { \
__typeof (*(mem)) __oldval; \
__typeof (mem) __memp = (mem); \
__typeof (*(mem)) __mask = (mask); \
__typeof (*(mem)) __atg15_old; \
__typeof (mem) __atg15_memp = (mem); \
__typeof (*(mem)) __atg15_mask = (mask); \
\
do \
__oldval = (*__memp); \
while (__builtin_expect (atomic_compare_and_exchange_bool_acq (__memp, \
__oldval \
& __mask, \
__oldval), \
0)); \
__atg15_old = (*__atg15_memp); \
while (__builtin_expect \
(atomic_compare_and_exchange_bool_acq (__atg15_memp, \
__atg15_old & __atg15_mask, \
__atg15_old), 0)); \
} while (0)
#endif
/* Atomically *mem &= mask and return the old value of *mem. */
#ifndef atomic_and_val
# define atomic_and_val(mem, mask) \
({ __typeof (*(mem)) __oldval; \
__typeof (mem) __memp = (mem); \
__typeof (*(mem)) __mask = (mask); \
({ __typeof (*(mem)) __atg16_old; \
__typeof (mem) __atg16_memp = (mem); \
__typeof (*(mem)) __atg16_mask = (mask); \
\
do \
__oldval = (*__memp); \
while (__builtin_expect (atomic_compare_and_exchange_bool_acq (__memp, \
__oldval \
& __mask, \
__oldval),\
0)); \
__atg16_old = (*__atg16_memp); \
while (__builtin_expect \
(atomic_compare_and_exchange_bool_acq (__atg16_memp, \
__atg16_old & __atg16_mask,\
__atg16_old), 0)); \
\
__oldval; })
__atg16_old; })
#endif
/* Atomically *mem |= mask and return the old value of *mem. */
#ifndef atomic_or
# define atomic_or(mem, mask) \
do { \
__typeof (*(mem)) __oldval; \
__typeof (mem) __memp = (mem); \
__typeof (*(mem)) __mask = (mask); \
__typeof (*(mem)) __atg17_old; \
__typeof (mem) __atg17_memp = (mem); \
__typeof (*(mem)) __atg17_mask = (mask); \
\
do \
__oldval = (*__memp); \
while (__builtin_expect (atomic_compare_and_exchange_bool_acq (__memp, \
__oldval \
| __mask, \
__oldval), \
0)); \
__atg17_old = (*__atg17_memp); \
while (__builtin_expect \
(atomic_compare_and_exchange_bool_acq (__atg17_memp, \
__atg17_old | __atg17_mask, \
__atg17_old), 0)); \
} while (0)
#endif
#ifndef catomic_or
# define catomic_or(mem, mask) \
do { \
__typeof (*(mem)) __oldval; \
__typeof (mem) __memp = (mem); \
__typeof (*(mem)) __mask = (mask); \
__typeof (*(mem)) __atg18_old; \
__typeof (mem) __atg18_memp = (mem); \
__typeof (*(mem)) __atg18_mask = (mask); \
\
do \
__oldval = (*__memp); \
while (__builtin_expect (catomic_compare_and_exchange_bool_acq (__memp, \
__oldval \
| __mask, \
__oldval),\
0)); \
__atg18_old = (*__atg18_memp); \
while (__builtin_expect \
(catomic_compare_and_exchange_bool_acq (__atg18_memp, \
__atg18_old | __atg18_mask,\
__atg18_old), 0)); \
} while (0)
#endif
/* Atomically *mem |= mask and return the old value of *mem. */
#ifndef atomic_or_val
# define atomic_or_val(mem, mask) \
({ __typeof (*(mem)) __oldval; \
__typeof (mem) __memp = (mem); \
__typeof (*(mem)) __mask = (mask); \
({ __typeof (*(mem)) __atg19_old; \
__typeof (mem) __atg19_memp = (mem); \
__typeof (*(mem)) __atg19_mask = (mask); \
\
do \
__oldval = (*__memp); \
while (__builtin_expect (atomic_compare_and_exchange_bool_acq (__memp, \
__oldval \
| __mask, \
__oldval),\
0)); \
__atg19_old = (*__atg19_memp); \
while (__builtin_expect \
(atomic_compare_and_exchange_bool_acq (__atg19_memp, \
__atg19_old | __atg19_mask,\
__atg19_old), 0)); \
\
__oldval; })
__atg19_old; })
#endif
#ifndef atomic_full_barrier

View File

@ -4699,7 +4699,7 @@ static void malloc_consolidate(av) mstate av;
search all bins all the time. */
maxfb = &(av->fastbins[fastbin_index(get_max_fast ())]);
#else
maxfb = &(av->fastbins[NFASTBINS]);
maxfb = &(av->fastbins[NFASTBINS - 1]);
#endif
fb = &(av->fastbins[0]);
do {

View File

@ -1,3 +1,9 @@
2006-10-17 Jakub Jelinek <jakub@redhat.com>
* sysdeps/unix/sysv/linux/rtld-lowlevel.h (__rtld_mrlock_lock,
__rtld_mrlock_unlock, __rtld_mrlock_change, __rtld_mrlock_done): Use
atomic_* instead of catomic_* macros.
2006-10-12 Ulrich Drepper <drepper@redhat.com>
[BZ #3285]

View File

@ -62,9 +62,9 @@ typedef int __rtld_mrlock_t;
{ \
int newval = ((oldval & __RTLD_MRLOCK_RBITS) \
+ __RTLD_MRLOCK_INC); \
int ret = catomic_compare_and_exchange_val_acq (&(lock), \
newval, \
oldval); \
int ret = atomic_compare_and_exchange_val_acq (&(lock), \
newval, \
oldval); \
if (__builtin_expect (ret == oldval, 1)) \
goto out; \
} \
@ -72,7 +72,7 @@ typedef int __rtld_mrlock_t;
} \
if ((oldval & __RTLD_MRLOCK_RWAIT) == 0) \
{ \
catomic_or (&(lock), __RTLD_MRLOCK_RWAIT); \
atomic_or (&(lock), __RTLD_MRLOCK_RWAIT); \
oldval |= __RTLD_MRLOCK_RWAIT; \
} \
lll_futex_wait (lock, oldval); \
@ -83,7 +83,7 @@ typedef int __rtld_mrlock_t;
#define __rtld_mrlock_unlock(lock) \
do { \
int oldval = catomic_exchange_and_add (&(lock), -__RTLD_MRLOCK_INC); \
int oldval = atomic_exchange_and_add (&(lock), -__RTLD_MRLOCK_INC); \
if (__builtin_expect ((oldval \
& (__RTLD_MRLOCK_RBITS | __RTLD_MRLOCK_WWAIT)) \
== (__RTLD_MRLOCK_INC | __RTLD_MRLOCK_WWAIT), 0)) \
@ -103,11 +103,11 @@ typedef int __rtld_mrlock_t;
for (int tries = 0; tries < __RTLD_MRLOCK_TRIES; ++tries) \
{ \
oldval = lock; \
while (__builtin_expect ((oldval & __RTLD_MRLOCK_RBITS) == 0, 1))\
while (__builtin_expect ((oldval & __RTLD_MRLOCK_RBITS) == 0, 1)) \
{ \
int newval = ((oldval & __RTLD_MRLOCK_RWAIT) \
+ __RTLD_MRLOCK_WRITER); \
int ret = catomic_compare_and_exchange_val_acq (&(lock), \
int ret = atomic_compare_and_exchange_val_acq (&(lock), \
newval, \
oldval); \
if (__builtin_expect (ret == oldval, 1)) \
@ -115,7 +115,7 @@ typedef int __rtld_mrlock_t;
} \
atomic_delay (); \
} \
catomic_or (&(lock), __RTLD_MRLOCK_WWAIT); \
atomic_or (&(lock), __RTLD_MRLOCK_WWAIT); \
oldval |= __RTLD_MRLOCK_WWAIT; \
lll_futex_wait (lock, oldval); \
} \
@ -125,7 +125,7 @@ typedef int __rtld_mrlock_t;
#define __rtld_mrlock_done(lock) \
do { \
int oldval = catomic_exchange_and_add (&(lock), -__RTLD_MRLOCK_WRITER); \
int oldval = atomic_exchange_and_add (&(lock), -__RTLD_MRLOCK_WRITER); \
if (__builtin_expect ((oldval & __RTLD_MRLOCK_RWAIT) != 0, 0)) \
lll_futex_wake (&(lock), 0x7fffffff); \
} while (0)

View File

@ -1,4 +1,4 @@
# Copyright (C) 1994-2004, 2005 Free Software Foundation, Inc.
# Copyright (C) 1994-2004, 2005, 2006 Free Software Foundation, Inc.
# This file is part of the GNU C Library.
# The GNU C Library is free software; you can redistribute it and/or
@ -85,7 +85,7 @@ all: # Make this the default target; it will be defined in Rules.
include ../Makeconfig
tests = tst-xdrmem
tests = tst-xdrmem tst-xdrmem2
xtests := tst-getmyaddr
ifeq ($(have-thread-library),yes)

114
sunrpc/tst-xdrmem2.c Normal file
View File

@ -0,0 +1,114 @@
/* Copyright (C) 2006 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Jakub Jelinek <jakub@redhat.com>, 2006.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#include <limits.h>
#include <stdio.h>
#include <string.h>
#include <rpc/rpc.h>
#include <sys/mman.h>
#include <unistd.h>
static int
do_test (void)
{
XDR xdrs;
void *buf;
size_t ps = sysconf (_SC_PAGESIZE);
uintptr_t half = -1;
int v_int;
u_short v_u_short;
half = (half >> 1) & ~(uintptr_t) (ps - 1);
buf = mmap ((void *) half, 2 * ps, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANON, -1, 0);
if (buf == MAP_FAILED || buf != (void *) half)
{
puts ("Couldn't mmap 2 pages in the middle of address space");
return 0;
}
xdrmem_create (&xdrs, (char *) buf, 2 * ps, XDR_ENCODE);
#define T(type, val) \
v_##type = val; \
if (! xdr_##type (&xdrs, &v_##type)) \
{ \
puts ("encoding of " #type \
" " #val " failed"); \
return 1; \
}
T(int, 127)
u_int pos = xdr_getpos (&xdrs);
T(u_short, 31)
if (! xdr_setpos (&xdrs, pos))
{
puts ("xdr_setpos during encoding failed");
return 1;
}
T(u_short, 36)
#undef T
xdr_destroy (&xdrs);
xdrmem_create (&xdrs, (char *) buf, 2 * ps, XDR_DECODE);
#define T(type, val) \
v_##type = 0x15; \
if (! xdr_##type (&xdrs, &v_##type)) \
{ \
puts ("decoding of " #type \
" " #val " failed"); \
return 1; \
} \
if (v_##type != val) \
{ \
puts ("decoded value differs, " \
"type " #type " " #val); \
return 1; \
}
T(int, 127)
pos = xdr_getpos (&xdrs);
T(u_short, 36)
if (! xdr_setpos (&xdrs, pos))
{
puts ("xdr_setpos during encoding failed");
return 1;
}
T(u_short, 36)
#undef T
xdr_destroy (&xdrs);
return 0;
}
#define TEST_FUNCTION do_test ()
#include "../test-skeleton.c"

View File

@ -177,13 +177,15 @@ xdrmem_setpos (xdrs, pos)
{
caddr_t newaddr = xdrs->x_base + pos;
caddr_t lastaddr = xdrs->x_private + xdrs->x_handy;
size_t handy = lastaddr - newaddr;
if ((long) newaddr > (long) lastaddr
|| (UINT_MAX < LONG_MAX
&& (long) UINT_MAX < (long) lastaddr - (long) newaddr))
if (newaddr > lastaddr
|| newaddr < xdrs->x_base
|| handy != (u_int) handy)
return FALSE;
xdrs->x_private = newaddr;
xdrs->x_handy = (long) lastaddr - (long) newaddr;
xdrs->x_handy = (u_int) handy;
return TRUE;
}

View File

@ -425,7 +425,7 @@ typedef uintmax_t uatomic_max_t;
"cmpl $0, %%gs:%P2\n\tje 0f\n\tlock\n0:\t"
#define catomic_decrement(mem) \
__arch_increment_body (__arch_decrement_cprefix, __arch_c, mem)
__arch_decrement_body (__arch_decrement_cprefix, __arch_c, mem)
#define atomic_decrement_and_test(mem) \

View File

@ -81,8 +81,8 @@ typedef uintmax_t uatomic_max_t;
({ __typeof (*mem) ret; \
__asm __volatile (LOCK_PREFIX "cmpxchgq %q2, %1" \
: "=a" (ret), "=m" (*mem) \
: "r" ((long) (newval)), "m" (*mem), \
"0" ((long) (oldval))); \
: "r" ((long int) (newval)), "m" (*mem), \
"0" ((long int) (oldval))); \
ret; })
@ -121,12 +121,13 @@ typedef uintmax_t uatomic_max_t;
#define __arch_c_compare_and_exchange_val_64_acq(mem, newval, oldval) \
({ __typeof (*mem) ret; \
__asm __volatile ("cmpl $0, %%fs:%P5\n\t" \
"je 0f\n\t" \
"lock\n" \
__asm __volatile ("cmpl $0, %%fs:%P5\n\t" \
"je 0f\n\t" \
"lock\n" \
"0:\tcmpxchgq %q2, %1" \
: "=a" (ret), "=m" (*mem) \
: "q" (newval), "m" (*mem), "0" (oldval), \
: "q" ((long int) (newval)), "m" (*mem), \
"0" ((long int)oldval), \
"i" (offsetof (tcbhead_t, multiple_threads))); \
ret; })
@ -351,7 +352,7 @@ typedef uintmax_t uatomic_max_t;
"cmpl $0, %%fs:%P2\n\tje 0f\n\tlock\n0:\t"
#define catomic_decrement(mem) \
__arch_increment_body (__arch_decrement_cprefix, mem)
__arch_decrement_body (__arch_decrement_cprefix, mem)
#define atomic_decrement_and_test(mem) \