public inbox for libc-hacker@sourceware.org
 help / color / mirror / Atom feed
* [PATCH] __rtld_*lock_recursive changes
@ 2003-08-07 16:06 Jakub Jelinek
  2003-08-08  7:44 ` Ulrich Drepper
  0 siblings, 1 reply; 2+ messages in thread
From: Jakub Jelinek @ 2003-08-07 16:06 UTC (permalink / raw)
  To: Ulrich Drepper, Roland McGrath; +Cc: Glibc hackers

Hi!

ATM ld.so and libc.so have weak undef references to __pthread_mutex_{,un}lock
and use it for GL(dl_load_lock) locking.
This is bad, in case libpthread is dlopened later.
Until libpthread is loaded, ld.so can use simple ++count/--count,
when libpthread is loaded, it can just take this count and lock the
recursive lock that many times so that lock recursion is preserved.
The following patch also kills one unneeded GOT relocation.

2003-08-07  Jakub Jelinek  <jakub@redhat.com>

	* sysdeps/generic/ldsodefs.h (_rtld_global): Add
	_dl_rtld_lock_recursive and _dl_rtld_unlock_recursive.
	* elf/rtld.c (rtld_lock_default_lock_recursive,
	rtld_lock_default_unlock_recursive): New functions.
	(dl_main): Initialize _dl_rtld_lock_recursive and
	_dl_rtld_unlock_recursive.
nptl/
	* sysdeps/pthread/bits/libc-lock.h [_LIBC && SHARED]
	(__rtld_lock_default_lock_recursive,
	__rtld_lock_default_unlock_recursive): Define.
	[_LIBC && SHARED] (__rtld_lock_lock_recursive,
	__rtld_lock_unlock_recursive): Define using
	GL(_dl_rtld_*lock_recursive).
	* init.c (__pthread_initialize_minimal_internal): Initialize
	_dl_rtld_lock_recursive and _dl_rtld_unlock_recursive.
	Lock GL(_dl_load_lock) the same number of times as
	GL(_dl_load_lock) using non-mt implementation was nested.

	* pthreadP.h (__pthread_cleanup_upto): Add hidden_proto.
	* pt-longjmp.c (__pthread_cleanup_upto): Add hidden_def.
linuxthreads/
	* sysdeps/pthread/bits/libc-lock.h [_LIBC && SHARED]
	(__rtld_lock_default_lock_recursive,
	__rtld_lock_default_unlock_recursive): Define.
	[_LIBC && SHARED] (__rtld_lock_lock_recursive,
	__rtld_lock_unlock_recursive): Define using
	GL(_dl_rtld_*lock_recursive).
	* pthread.c (pthread_initialize): Initialize _dl_rtld_lock_recursive
	and _dl_rtld_unlock_recursive.  Lock GL(_dl_load_lock) the same
	number of times as GL(_dl_load_lock) using non-mt implementation was
	nested.

--- libc/nptl/sysdeps/pthread/bits/libc-lock.h.jj	2003-07-08 09:54:09.000000000 -0400
+++ libc/nptl/sysdeps/pthread/bits/libc-lock.h	2003-08-07 06:43:04.000000000 -0400
@@ -248,9 +248,6 @@ typedef pthread_key_t __libc_key_t;
   __libc_maybe_call (__pthread_mutex_lock, (&(NAME).mutex), 0)
 #endif
 
-#define __rtld_lock_lock_recursive(NAME) \
-  __libc_maybe_call (__pthread_mutex_lock, (&(NAME).mutex), 0)
-
 /* Try to lock the named lock variable.  */
 #if defined _LIBC && (!defined NOT_IN_libc || defined IS_IN_libpthread)
 # define __libc_lock_trylock(NAME) \
@@ -319,8 +316,25 @@ typedef pthread_key_t __libc_key_t;
   __libc_maybe_call (__pthread_mutex_unlock, (&(NAME)), 0)
 #endif
 
-#define __rtld_lock_unlock_recursive(NAME) \
+#if defined _LIBC && defined SHARED
+# define __rtld_lock_default_lock_recursive(lock) \
+  ++((pthread_mutex_t *)(lock))->__data.__count;
+
+# define __rtld_lock_default_unlock_recursive(lock) \
+  --((pthread_mutex_t *)(lock))->__data.__count;
+
+# define __rtld_lock_lock_recursive(NAME) \
+  GL(dl_rtld_lock_recursive) (&(NAME).mutex)
+
+# define __rtld_lock_unlock_recursive(NAME) \
+  GL(dl_rtld_unlock_recursive) (&(NAME).mutex)
+#else
+# define __rtld_lock_lock_recursive(NAME) \
+  __libc_maybe_call (__pthread_mutex_lock, (&(NAME).mutex), 0)
+
+# define __rtld_lock_unlock_recursive(NAME) \
   __libc_maybe_call (__pthread_mutex_unlock, (&(NAME).mutex), 0)
+#endif
 
 /* Define once control variable.  */
 #if PTHREAD_ONCE_INIT == 0
--- libc/nptl/init.c.jj	2003-08-03 04:15:48.000000000 -0400
+++ libc/nptl/init.c	2003-08-07 08:20:34.000000000 -0400
@@ -270,6 +270,15 @@ __pthread_initialize_minimal_internal (v
   /* Transfer the old value from the dynamic linker's internal location.  */
   *__libc_dl_error_tsd () = *(*GL(dl_error_catch_tsd)) ();
   GL(dl_error_catch_tsd) = &__libc_dl_error_tsd;
+
+  /* Make __rtld_lock_{,un}lock_recursive use pthread_mutex_{,un}lock,
+     keep the lock count from the ld.so implementation.  */
+  GL(dl_rtld_lock_recursive) = (void *) INTUSE (__pthread_mutex_lock);
+  GL(dl_rtld_unlock_recursive) = (void *) INTUSE (__pthread_mutex_unlock);
+  unsigned int rtld_lock_count = GL(dl_load_lock).mutex.__data.__count;
+  GL(dl_load_lock).mutex.__data.__count = 0;
+  while (rtld_lock_count-- > 0)
+    INTUSE (__pthread_mutex_lock) (&GL(dl_load_lock).mutex);
 #endif
 
   GL(dl_init_static_tls) = &__pthread_init_static_tls;
--- libc/nptl/pt-longjmp.c.jj	2002-11-26 17:49:18.000000000 -0500
+++ libc/nptl/pt-longjmp.c	2003-08-07 07:38:47.000000000 -0400
@@ -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 <drepper@redhat.com>, 2002.
 
@@ -54,7 +54,7 @@ __pthread_cleanup_upto (__jmp_buf target
 
   THREAD_SETMEM (self, cleanup, cbuf);
 }
-
+hidden_def (__pthread_cleanup_upto)
 
 
 void
--- libc/nptl/pthreadP.h.jj	2003-08-03 04:15:48.000000000 -0400
+++ libc/nptl/pthreadP.h	2003-08-03 04:15:48.000000000 -0400
@@ -217,6 +217,9 @@ extern void __reclaim_stacks (void) attr
 
 /* longjmp handling.  */
 extern void __pthread_cleanup_upto (__jmp_buf target, char *targetframe);
+#if defined NOT_IN_libc && defined IS_IN_libpthread
+hidden_proto (__pthread_cleanup_upto)
+#endif
 
 
 /* Functions with versioned interfaces.  */
--- libc/elf/rtld.c.jj	2003-08-06 14:36:13.000000000 -0400
+++ libc/elf/rtld.c	2003-08-07 06:57:42.000000000 -0400
@@ -588,6 +588,20 @@ _dl_initial_error_catch_tsd (void)
 }
 #endif
 
+#if defined SHARED && defined _LIBC_REENTRANT \
+    && defined __rtld_lock_default_lock_recursive
+static void rtld_lock_default_lock_recursive (void *lock)
+{
+  __rtld_lock_default_lock_recursive (lock);
+}
+
+static void rtld_lock_default_unlock_recursive (void *lock)
+{
+  __rtld_lock_default_unlock_recursive (lock);
+}
+#endif
+
+
 static const char *library_path;	/* The library search path.  */
 static const char *preloadlist;		/* The list preloaded objects.  */
 static int version_info;		/* Nonzero if information about
@@ -626,6 +640,12 @@ dl_main (const ElfW(Phdr) *phdr,
   GL(dl_init_static_tls) = &_dl_nothread_init_static_tls;
 #endif
 
+#if defined SHARED && defined _LIBC_REENTRANT \
+    && defined __rtld_lock_default_lock_recursive
+  GL(dl_rtld_lock_recursive) = rtld_lock_default_lock_recursive;
+  GL(dl_rtld_unlock_recursive) = rtld_lock_default_unlock_recursive;
+#endif
+
   /* Process the environment variable which control the behaviour.  */
   process_envvars (&mode);
 
--- libc/linuxthreads/pthread.c.jj	2003-07-31 04:35:47.000000000 -0400
+++ libc/linuxthreads/pthread.c	2003-08-07 08:37:43.000000000 -0400
@@ -588,6 +588,15 @@ static void pthread_initialize(void)
   /* Transfer the old value from the dynamic linker's internal location.  */
   *__libc_dl_error_tsd () = *(*GL(dl_error_catch_tsd)) ();
   GL(dl_error_catch_tsd) = &__libc_dl_error_tsd;
+
+  /* Make __rtld_lock_{,un}lock_recursive use pthread_mutex_{,un}lock,
+     keep the lock count from the ld.so implementation.  */
+  GL(dl_rtld_lock_recursive) = (void *) __pthread_mutex_lock;
+  GL(dl_rtld_unlock_recursive) = (void *) __pthread_mutex_unlock;
+  unsigned int rtld_lock_count = GL(dl_load_lock).mutex.__m_count;
+  GL(dl_load_lock).mutex.__m_count = 0;
+  while (rtld_lock_count-- > 0)
+    __pthread_mutex_lock (&GL(dl_load_lock).mutex);
 #endif
 
 #ifdef USE_TLS
--- libc/linuxthreads/sysdeps/pthread/bits/libc-lock.h.jj	2003-07-21 07:30:23.000000000 -0400
+++ libc/linuxthreads/sysdeps/pthread/bits/libc-lock.h	2003-08-07 08:32:13.000000000 -0400
@@ -180,7 +180,6 @@ typedef pthread_key_t __libc_key_t;
 
 /* Lock the recursive named lock variable.  */
 #define __libc_lock_lock_recursive(NAME) __libc_lock_lock ((NAME).mutex)
-#define __rtld_lock_lock_recursive(NAME) __libc_lock_lock_recursive (NAME)
 
 /* Try to lock the named lock variable.  */
 #define __libc_lock_trylock(NAME) \
@@ -203,8 +202,23 @@ typedef pthread_key_t __libc_key_t;
 
 /* Unlock the recursive named lock variable.  */
 #define __libc_lock_unlock_recursive(NAME) __libc_lock_unlock ((NAME).mutex)
-#define __rtld_lock_unlock_recursive(NAME) __libc_lock_unlock_recursive (NAME)
 
+#if defined _LIBC && defined SHARED
+# define __rtld_lock_default_lock_recursive(lock) \
+  ++((pthread_mutex_t *)(lock))->__m_count;
+
+# define __rtld_lock_default_unlock_recursive(lock) \
+  --((pthread_mutex_t *)(lock))->__m_count;
+
+# define __rtld_lock_lock_recursive(NAME) \
+  GL(dl_rtld_lock_recursive) (&(NAME).mutex)
+
+# define __rtld_lock_unlock_recursive(NAME) \
+  GL(dl_rtld_unlock_recursive) (&(NAME).mutex)
+#else
+#define __rtld_lock_lock_recursive(NAME) __libc_lock_lock_recursive (NAME)
+#define __rtld_lock_unlock_recursive(NAME) __libc_lock_unlock_recursive (NAME)
+#endif
 
 /* Define once control variable.  */
 #if PTHREAD_ONCE_INIT == 0
--- libc/sysdeps/generic/ldsodefs.h.jj	2003-07-31 04:35:54.000000000 -0400
+++ libc/sysdeps/generic/ldsodefs.h	2003-08-07 06:57:29.000000000 -0400
@@ -349,6 +349,12 @@ struct rtld_global
   /* Structure describing the dynamic linker itself.  */
   EXTERN struct link_map _dl_rtld_map;
 
+#if defined SHARED && defined _LIBC_REENTRANT \
+    && defined __rtld_lock_default_lock_recursive
+  EXTERN void (*_dl_rtld_lock_recursive) (void *);
+  EXTERN void (*_dl_rtld_unlock_recursive) (void *);
+#endif
+
   /* Keep the conditional TLS members at the end so the layout of the
      structure used by !USE_TLS code matches the prefix of the layout in
      the USE_TLS rtld.  Note that `struct link_map' is conditionally

	Jakub

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [PATCH] __rtld_*lock_recursive changes
  2003-08-07 16:06 [PATCH] __rtld_*lock_recursive changes Jakub Jelinek
@ 2003-08-08  7:44 ` Ulrich Drepper
  0 siblings, 0 replies; 2+ messages in thread
From: Ulrich Drepper @ 2003-08-08  7:44 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: Roland McGrath, Glibc hackers

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Jakub Jelinek wrote:

> Until libpthread is loaded, ld.so can use simple ++count/--count,
> when libpthread is loaded, it can just take this count and lock the
> recursive lock that many times so that lock recursion is preserved.
> The following patch also kills one unneeded GOT relocation.

I've applied the patch.  Thanks,

- -- 
- --------------.                        ,-.            444 Castro Street
Ulrich Drepper \    ,-----------------'   \ Mountain View, CA 94041 USA
Red Hat         `--' drepper at redhat.com `---------------------------
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.1 (GNU/Linux)

iD8DBQE/M1Sz2ijCOnn/RHQRAiBQAJ4hFypVBr+2aRozVXICdH4n4ZaXFACbBPld
T7a3kSOD9tCo2dzmCPL62cM=
=rkUg
-----END PGP SIGNATURE-----

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2003-08-08  7:44 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-08-07 16:06 [PATCH] __rtld_*lock_recursive changes Jakub Jelinek
2003-08-08  7:44 ` Ulrich Drepper

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).