From jakub@redhat.com Mon Jul 13 16:11:00 2009 From: jakub@redhat.com (Jakub Jelinek) Date: Mon, 13 Jul 2009 16:11:00 -0000 Subject: [PATCH] Use rel semantics of cas instead of acq semantics with full barrier before it in _int_free Message-ID: <20090713161031.GF3101@sunsite.ms.mff.cuni.cz> Hi! The following patch fixes catomic_compare_and_exchange_*_rel definitions (which were never used and weren't correct) and uses catomic_compare_and_exchange_val_rel in _int_free. Comparing to the pre-2009-07-02 --enable-experimental-malloc state the generated code should be identical on all arches other than ppc/ppc64 and on ppc/ppc64 should use lwsync instead of isync barrier. 2009-07-13 Jakub Jelinek * include/atomic.h (catomic_compare_and_exchange_val_rel): If arch overrides atomic_compare_and_exchange_val_rel, define to atomic_compare_and_exchange_val_rel by default, otherwise default to catomic_compare_and_exchange_val_acq. (catomic_compare_and_exchange_bool_rel): If arch overrides atomic_compare_and_exchange_bool_rel, define to atomic_compare_and_exchange_bool_rel by default. * malloc/malloc.c (_int_free): Revert 2009-07-02 change. Use catomic_compare_and_exchange_val_rel instead of catomic_compare_and_exchange_val_acq. --- libc/include/atomic.h.jj 2009-05-16 19:23:35.000000000 +0200 +++ libc/include/atomic.h 2009-07-13 17:47:02.000000000 +0200 @@ -107,14 +107,19 @@ #endif -#ifndef atomic_compare_and_exchange_val_rel -# define atomic_compare_and_exchange_val_rel(mem, newval, oldval) \ - atomic_compare_and_exchange_val_acq (mem, newval, oldval) +#ifndef catomic_compare_and_exchange_val_rel +# ifndef atomic_compare_and_exchange_val_rel +# define catomic_compare_and_exchange_val_rel(mem, newval, oldval) \ + catomic_compare_and_exchange_val_acq (mem, newval, oldval) +# else +# define catomic_compare_and_exchange_val_rel(mem, newval, oldval) \ + atomic_compare_and_exchange_val_rel (mem, newval, oldval) +# endif #endif -#ifndef catomic_compare_and_exchange_val_rel -# define catomic_compare_and_exchange_val_rel(mem, newval, oldval) \ +#ifndef atomic_compare_and_exchange_val_rel +# define atomic_compare_and_exchange_val_rel(mem, newval, oldval) \ atomic_compare_and_exchange_val_acq (mem, newval, oldval) #endif @@ -155,15 +160,20 @@ #endif -#ifndef atomic_compare_and_exchange_bool_rel -# define atomic_compare_and_exchange_bool_rel(mem, newval, oldval) \ - atomic_compare_and_exchange_bool_acq (mem, newval, oldval) +#ifndef catomic_compare_and_exchange_bool_rel +# ifndef atomic_compare_and_exchange_bool_rel +# define catomic_compare_and_exchange_bool_rel(mem, newval, oldval) \ + catomic_compare_and_exchange_bool_acq (mem, newval, oldval) +# else +# define catomic_compare_and_exchange_bool_rel(mem, newval, oldval) \ + atomic_compare_and_exchange_bool_rel (mem, newval, oldval) +# endif #endif -#ifndef catomic_compare_and_exchange_bool_rel -# define catomic_compare_and_exchange_bool_rel(mem, newval, oldval) \ - catomic_compare_and_exchange_bool_acq (mem, newval, oldval) +#ifndef atomic_compare_and_exchange_bool_rel +# define atomic_compare_and_exchange_bool_rel(mem, newval, oldval) \ + atomic_compare_and_exchange_bool_acq (mem, newval, oldval) #endif --- libc/malloc/malloc.c.jj 2009-07-07 19:10:19.000000000 +0200 +++ libc/malloc/malloc.c 2009-07-13 17:47:52.000000000 +0200 @@ -4822,9 +4822,8 @@ _int_free(mstate av, mchunkptr p) goto errout; } p->fd = fd = old; - atomic_full_barrier (); } - while ((old = catomic_compare_and_exchange_val_acq (fb, p, fd)) != fd); + while ((old = catomic_compare_and_exchange_val_rel (fb, p, fd)) != fd); #else /* Another simple check: make sure the top of the bin is not the record we are going to add (i.e., double free). */ Jakub From sjmunroe@us.ibm.com Tue Jul 14 14:44:00 2009 From: sjmunroe@us.ibm.com (Steve Munroe) Date: Tue, 14 Jul 2009 14:44:00 -0000 Subject: [PATCH] Use rel semantics of cas instead of acq semantics with full barrier before it in _int_free In-Reply-To: <20090713161031.GF3101@sunsite.ms.mff.cuni.cz> Message-ID: Jakub Jelinek wrote on 07/13/2009 11:10:31 AM: > Hi! > > The following patch fixes catomic_compare_and_exchange_*_rel definitions > (which were never used and weren't correct) and uses > catomic_compare_and_exchange_val_rel in _int_free. Comparing to the > pre-2009-07-02 --enable-experimental-malloc state the generated code should > be identical on all arches other than ppc/ppc64 and on ppc/ppc64 should use > lwsync instead of isync barrier. > > 2009-07-13 Jakub Jelinek > > * include/atomic.h (catomic_compare_and_exchange_val_rel): If arch > overrides atomic_compare_and_exchange_val_rel, define to > atomic_compare_and_exchange_val_rel by default, otherwise default > to catomic_compare_and_exchange_val_acq. > (catomic_compare_and_exchange_bool_rel): If arch overrides > atomic_compare_and_exchange_bool_rel, define to > atomic_compare_and_exchange_bool_rel by default. > * malloc/malloc.c (_int_free): Revert 2009-07-02 change. > Use catomic_compare_and_exchange_val_rel instead of > catomic_compare_and_exchange_val_acq. > > --- libc/include/atomic.h.jj 2009-05-16 19:23:35.000000000 +0200 > +++ libc/include/atomic.h 2009-07-13 17:47:02.000000000 +0200 > @@ -107,14 +107,19 @@ > #endif > > > -#ifndef atomic_compare_and_exchange_val_rel > -# define atomic_compare_and_exchange_val_rel(mem, newval, oldval) \ > - atomic_compare_and_exchange_val_acq (mem, newval, oldval) > +#ifndef catomic_compare_and_exchange_val_rel > +# ifndef atomic_compare_and_exchange_val_rel > +# define catomic_compare_and_exchange_val_rel(mem, newval, oldval) \ > + catomic_compare_and_exchange_val_acq (mem, newval, oldval) > +# else > +# define catomic_compare_and_exchange_val_rel(mem, newval, oldval) \ > + atomic_compare_and_exchange_val_rel (mem, newval, oldval) > +# endif > #endif > I assume that defining catomic_compare_and_exchange_val_rel in terms of catomic_compare_and_exchange_val_acq is only for platforms where there is no distinction (between _acq/_rel) and the platforms sysdeps atomic.h did not define separate *_rel macros. Otherwise this is a bit confusing... > snip ... > --- libc/malloc/malloc.c.jj 2009-07-07 19:10:19.000000000 +0200 > +++ libc/malloc/malloc.c 2009-07-13 17:47:52.000000000 +0200 > @@ -4822,9 +4822,8 @@ _int_free(mstate av, mchunkptr p) > goto errout; > } > p->fd = fd = old; > - atomic_full_barrier (); > } > - while ((old = catomic_compare_and_exchange_val_acq (fb, p, fd)) != fd); > + while ((old = catomic_compare_and_exchange_val_rel (fb, p, fd)) != fd); > #else > /* Another simple check: make sure the top of the bin is not the > record we are going to add (i.e., double free). */ > > Jakub This is a better solution as the use case matches release semantics. In this case we are exporting the "p->fd = fd = old" and needs the export/read barrier that the *_rel macro naturally provides. A import/write barrier is not required as the do/while iterates only for retry. For PPC the selection of raw *_acq vs *_rel macros depends on the context. Thanks Steven J. Munroe Linux on Power Toolchain Architect IBM Corporation, Linux Technology Center From jakub@redhat.com Mon Jul 27 14:07:00 2009 From: jakub@redhat.com (Jakub Jelinek) Date: Mon, 27 Jul 2009 14:07:00 -0000 Subject: [PATCH] Fix STB_GNU_UNIQUE handling for > 30 unique symbols Message-ID: <20090727140602.GN3101@sunsite.ms.mff.cuni.cz> Hi! There were several issues when the initial 31 entries hashtab filled up. size * 3 <= tab->n_elements is always false, table can't have more elements than its size. I assume from libiberty/hashtab.c this meant to be check for 3/4 full. Even after fixing that, _dl_higher_prime_number (31) apparently returns 31, only _dl_higher_prime_number (32) returns 61. And, size variable wasn't updated during reallocation, which means during reallocation the insertion of the new entry was done into a wrong spot. All this lead to a hang in ld.so, because a search with n_elements 31 size 31 wouldn't ever terminate. 2009-07-27 Jakub Jelinek * elf/dl-lookup.c (do_lookup_x): Fix check for table more than 3/4 full. Pass size + 1 rather than size to _dl_higher_prime_number. Update size when reallocating. --- libc/elf/dl-lookup.c.jj 2009-07-23 16:44:46.000000000 +0200 +++ libc/elf/dl-lookup.c 2009-07-27 15:58:48.000000000 +0200 @@ -377,10 +377,10 @@ do_lookup_x (const char *undef_name, uin idx -= size; } - if (size * 3 <= tab->n_elements) + if (size * 3 <= tab->n_elements * 4) { /* Expand the table. */ - size_t newsize = _dl_higher_prime_number (size); + size_t newsize = _dl_higher_prime_number (size + 1); struct unique_sym *newentries = calloc (sizeof (struct unique_sym), newsize); if (newentries == NULL) @@ -398,6 +398,7 @@ do_lookup_x (const char *undef_name, uin tab->free (entries); tab->size = newsize; + size = newsize; entries = tab->entries = newentries; tab->free = free; } Jakub From jakub@redhat.com Fri Jul 31 12:22:00 2009 From: jakub@redhat.com (Jakub Jelinek) Date: Fri, 31 Jul 2009 12:22:00 -0000 Subject: [PATCH] Fix obstack* on i?86 Message-ID: <20090731122131.GO3101@sunsite.ms.mff.cuni.cz> Hi! obstack calls several callbacks, so on i?86 it'd better be compiled without -mpreferred-stack-boundary=2, otherwise the callbacks are called with misaligned stack. 2009-07-31 Jakub Jelinek * malloc/Makefile (CFLAGS-obstack.c): Add $(uses-callbacks). --- libc/malloc/Makefile 2009-05-16 19:23:36.000000000 +0200 +++ libc/malloc/Makefile 2009-07-31 09:09:51.760080072 +0200 @@ -104,6 +104,7 @@ $(objpfx)memusagestat: $(memusagestat-mo include ../Rules CFLAGS-mcheck-init.c = $(PIC-ccflag) +CFLAGS-obstack.c = $(uses-callbacks) $(objpfx)libmcheck.a: $(objpfx)mcheck-init.o -rm -f $@ Jakub