]> sourceware.org Git - glibc.git/commitdiff
htl: Move thread table to ld.so
authorSergey Bugaev <bugaevc@gmail.com>
Wed, 15 Sep 2021 17:11:08 +0000 (20:11 +0300)
committerSamuel Thibault <samuel.thibault@ens-lyon.org>
Wed, 15 Sep 2021 23:04:05 +0000 (01:04 +0200)
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.

Signed-off-by: Sergey Bugaev <bugaevc@gmail.com>
Message-Id: <20210915171110.226187-2-bugaevc@gmail.com>
Reviewed-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
13 files changed:
htl/Versions
htl/pt-alloc.c
htl/pt-create.c
htl/pt-internal.h
sysdeps/generic/ldsodefs.h
sysdeps/htl/dl-support.c [new file with mode: 0644]
sysdeps/htl/pt-key-delete.c
sysdeps/htl/pthreadP.h
sysdeps/htl/raise.c
sysdeps/htl/thrd_current.c
sysdeps/mach/hurd/htl/pt-sigstate-init.c
sysdeps/mach/hurd/htl/pt-sysdep.c
sysdeps/mach/hurd/htl/pt-sysdep.h

index 4aea3210164fb8e07a4a983900d530b74210e97f..4e0ebac28546a6b92774a9951cecfece0b935549 100644 (file)
@@ -168,8 +168,6 @@ libpthread {
   GLIBC_PRIVATE {
     __pthread_initialize_minimal;
 
-    __pthread_threads;
-
     __cthread_detach;
     __cthread_fork;
     __pthread_detach;
index acc67f27119b3a1940bb2995879d9ffb2a89373d..f6e783be103f0594cca54fae2e50df1629b711e8 100644 (file)
    of the threads functions "shall fail" if "No thread could be found
    corresponding to that specified by the given thread ID."  */
 
-/* Thread ID lookup table.  */
-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;
-
-/* A lock for the table, and the other variables above.  */
-pthread_rwlock_t __pthread_threads_lock;
-
 /* List of thread structures corresponding to free thread IDs.  */
 struct __pthread *__pthread_free_threads;
 pthread_mutex_t __pthread_free_threads_lock;
@@ -132,25 +122,25 @@ __pthread_alloc (struct __pthread **pthread)
     }
 
 retry:
-  __pthread_rwlock_wrlock (&__pthread_threads_lock);
+  __libc_rwlock_wrlock (GL (dl_pthread_threads_lock));
 
-  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);
+      __libc_rwlock_unlock (GL (dl_pthread_threads_lock));
 
       *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);
+      __libc_rwlock_unlock (GL (dl_pthread_threads_lock));
 
       free (new);
       return EAGAIN;
@@ -162,7 +152,7 @@ retry:
      memory allocation, since that's a potentially blocking operation.  */
   max_threads = __pthread_max_threads;
 
-  __pthread_rwlock_unlock (&__pthread_threads_lock);
+  __libc_rwlock_unlock (GL (dl_pthread_threads_lock));
 
   /* Allocate a new lookup table that's twice as large.  */
   new_max_threads
@@ -174,13 +164,13 @@ retry:
       return ENOMEM;
     }
 
-  __pthread_rwlock_wrlock (&__pthread_threads_lock);
+  __libc_rwlock_wrlock (GL (dl_pthread_threads_lock));
 
   /* Check if nobody else has already enlarged the table.  */
   if (max_threads != __pthread_max_threads)
     {
       /* Yep, they did.  */
-      __pthread_rwlock_unlock (&__pthread_threads_lock);
+      __libc_rwlock_unlock (GL (dl_pthread_threads_lock));
 
       /* Free the newly allocated table and try again to allocate a slot.  */
       free (threads);
@@ -188,22 +178,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);
+  __libc_rwlock_unlock (GL (dl_pthread_threads_lock));
 
   free (old_threads);
 
@@ -217,10 +207,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)
+  __libc_rwlock_wrlock (GL (dl_pthread_threads_lock));
+  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 +227,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);
+  __libc_rwlock_unlock (GL (dl_pthread_threads_lock));
 }
index f0a1f1ab091a6d4f0e64c0b9f2cf36a69719aa24..a6c9ab3e93e2d4796df2fe4db425cf3ee8c0f77a 100644 (file)
@@ -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);
@@ -231,9 +231,9 @@ __pthread_create_internal (struct __pthread **thread,
      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);
+  __libc_rwlock_rdlock (GL (dl_pthread_threads_lock));
+  GL (dl_pthread_threads)[pthread->thread - 1] = pthread;
+  __libc_rwlock_unlock (GL (dl_pthread_threads_lock));
 
   /* 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
index 34e6da338e50f64e61ad6d83a86817eff17916b6..b17f12b7337a3b26c87f1abfb0ad1a8adb729729 100644 (file)
@@ -166,33 +166,24 @@ __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;
+/* The size of the thread ID lookup table.  */
 extern int __pthread_max_threads;
-extern pthread_rwlock_t __pthread_threads_lock;
 
 #define __pthread_getid(thread) \
   ({ struct __pthread *__t = NULL;                                           \
-     __pthread_rwlock_rdlock (&__pthread_threads_lock);                      \
+     __libc_rwlock_rdlock (GL (dl_pthread_threads_lock));                    \
      if (thread <= __pthread_max_threads)                                    \
-       __t = __pthread_threads[thread - 1];                                  \
-     __pthread_rwlock_unlock (&__pthread_threads_lock);                      \
+       __t = GL (dl_pthread_threads)[thread - 1];                            \
+     __libc_rwlock_unlock (GL (dl_pthread_threads_lock));                    \
      __t; })
 
 #define __pthread_setid(thread, pthread) \
-  __pthread_rwlock_wrlock (&__pthread_threads_lock);                         \
-  __pthread_threads[thread - 1] = pthread;                                   \
-  __pthread_rwlock_unlock (&__pthread_threads_lock);
+  __libc_rwlock_wrlock (GL (dl_pthread_threads_lock));                       \
+  GL (dl_pthread_threads)[thread - 1] = pthread;                             \
+  __libc_rwlock_unlock (GL (dl_pthread_threads_lock));
 
 /* Similar to pthread_self, but returns the thread descriptor instead
    of the thread ID.  */
index 02bd579ef89cf869f62fb126dbb88709cd4b7232..f01b601d636c01c6601fd15d3f4e175fcc6e94fc 100644 (file)
@@ -486,7 +486,16 @@ struct rtld_global
 
   /* Mutex protecting the stack lists.  */
   EXTERN int _dl_stack_cache_lock;
+#else
+  /* 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;
+  __libc_rwlock_define (EXTERN, _dl_pthread_threads_lock)
 #endif
+
 #if !THREAD_GSCOPE_IN_TCB
   EXTERN int _dl_thread_gscope_count;
 #endif
diff --git a/sysdeps/htl/dl-support.c b/sysdeps/htl/dl-support.c
new file mode 100644 (file)
index 0000000..7198a3f
--- /dev/null
@@ -0,0 +1,23 @@
+/* Support for dynamic linking code in static libc.
+   Copyright (C) 2007-2021 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
+   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, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <elf/dl-support.c>
+
+int _dl_pthread_num_threads;
+struct __pthread **_dl_pthread_threads;
+__libc_rwlock_define_initialized (, _dl_pthread_threads_lock)
index 4e77ef75218ddb0309bbd78e4c0a7b39c13fc889..9f5907bf13d465b3a263d834b0be1d749b182d5e 100644 (file)
@@ -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)
+      __libc_rwlock_rdlock (GL (dl_pthread_threads_lock));
+      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);
+      __libc_rwlock_unlock (GL (dl_pthread_threads_lock));
     }
 
   __pthread_mutex_unlock (&__pthread_key_lock);
index 3fd774269fa20ed69bf50e649f1b51953e185740..8b02bef3559a4ee714217008a6c475c733cd709c 100644 (file)
@@ -31,8 +31,6 @@ extern void __pthread_init_static_tls (struct link_map *) attribute_hidden;
 
 /* These represent the interface used by glibc itself.  */
 
-extern struct __pthread **__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);
 extern int __pthread_mutex_lock (pthread_mutex_t *__mutex);
index 5a0f37d3b8d488ed8e5799d765ddc65044b43877..8c17db6f655e3d29bbf4e538abea75f7e530c325 100644 (file)
@@ -17,6 +17,7 @@
    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)
 {
@@ -31,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);
index eecb86af85aa57636b6fa7d6937e8561a2bffcca..87359677d6769bcd89292b0d21b6297a683accfc 100644 (file)
    <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;
index 399068ca7855056b28f887ac81f6225bd510d784..6f43ade653a9c2cf908a88c4735be221e5759799 100644 (file)
@@ -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;
index 03ff8079baa16f0e0bafcfc40f0599bc046000b1..2fd0a8d6e75d3cd065981c0a335b895b10954535 100644 (file)
@@ -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;
 
index acd4fce9c474db69c972e51ff0cfa5e4c4eb2356..d90563af0c4197f0891f7af5689f119aa761b646 100644 (file)
@@ -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);                                         \
This page took 0.064776 seconds and 5 git commands to generate.