public inbox for glibc-cvs@sourceware.org
help / color / mirror / Atom feed
* [glibc] htl: Add support for static TSD data
@ 2023-08-08 11:16 Samuel Thibault
  0 siblings, 0 replies; only message in thread
From: Samuel Thibault @ 2023-08-08 11:16 UTC (permalink / raw)
  To: glibc-cvs

https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=644aa127b9b42a899a12b6ccc6644bc035c231e3

commit 644aa127b9b42a899a12b6ccc6644bc035c231e3
Author: Samuel Thibault <samuel.thibault@ens-lyon.org>
Date:   Tue Aug 8 12:10:06 2023 +0200

    htl: Add support for static TSD data
    
    When using jemalloc, malloc() needs to use TSD, while libpthread
    initialization needs malloc(). Supporting a static TSD area allows jemalloc
    and libpthread to initialize together.

Diff:
---
 sysdeps/htl/pt-destroy-specific.c | 35 ++++++++++++++++++++++++++++++-----
 sysdeps/htl/pt-getspecific.c      |  8 ++++++++
 sysdeps/htl/pt-init-specific.c    |  2 ++
 sysdeps/htl/pt-key-create.c       | 25 +++++++++++++++++--------
 sysdeps/htl/pt-key-delete.c       | 12 ++++++++++--
 sysdeps/htl/pt-key.h              |  7 ++++++-
 sysdeps/htl/pt-setspecific.c      | 26 ++++++++++++++++++++++++--
 7 files changed, 97 insertions(+), 18 deletions(-)

diff --git a/sysdeps/htl/pt-destroy-specific.c b/sysdeps/htl/pt-destroy-specific.c
index 7c1acb5068..6d1ad6baed 100644
--- a/sysdeps/htl/pt-destroy-specific.c
+++ b/sysdeps/htl/pt-destroy-specific.c
@@ -29,7 +29,16 @@ __pthread_destroy_specific (struct __pthread *thread)
 
   /* Check if there is any thread specific data.  */
   if (thread->thread_specifics == NULL)
-    return;
+    {
+      for (i = 0; i < PTHREAD_STATIC_KEYS; i++)
+	{
+	  if (thread->static_thread_specifics[i] != NULL)
+	    break;
+	}
+
+      if (i == PTHREAD_STATIC_KEYS)
+	return;
+    }
 
   __pthread_key_lock_ready ();
 
@@ -40,18 +49,32 @@ __pthread_destroy_specific (struct __pthread *thread)
 
       __pthread_mutex_lock (&__pthread_key_lock);
 
-      for (i = 0; i < __pthread_key_count && i < thread->thread_specifics_size;
-	   i++)
+      for (i = 0; i < __pthread_key_count; i++)
 	{
 	  void *value;
 
 	  if (__pthread_key_destructors[i] == PTHREAD_KEY_INVALID)
 	    continue;
 
-	  value = thread->thread_specifics[i];
+	  if (thread->thread_specifics == NULL)
+	    {
+	      if (i >= PTHREAD_STATIC_KEYS)
+		break;
+	      value = thread->static_thread_specifics[i];
+	    }
+	  else
+	    {
+	      if (i >= thread->thread_specifics_size)
+		break;
+	      value = thread->thread_specifics[i];
+	    }
+
 	  if (value != NULL)
 	    {
-	      thread->thread_specifics[i] = 0;
+	      if (thread->thread_specifics == NULL)
+		thread->static_thread_specifics[i] = 0;
+	      else
+		thread->thread_specifics[i] = 0;
 
 	      if (__pthread_key_destructors[i])
 		{
@@ -74,4 +97,6 @@ __pthread_destroy_specific (struct __pthread *thread)
   free (thread->thread_specifics);
   thread->thread_specifics = 0;
   thread->thread_specifics_size = 0;
+  memset (&thread->static_thread_specifics, 0,
+	  sizeof (thread->static_thread_specifics));
 }
diff --git a/sysdeps/htl/pt-getspecific.c b/sysdeps/htl/pt-getspecific.c
index 68a2503563..4d42cba93d 100644
--- a/sysdeps/htl/pt-getspecific.c
+++ b/sysdeps/htl/pt-getspecific.c
@@ -29,6 +29,14 @@ __pthread_getspecific (pthread_key_t key)
     return NULL;
 
   self = _pthread_self ();
+
+  if (self->thread_specifics == NULL)
+    {
+      if (key >= PTHREAD_STATIC_KEYS)
+	return NULL;
+      return self->static_thread_specifics[key];
+    }
+
   if (key >= self->thread_specifics_size)
     return 0;
 
diff --git a/sysdeps/htl/pt-init-specific.c b/sysdeps/htl/pt-init-specific.c
index 8c4d23cb13..ed6c6f2d0c 100644
--- a/sysdeps/htl/pt-init-specific.c
+++ b/sysdeps/htl/pt-init-specific.c
@@ -26,5 +26,7 @@ __pthread_init_specific (struct __pthread *thread)
 {
   thread->thread_specifics = 0;
   thread->thread_specifics_size = 0;
+  memset (&thread->static_thread_specifics, 0,
+	  sizeof (thread->static_thread_specifics));
   return 0;
 }
diff --git a/sysdeps/htl/pt-key-create.c b/sysdeps/htl/pt-key-create.c
index 51c0ef72b8..b7057434e3 100644
--- a/sysdeps/htl/pt-key-create.c
+++ b/sysdeps/htl/pt-key-create.c
@@ -26,10 +26,11 @@
 pthread_mutex_t __pthread_key_lock;
 pthread_once_t __pthread_key_once = PTHREAD_ONCE_INIT;
 
-void (**__pthread_key_destructors) (void *arg);
-int __pthread_key_size;
+void (*__pthread_static_key_destructors [PTHREAD_STATIC_KEYS]) (void *arg);
+void (**__pthread_key_destructors) (void *arg) = __pthread_static_key_destructors;
+int __pthread_key_size = PTHREAD_STATIC_KEYS;
 int __pthread_key_count;
-int __pthread_key_invalid_count;
+int __pthread_key_invalid_count = PTHREAD_STATIC_KEYS;
 
 int
 __pthread_key_create (pthread_key_t *key, void (*destructor) (void *))
@@ -80,13 +81,21 @@ do_search:
 	void *t;
 	int newsize;
 
-	if (__pthread_key_size == 0)
-	  newsize = 8;
+	newsize = __pthread_key_size * 2;
+
+	if (__pthread_key_destructors == __pthread_static_key_destructors)
+	  {
+	    /* We were still using the static array.  Switch to dynamic.  */
+	    t = malloc (newsize * sizeof (*__pthread_key_destructors));
+
+	    if (t != NULL)
+	      memcpy (t, __pthread_key_destructors,
+		      __pthread_key_size * sizeof (*__pthread_key_destructors));
+	  }
 	else
-	  newsize = __pthread_key_size * 2;
+	  t = realloc (__pthread_key_destructors,
+		       newsize * sizeof (*__pthread_key_destructors));
 
-	t = realloc (__pthread_key_destructors,
-		     newsize * sizeof (*__pthread_key_destructors));
 	if (t == NULL)
 	  {
 	    __pthread_mutex_unlock (&__pthread_key_lock);
diff --git a/sysdeps/htl/pt-key-delete.c b/sysdeps/htl/pt-key-delete.c
index ce77a573c2..6d128d2aaf 100644
--- a/sysdeps/htl/pt-key-delete.c
+++ b/sysdeps/htl/pt-key-delete.c
@@ -51,8 +51,16 @@ __pthread_key_delete (pthread_key_t key)
 
 	  /* Just remove the key, no need to care whether it was
 	     already there. */
-	  if (key < t->thread_specifics_size)
-	    t->thread_specifics[key] = 0;
+	  if (t->thread_specifics == NULL)
+	    {
+	      if (key < PTHREAD_STATIC_KEYS)
+		t->static_thread_specifics[key] = 0;
+	    }
+	  else
+	    {
+	      if (key < t->thread_specifics_size)
+		t->thread_specifics[key] = 0;
+	    }
 	}
       __libc_rwlock_unlock (GL (dl_pthread_threads_lock));
     }
diff --git a/sysdeps/htl/pt-key.h b/sysdeps/htl/pt-key.h
index 262006de9f..047b7e24ba 100644
--- a/sysdeps/htl/pt-key.h
+++ b/sysdeps/htl/pt-key.h
@@ -20,9 +20,14 @@
 #include <libc-lockP.h>
 #include <pthreadP.h>
 
+/* When using e.g. jemalloc, we need to be able to create and use keys before
+   being able to allocate.  */
+#define PTHREAD_STATIC_KEYS 4
+
 #define PTHREAD_KEY_MEMBERS \
   void **thread_specifics;		/* This is only resized by the thread, and always growing */ \
-  unsigned thread_specifics_size;	/* Number of entries in thread_specifics */
+  unsigned thread_specifics_size;	/* Number of entries in thread_specifics */ \
+  void *static_thread_specifics[PTHREAD_STATIC_KEYS];	/* Static storage for a few entries */
 
 #define PTHREAD_KEY_INVALID (void *) (-1)
 
diff --git a/sysdeps/htl/pt-setspecific.c b/sysdeps/htl/pt-setspecific.c
index 2b9a89dc70..30550e09c7 100644
--- a/sysdeps/htl/pt-setspecific.c
+++ b/sysdeps/htl/pt-setspecific.c
@@ -28,12 +28,34 @@ __pthread_setspecific (pthread_key_t key, const void *value)
   if (key < 0 || key >= __pthread_key_count)
     return EINVAL;
 
+  if (self->thread_specifics == NULL)
+    {
+      if (key < PTHREAD_STATIC_KEYS)
+	{
+	  self->static_thread_specifics[key] = (void *) value;
+	  return 0;
+	}
+    }
+
   if (key >= self->thread_specifics_size)
     {
       /* Amortize reallocation cost.  */
       int newsize = 2 * key + 1;
-      void **new = realloc (self->thread_specifics,
-			    newsize * sizeof (new[0]));
+      void **new;
+
+      if (self->thread_specifics == NULL)
+	{
+	  self->thread_specifics_size = PTHREAD_STATIC_KEYS;
+	  new = malloc (newsize * sizeof (new[0]));
+	  if (new != NULL)
+	    memcpy (new, self->static_thread_specifics,
+		    PTHREAD_STATIC_KEYS * sizeof (new[0]));
+	}
+      else
+	{
+	  new = realloc (self->thread_specifics,
+			 newsize * sizeof (new[0]));
+	}
       if (new == NULL)
 	return ENOMEM;

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2023-08-08 11:16 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-08-08 11:16 [glibc] htl: Add support for static TSD data Samuel Thibault

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).