diff --git a/ChangeLog b/ChangeLog index 4b1ef43712..36ee420152 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2003-01-03 Jakub Jelinek + + * sysdeps/generic/ldsodefs.h (_dl_allocate_tls, _dl_deallocate_tls): + Add rtld_hidden_proto. + * sysdeps/generic/dl-tls.c (_dl_deallocate_tls): Add rtld_hidden_def. + (_dl_allocate_tls): Likewise. Remove INTDEF. + 2002-07-05 Kaz Kojima * sysdeps/sh/memcpy.S: Optimize. Based on a patch by Toshiyasu diff --git a/linuxthreads/ChangeLog b/linuxthreads/ChangeLog index ad38286577..175f7437e1 100644 --- a/linuxthreads/ChangeLog +++ b/linuxthreads/ChangeLog @@ -1,3 +1,7 @@ +2003-01-03 Jakub Jelinek + + * Makefile ($(objpfx)libpthread.so): Depend on ld.so. + 2003-01-02 Ulrich Drepper * tst-cancel-wrappers.sh: Exclude sigwait.c as well, it does not have diff --git a/linuxthreads/Makefile b/linuxthreads/Makefile index b9edd40031..ff26e06eea 100644 --- a/linuxthreads/Makefile +++ b/linuxthreads/Makefile @@ -185,7 +185,9 @@ endif # Depend on libc.so so a DT_NEEDED is generated in the shared objects. # This ensures they will load libc.so for needed symbols if loaded by # a statically-linked program that hasn't already loaded it. -$(objpfx)libpthread.so: $(libc-link.so) $(common-objpfx)libc_nonshared.a +# Depend on ld.so too to get proper versions of ld.so symbols. +$(objpfx)libpthread.so: $(libc-link.so) $(common-objpfx)libc_nonshared.a \ + $(if $(filter yes,$(elf)), $(elfobjdir)/ld.so) # Make sure we link with the thread library. ifeq ($(build-shared),yes) diff --git a/nptl/ChangeLog b/nptl/ChangeLog index e7173f9e4f..62744b1e37 100644 --- a/nptl/ChangeLog +++ b/nptl/ChangeLog @@ -1,3 +1,14 @@ +2003-01-03 Ulrich Drepper + + * atomic.h: Correct definitions of atomic_full_barrier, + atomic_read_barrier, atomic_write_barrier. + + * old_pthread_cond_broadcast.c: Make memory allocate and initialization + race-free. + * old_pthread_cond_signal.c: Likewise. + * old_pthread_cond_timedwait.c: Likewise. + * old_pthread_cond_wait.c: Likewise. + 2003-01-03 Jakub Jelinek * Makefile ($(objpfx)libpthread.so): Depend on ld.so. diff --git a/nptl/Makefile b/nptl/Makefile index 2a68c2e566..ceee78758c 100644 --- a/nptl/Makefile +++ b/nptl/Makefile @@ -212,8 +212,10 @@ $(objpfx)libpthread.so: +preinit += $(objpfx)crti.o # Depend on libc.so so a DT_NEEDED is generated in the shared objects. # This ensures they will load libc.so for needed symbols if loaded by # a statically-linked program that hasn't already loaded it. +# Depend on ld.so too to get proper versions of ld.so symbols. $(objpfx)libpthread.so: $(common-objpfx)libc.so \ - $(common-objpfx)libc_nonshared.a + $(common-objpfx)libc_nonshared.a \ + $(if $(filter yes,$(elf)), $(elfobjdir)/ld.so) # Make sure we link with the thread library. ifeq ($(build-shared),yes) diff --git a/nptl/atomic.h b/nptl/atomic.h index 927e0fe5ac..0464705691 100644 --- a/nptl/atomic.h +++ b/nptl/atomic.h @@ -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. Contributed by Ulrich Drepper , 2002. @@ -93,17 +93,17 @@ #ifndef atomic_full_barrier -# define full_barrier() __asm ("" ::: "memory") +# define atomic_full_barrier() __asm ("" ::: "memory") #endif #ifndef atomic_read_barrier -# define read_barrier() full_barrier() +# define atomic_read_barrier() atomic_full_barrier() #endif #ifndef atomic_write_barrier -# define write_barrier() full_barrier() +# define atomic_write_barrier() atomic_full_barrier() #endif #endif /* atomic.h */ diff --git a/nptl/old_pthread_cond_broadcast.c b/nptl/old_pthread_cond_broadcast.c index a9713f5e1b..05f24bb52b 100644 --- a/nptl/old_pthread_cond_broadcast.c +++ b/nptl/old_pthread_cond_broadcast.c @@ -20,7 +20,7 @@ #include #include #include "pthreadP.h" -#include +#include #include @@ -31,18 +31,19 @@ __pthread_cond_broadcast_2_0 (cond) { if (cond->cond == NULL) { - lll_mutex_lock (cond->lock); + pthread_cond_t *newcond; - /* Check whether the condvar is still not allocated. */ - if (cond->cond == NULL) - cond->cond = (pthread_cond_t *) malloc (sizeof (pthread_cond_t)); - - lll_mutex_unlock (cond->lock); - - if (cond->cond == NULL) + newcond = (pthread_cond_t *) malloc (sizeof (pthread_cond_t)); + if (newcond == NULL) return ENOMEM; - *cond->cond = (struct pthread_cond_t) PTHREAD_COND_INITIALIZER; + *newcond = (struct pthread_cond_t) PTHREAD_COND_INITIALIZER; + + atomic_write_barrier (); + + if (atomic_compare_and_exchange_acq (&cond->cond, newcond, NULL) != 0) + /* Somebody else just initialized the condvar. */ + free (newcond); } return __pthread_cond_broadcast (cond->cond); diff --git a/nptl/old_pthread_cond_signal.c b/nptl/old_pthread_cond_signal.c index 952ee6de41..717a33912b 100644 --- a/nptl/old_pthread_cond_signal.c +++ b/nptl/old_pthread_cond_signal.c @@ -20,6 +20,7 @@ #include #include #include "pthreadP.h" +#include #include @@ -30,18 +31,19 @@ __pthread_cond_signal_2_0 (cond) { if (cond->cond == NULL) { - lll_mutex_lock (cond->lock); + pthread_cond_t *newcond; - /* Check whether the condvar is still not allocated. */ - if (cond->cond == NULL) - cond->cond = (pthread_cond_t *) malloc (sizeof (pthread_cond_t)); - - lll_mutex_unlock (cond->lock); - - if (cond->cond == NULL) + newcond = (pthread_cond_t *) malloc (sizeof (pthread_cond_t)); + if (newcond == NULL) return ENOMEM; - *cond->cond = (struct pthread_cond_t) PTHREAD_COND_INITIALIZER; + *newcond = (struct pthread_cond_t) PTHREAD_COND_INITIALIZER; + + atomic_write_barrier (); + + if (atomic_compare_and_exchange_acq (&cond->cond, newcond, NULL) != 0) + /* Somebody else just initialized the condvar. */ + free (newcond); } return __pthread_cond_signal (cond->cond); diff --git a/nptl/old_pthread_cond_timedwait.c b/nptl/old_pthread_cond_timedwait.c index 7b0faa78d2..ef4db9e6e8 100644 --- a/nptl/old_pthread_cond_timedwait.c +++ b/nptl/old_pthread_cond_timedwait.c @@ -20,6 +20,7 @@ #include #include #include "pthreadP.h" +#include #include @@ -32,18 +33,19 @@ __pthread_cond_timedwait_2_0 (cond, mutex, abstime) { if (cond->cond == NULL) { - lll_mutex_lock (cond->lock); + pthread_cond_t *newcond; - /* Check whether the condvar is still not allocated. */ - if (cond->cond == NULL) - cond->cond = (pthread_cond_t *) malloc (sizeof (pthread_cond_t)); - - lll_mutex_unlock (cond->lock); - - if (cond->cond == NULL) + newcond = (pthread_cond_t *) malloc (sizeof (pthread_cond_t)); + if (newcond == NULL) return ENOMEM; - *cond->cond = (struct pthread_cond_t) PTHREAD_COND_INITIALIZER; + *newcond = (struct pthread_cond_t) PTHREAD_COND_INITIALIZER; + + atomic_write_barrier (); + + if (atomic_compare_and_exchange_acq (&cond->cond, newcond, NULL) != 0) + /* Somebody else just initialized the condvar. */ + free (newcond); } return __pthread_cond_timedwait (cond->cond, mutex, abstime); diff --git a/nptl/old_pthread_cond_wait.c b/nptl/old_pthread_cond_wait.c index 493f00a3eb..b124b260d4 100644 --- a/nptl/old_pthread_cond_wait.c +++ b/nptl/old_pthread_cond_wait.c @@ -20,6 +20,7 @@ #include #include #include "pthreadP.h" +#include #include @@ -31,18 +32,19 @@ __pthread_cond_wait_2_0 (cond, mutex) { if (cond->cond == NULL) { - lll_mutex_lock (cond->lock); + pthread_cond_t *newcond; - /* Check whether the condvar is still not allocated. */ - if (cond->cond == NULL) - cond->cond = (pthread_cond_t *) malloc (sizeof (pthread_cond_t)); - - lll_mutex_unlock (cond->lock); - - if (cond->cond == NULL) + newcond = (pthread_cond_t *) malloc (sizeof (pthread_cond_t)); + if (newcond == NULL) return ENOMEM; - *cond->cond = (struct pthread_cond_t) PTHREAD_COND_INITIALIZER; + *newcond = (struct pthread_cond_t) PTHREAD_COND_INITIALIZER; + + atomic_write_barrier (); + + if (atomic_compare_and_exchange_acq (&cond->cond, newcond, NULL) != 0) + /* Somebody else just initialized the condvar. */ + free (newcond); } return __pthread_cond_wait (cond->cond, mutex); diff --git a/sysdeps/generic/dl-tls.c b/sysdeps/generic/dl-tls.c index 725625d0fe..6791d765ee 100644 --- a/sysdeps/generic/dl-tls.c +++ b/sysdeps/generic/dl-tls.c @@ -1,5 +1,5 @@ /* Thread-local storage handling in the ELF dynamic linker. Generic version. - Copyright (C) 2002 Free Software Foundation, Inc. + Copyright (C) 2002, 2003 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 @@ -388,7 +388,7 @@ _dl_allocate_tls (void *mem) ? _dl_allocate_tls_storage () : allocate_dtv (mem)); } -INTDEF(_dl_allocate_tls) +rtld_hidden_def (_dl_allocate_tls) void @@ -409,7 +409,7 @@ _dl_deallocate_tls (void *tcb, bool dealloc_tcb) free (tcb); } } - +rtld_hidden_def (_dl_deallocate_tls) # ifdef SHARED diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h index 6150852ed9..2d8041fa68 100644 --- a/sysdeps/generic/ldsodefs.h +++ b/sysdeps/generic/ldsodefs.h @@ -1,5 +1,5 @@ /* Run-time dynamic linker data structures for loaded ELF shared objects. - Copyright (C) 1995-1999, 2000, 2001, 2002 Free Software Foundation, Inc. + Copyright (C) 1995-2002, 2003 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 @@ -769,6 +769,7 @@ rtld_hidden_proto (_dl_tls_setup) /* Allocate memory for static TLS block (unless MEM is nonzero) and dtv. */ extern void *_dl_allocate_tls (void *mem) internal_function; +rtld_hidden_proto (_dl_allocate_tls) /* Get size and alignment requirements of the static TLS block. */ extern void _dl_get_tls_static_info (size_t *sizep, size_t *alignp) @@ -783,6 +784,7 @@ rtld_hidden_proto (_dl_allocate_tls_init) /* Deallocate memory allocated with _dl_allocate_tls. */ extern void _dl_deallocate_tls (void *tcb, bool dealloc_tcb) internal_function; +rtld_hidden_proto (_dl_deallocate_tls) /* Return the symbol address given the map of the module it is in and the symbol record. */