bug-hurd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[RFC PATCH glibc 2/3] XXX: Move __pthread_threads to ld.so


From: Sergey Bugaev
Subject: [RFC PATCH glibc 2/3] XXX: Move __pthread_threads to ld.so
Date: Sun, 9 May 2021 16:54:03 +0300

The next commit is going to introduce a new implementation of
THREAD_GSCOPE_WAIT, which needs to access the list of threads. Since
it must be usable from the dynamic laoder, we have to move the
symbols for the list of threads into the loader.

This is my attempt at doing so.
---
 elf/dl-support.c                         |  4 ++-
 htl/Versions                             |  2 +-
 htl/pt-alloc.c                           | 46 ++++++++++++------------
 htl/pt-create.c                          | 11 ++----
 htl/pt-internal.h                        | 28 +++++----------
 sysdeps/generic/ldsodefs.h               |  8 ++++-
 sysdeps/htl/pt-key-delete.c              |  8 ++---
 sysdeps/htl/pthreadP.h                   |  2 +-
 sysdeps/htl/raise.c                      |  9 +++--
 sysdeps/htl/thrd_current.c               |  8 +++--
 sysdeps/mach/hurd/htl/pt-sigstate-init.c |  2 +-
 sysdeps/mach/hurd/htl/pt-sysdep.c        |  2 +-
 sysdeps/mach/hurd/htl/pt-sysdep.h        |  2 +-
 13 files changed, 67 insertions(+), 65 deletions(-)

diff --git a/elf/dl-support.c b/elf/dl-support.c
index af340bee..a55834a1 100644
--- a/elf/dl-support.c
+++ b/elf/dl-support.c
@@ -194,7 +194,9 @@ list_t _dl_stack_used;
 list_t _dl_stack_user;
 int _dl_stack_cache_lock;
 #else
-int _dl_thread_gscope_count;
+int _dl_pthread_num_threads;
+struct __pthread **_dl_pthread_threads;
+int _dl_pthread_threads_lock;
 void (*_dl_init_static_tls) (struct link_map *) = 
&_dl_nothread_init_static_tls;
 #endif
 struct dl_scope_free_list *_dl_scope_free_list;
diff --git a/htl/Versions b/htl/Versions
index 9506043c..07a343f9 100644
--- a/htl/Versions
+++ b/htl/Versions
@@ -168,7 +168,7 @@ libpthread {
   GLIBC_PRIVATE {
     __pthread_initialize_minimal;
 
-    __pthread_threads;
+    # __pthread_threads;
 
     __cthread_detach;
     __cthread_fork;
diff --git a/htl/pt-alloc.c b/htl/pt-alloc.c
index acc67f27..b60daf81 100644
--- a/htl/pt-alloc.c
+++ b/htl/pt-alloc.c
@@ -29,17 +29,17 @@
    corresponding to that specified by the given thread ID."  */
 
 /* Thread ID lookup table.  */
-struct __pthread **__pthread_threads;
+// struct __pthread **__pthread_threads;
 
 /* The size of the thread ID lookup table.  */
 int __pthread_max_threads;
 
 /* The total number of thread IDs currently in use, or on the list of
    available thread IDs.  */
-int __pthread_num_threads;
+// int __pthread_num_threads;
 
 /* A lock for the table, and the other variables above.  */
-pthread_rwlock_t __pthread_threads_lock;
+// pthread_rwlock_t __pthread_threads_lock;
 
 /* List of thread structures corresponding to free thread IDs.  */
 struct __pthread *__pthread_free_threads;
@@ -132,25 +132,25 @@ __pthread_alloc (struct __pthread **pthread)
     }
 
 retry:
-  __pthread_rwlock_wrlock (&__pthread_threads_lock);
+  lll_lock (GL (dl_pthread_threads_lock), 0);
 
-  if (__pthread_num_threads < __pthread_max_threads)
+  if (GL (dl_pthread_num_threads) < __pthread_max_threads)
     {
       /* We have a free slot.  Use the slot number plus one as the
          thread ID for the new thread.  */
-      new->thread = 1 + __pthread_num_threads++;
-      __pthread_threads[new->thread - 1] = NULL;
+      new->thread = 1 + GL (dl_pthread_num_threads)++;
+      GL (dl_pthread_threads)[new->thread - 1] = NULL;
 
-      __pthread_rwlock_unlock (&__pthread_threads_lock);
+      lll_unlock (GL (dl_pthread_threads_lock), 0);
 
       *pthread = new;
       return 0;
     }
 #ifdef PTHREAD_THREADS_MAX
-  else if (__pthread_num_threads >= PTHREAD_THREADS_MAX)
+  else if (GL (dl_pthread_num_threads) >= PTHREAD_THREADS_MAX)
     {
       /* We have reached the limit on the number of threads per process.  */
-      __pthread_rwlock_unlock (&__pthread_threads_lock);
+      lll_unlock (GL (dl_pthread_threads_lock), 0);
 
       free (new);
       return EAGAIN;
@@ -162,7 +162,7 @@ retry:
      memory allocation, since that's a potentially blocking operation.  */
   max_threads = __pthread_max_threads;
 
-  __pthread_rwlock_unlock (&__pthread_threads_lock);
+  lll_unlock (GL (dl_pthread_threads_lock), 0);
 
   /* Allocate a new lookup table that's twice as large.  */
   new_max_threads
@@ -174,13 +174,13 @@ retry:
       return ENOMEM;
     }
 
-  __pthread_rwlock_wrlock (&__pthread_threads_lock);
+  lll_lock (GL (dl_pthread_threads_lock), 0);
 
   /* Check if nobody else has already enlarged the table.  */
   if (max_threads != __pthread_max_threads)
     {
       /* Yep, they did.  */
-      __pthread_rwlock_unlock (&__pthread_threads_lock);
+      lll_unlock (GL (dl_pthread_threads_lock), 0);
 
       /* Free the newly allocated table and try again to allocate a slot.  */
       free (threads);
@@ -188,22 +188,22 @@ retry:
     }
 
   /* Copy over the contents of the old table.  */
-  memcpy (threads, __pthread_threads,
+  memcpy (threads, GL (dl_pthread_threads),
          __pthread_max_threads * sizeof (struct __pthread *));
 
   /* Save the location of the old table.  We want to deallocate its
      storage after we released the lock.  */
-  old_threads = __pthread_threads;
+  old_threads = GL (dl_pthread_threads);
 
   /* Replace the table with the new one.  */
   __pthread_max_threads = new_max_threads;
-  __pthread_threads = threads;
+  GL (dl_pthread_threads) = threads;
 
   /* And allocate ourselves one of the newly created slots.  */
-  new->thread = 1 + __pthread_num_threads++;
-  __pthread_threads[new->thread - 1] = NULL;
+  new->thread = 1 + GL (dl_pthread_num_threads)++;
+  GL (dl_pthread_threads)[new->thread - 1] = NULL;
 
-  __pthread_rwlock_unlock (&__pthread_threads_lock);
+  lll_unlock (GL (dl_pthread_threads_lock), 0);
 
   free (old_threads);
 
@@ -217,10 +217,10 @@ __pthread_init_static_tls (struct link_map *map)
 {
   int i;
 
-  __pthread_rwlock_wrlock (&__pthread_threads_lock);
-  for (i = 0; i < __pthread_num_threads; ++i)
+  lll_lock (GL (dl_pthread_threads_lock), 0);
+  for (i = 0; i < GL (dl_pthread_num_threads); ++i)
     {
-      struct __pthread *t = __pthread_threads[i];
+      struct __pthread *t = GL (dl_pthread_threads)[i];
 
       if (t == NULL)
        continue;
@@ -237,5 +237,5 @@ __pthread_init_static_tls (struct link_map *map)
       memset (__mempcpy (dest, map->l_tls_initimage, 
map->l_tls_initimage_size),
              '\0', map->l_tls_blocksize - map->l_tls_initimage_size);
     }
-  __pthread_rwlock_unlock (&__pthread_threads_lock);
+  lll_unlock (GL (dl_pthread_threads_lock), 0);
 }
diff --git a/htl/pt-create.c b/htl/pt-create.c
index f0a1f1ab..4e16cbbd 100644
--- a/htl/pt-create.c
+++ b/htl/pt-create.c
@@ -207,7 +207,7 @@ __pthread_create_internal (struct __pthread **thread,
      creating thread.  The set of signals pending for the new thread
      shall be empty."  If the currnet thread is not a pthread then we
      just inherit the process' sigmask.  */
-  if (__pthread_num_threads == 1)
+  if (GL (dl_pthread_num_threads) == 1)
     err = __sigprocmask (0, 0, &pthread->init_sigset);
   else
     err = __pthread_sigstate (_pthread_self (), 0, 0, &pthread->init_sigset, 
0);
@@ -227,13 +227,8 @@ __pthread_create_internal (struct __pthread **thread,
      new thread runs.  */
   atomic_increment (&__pthread_total);
 
-  /* Store a pointer to this thread in the thread ID lookup table.  We
-     could use __thread_setid, however, we only lock for reading as no
-     other thread should be using this entry (we also assume that the
-     store is atomic).  */
-  __pthread_rwlock_rdlock (&__pthread_threads_lock);
-  __pthread_threads[pthread->thread - 1] = pthread;
-  __pthread_rwlock_unlock (&__pthread_threads_lock);
+  /* Store a pointer to this thread in the thread ID lookup table.  */
+  __pthread_setid (pthread->thread, pthread);
 
   /* At this point it is possible to guess our pthread ID.  We have to
      make sure that all functions taking a pthread_t argument can
diff --git a/htl/pt-internal.h b/htl/pt-internal.h
index 34e6da33..5ddda0ab 100644
--- a/htl/pt-internal.h
+++ b/htl/pt-internal.h
@@ -166,33 +166,23 @@ __pthread_dequeue (struct __pthread *thread)
 /* The total number of threads currently active.  */
 extern unsigned int __pthread_total;
 
-/* The total number of thread IDs currently in use, or on the list of
-   available thread IDs.  */
-extern int __pthread_num_threads;
-
 /* Concurrency hint.  */
 extern int __pthread_concurrency;
 
-/* Array of __pthread structures and its lock.  Indexed by the pthread
-   id minus one.  (Why not just use the pthread id?  Because some
-   brain-dead users of the pthread interface incorrectly assume that 0
-   is an invalid pthread id.)  */
-extern struct __pthread **__pthread_threads;
-extern int __pthread_max_threads;
-extern pthread_rwlock_t __pthread_threads_lock;
+extern int  __pthread_max_threads;
 
 #define __pthread_getid(thread) \
-  ({ struct __pthread *__t = NULL;                                           \
-     __pthread_rwlock_rdlock (&__pthread_threads_lock);                      \
-     if (thread <= __pthread_max_threads)                                    \
-       __t = __pthread_threads[thread - 1];                                  \
-     __pthread_rwlock_unlock (&__pthread_threads_lock);                      \
+  ({ struct __pthread *__t = NULL;                 \
+     lll_lock (GL (dl_pthread_threads_lock), 0);   \
+     if (thread <= __pthread_max_threads)          \
+       __t = GL (dl_pthread_threads[thread - 1]);  \
+     lll_unlock (GL (dl_pthread_threads_lock), 0); \
      __t; })
 
 #define __pthread_setid(thread, pthread) \
-  __pthread_rwlock_wrlock (&__pthread_threads_lock);                         \
-  __pthread_threads[thread - 1] = pthread;                                   \
-  __pthread_rwlock_unlock (&__pthread_threads_lock);
+  lll_lock (GL (dl_pthread_threads_lock), 0);    \
+  GL (dl_pthread_threads)[thread - 1] = pthread; \
+  lll_unlock (GL (dl_pthread_threads_lock), 0);
 
 /* Similar to pthread_self, but returns the thread descriptor instead
    of the thread ID.  */
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
index 7e087763..4604d00b 100644
--- a/sysdeps/generic/ldsodefs.h
+++ b/sysdeps/generic/ldsodefs.h
@@ -484,7 +484,13 @@ struct rtld_global
   /* Mutex protecting the stack lists.  */
   EXTERN int _dl_stack_cache_lock;
 #else
-  EXTERN int _dl_thread_gscope_count;
+  /* The total number of thread IDs currently in use, or on the list of
+     available thread IDs.  */
+  EXTERN int _dl_pthread_num_threads;
+
+  /* Array of __pthread structures and its lock. */
+  EXTERN struct __pthread **_dl_pthread_threads;
+  EXTERN int _dl_pthread_threads_lock;
 #endif
 #ifdef SHARED
 };
diff --git a/sysdeps/htl/pt-key-delete.c b/sysdeps/htl/pt-key-delete.c
index 4e77ef75..de2b04f1 100644
--- a/sysdeps/htl/pt-key-delete.c
+++ b/sysdeps/htl/pt-key-delete.c
@@ -39,12 +39,12 @@ __pthread_key_delete (pthread_key_t key)
       __pthread_key_destructors[key] = PTHREAD_KEY_INVALID;
       __pthread_key_invalid_count++;
 
-      __pthread_rwlock_rdlock (&__pthread_threads_lock);
-      for (i = 0; i < __pthread_num_threads; ++i)
+      lll_lock (GL (dl_pthread_threads_lock), 0);
+      for (i = 0; i < GL (dl_pthread_num_threads); ++i)
        {
          struct __pthread *t;
 
-         t = __pthread_threads[i];
+         t = GL (dl_pthread_threads)[i];
 
          if (t == NULL)
            continue;
@@ -54,7 +54,7 @@ __pthread_key_delete (pthread_key_t key)
          if (key < t->thread_specifics_size)
            t->thread_specifics[key] = 0;
        }
-      __pthread_rwlock_unlock (&__pthread_threads_lock);
+      lll_unlock (GL (dl_pthread_threads_lock), 0);
     }
 
   __pthread_mutex_unlock (&__pthread_key_lock);
diff --git a/sysdeps/htl/pthreadP.h b/sysdeps/htl/pthreadP.h
index 8e2cf2ce..45b00dec 100644
--- a/sysdeps/htl/pthreadP.h
+++ b/sysdeps/htl/pthreadP.h
@@ -33,7 +33,7 @@ extern void __pthread_init_static_tls (struct link_map *) 
attribute_hidden;
 
 extern pthread_t __pthread_self (void);
 extern int __pthread_kill (pthread_t threadid, int signo);
-extern struct __pthread **__pthread_threads;
+// extern struct __pthread ** GL (dl_pthread_threads);
 
 extern int __pthread_mutex_init (pthread_mutex_t *__mutex, const 
pthread_mutexattr_t *__attr);
 extern int __pthread_mutex_destroy (pthread_mutex_t *__mutex);
diff --git a/sysdeps/htl/raise.c b/sysdeps/htl/raise.c
index 6594d087..d53cd3f3 100644
--- a/sysdeps/htl/raise.c
+++ b/sysdeps/htl/raise.c
@@ -18,13 +18,18 @@
    License along with this program.  If not, see
    <https://www.gnu.org/licenses/>.  */
 
+#include <ldsodefs.h>
 #include <pthreadP.h>
 #include <signal.h>
 #include <unistd.h>
 
 #pragma weak __pthread_kill
 #pragma weak __pthread_self
-#pragma weak __pthread_threads
+
+#ifndef SHARED
+#pragma weak _dl_pthread_threads
+#endif
+
 int
 raise (int signo)
 {
@@ -32,7 +37,7 @@ raise (int signo)
      "the effect of the raise() function shall be equivalent to
      calling: pthread_kill(pthread_self(), sig);"  */
 
-  if (__pthread_kill != NULL && __pthread_threads != NULL)
+  if (__pthread_kill != NULL && GL (dl_pthread_threads) != NULL)
     {
       int err;
       err = __pthread_kill (__pthread_self (), signo);
diff --git a/sysdeps/htl/thrd_current.c b/sysdeps/htl/thrd_current.c
index eecb86af..f52b8229 100644
--- a/sysdeps/htl/thrd_current.c
+++ b/sysdeps/htl/thrd_current.c
@@ -17,14 +17,18 @@
    <https://www.gnu.org/licenses/>.  */
 
 #include "thrd_priv.h"
+#include <ldsodefs.h>
 
 #pragma weak __pthread_self
-#pragma weak __pthread_threads
+
+#ifndef SHARED
+#pragma weak _dl_pthread_threads
+#endif
 
 thrd_t
 thrd_current (void)
 {
-  if (__pthread_threads)
+  if (GL (dl_pthread_threads))
     return (thrd_t) __pthread_self ();
 
   return (thrd_t) 0;
diff --git a/sysdeps/mach/hurd/htl/pt-sigstate-init.c 
b/sysdeps/mach/hurd/htl/pt-sigstate-init.c
index 399068ca..6f43ade6 100644
--- a/sysdeps/mach/hurd/htl/pt-sigstate-init.c
+++ b/sysdeps/mach/hurd/htl/pt-sigstate-init.c
@@ -37,7 +37,7 @@ __pthread_sigstate_init (struct __pthread *thread)
       struct hurd_sigstate *ss = _hurd_thread_sigstate (thread->kernel_thread);
       _hurd_sigstate_set_global_rcv (ss);
     }
-  else if (__pthread_num_threads >= 2)
+  else if (GL (dl_pthread_num_threads) >= 2)
     do_init_global = 1;
 
   return 0;
diff --git a/sysdeps/mach/hurd/htl/pt-sysdep.c 
b/sysdeps/mach/hurd/htl/pt-sysdep.c
index 03ff8079..2fd0a8d6 100644
--- a/sysdeps/mach/hurd/htl/pt-sysdep.c
+++ b/sysdeps/mach/hurd/htl/pt-sysdep.c
@@ -45,7 +45,7 @@ _init_routine (void *stack)
   int err;
   pthread_attr_t attr, *attrp = 0;
 
-  if (__pthread_threads != NULL)
+  if (GL (dl_pthread_threads) != NULL)
     /* Already initialized */
     return;
 
diff --git a/sysdeps/mach/hurd/htl/pt-sysdep.h 
b/sysdeps/mach/hurd/htl/pt-sysdep.h
index acd4fce9..d90563af 100644
--- a/sysdeps/mach/hurd/htl/pt-sysdep.h
+++ b/sysdeps/mach/hurd/htl/pt-sysdep.h
@@ -37,7 +37,7 @@ extern __thread struct __pthread *___pthread_self;
        ({                                                         \
          struct __pthread *thread;                                \
                                                                   \
-         assert (__pthread_threads);                              \
+         assert (GL (dl_pthread_threads));                        \
          thread = ___pthread_self;                                \
                                                                   \
          assert (thread);                                         \
-- 
2.31.1




reply via email to

[Prev in Thread] Current Thread [Next in Thread]