diff mbox

malloc: Rewrite with explicit TLS access using __thread

Message ID 5620CE96.6080906@redhat.com
State New
Headers show

Commit Message

Florian Weimer Oct. 16, 2015, 10:16 a.m. UTC
The generated assembly is basically the same.  The only differences are
due to the changed variable name and changed line numbers in asserts.

Florian

Comments

Mike Frysinger Oct. 17, 2015, 2:48 a.m. UTC | #1
OK
-mike
diff mbox

Patch

2015-10-16  Florian Weimer  <fweimer@redhat.com>

	malloc: Rewrite with explicit TLS access using __thread.
	* sysdeps/generic/malloc-machine.h (tsd_key_t, tsd_key_create)
	(tsd_setspecific, tsd_getspecific): Remove.
	* sysdeps/mach/hurd/malloc-machine.h (tsd_key_t, tsd_key_create)
	(tsd_setspecific, tsd_getspecific): Likewise.
	* sysdeps/nptl/malloc-machine.h (tsd_key_t, tsd_key_create)
	(tsd_setspecific, tsd_getspecific): Likewise.
	* malloc/arena.c (thread_arena): New TLS variable.
	(arena_key): Remove variable.
	(arena_get): Use thread_arena.
	(arena_lookup): Remove macro.
	(malloc_atfork, free_atfork, ptmalloc_lock_all)
	(ptmalloc_unlock_all, ptmalloc_unlock_all2, ptmalloc_init)
	(_int_new_arena, get_free_list, reused_arena)
	(arena_thread_freeres): Use thread_arena.
	* manual/memory.texi (Basic Allocation): Remove arena_lookup,
	tsd_getspecific, tsd_setspecific from safety annotations.
	(Allocating Cleared Space): Remove arena_lookup from safety
	annotations.

diff --git a/malloc/arena.c b/malloc/arena.c
index cb45a04..caf718d 100644
--- a/malloc/arena.c
+++ b/malloc/arena.c
@@ -64,9 +64,12 @@  extern int sanity_check_heap_info_alignment[(sizeof (heap_info)
                                              + 2 * SIZE_SZ) % MALLOC_ALIGNMENT
                                             ? -1 : 1];
 
-/* Thread specific data */
+/* Thread specific data.  */
+
+static __thread mstate thread_arena attribute_tls_model_ie;
+
+/* Arena free list.  */
 
-static tsd_key_t arena_key;
 static mutex_t list_lock = MUTEX_INITIALIZER;
 static size_t narenas = 1;
 static mstate free_list;
@@ -89,15 +92,10 @@  int __malloc_initialized = -1;
    in the new arena. */
 
 #define arena_get(ptr, size) do { \
-      arena_lookup (ptr);						      \
+      ptr = thread_arena;						      \
       arena_lock (ptr, size);						      \
   } while (0)
 
-#define arena_lookup(ptr) do { \
-      void *vptr = NULL;						      \
-      ptr = (mstate) tsd_getspecific (arena_key, vptr);			      \
-  } while (0)
-
 #define arena_lock(ptr, size) do {					      \
       if (ptr && !arena_is_corrupt (ptr))				      \
         (void) mutex_lock (&ptr->mutex);				      \
@@ -138,11 +136,9 @@  ATFORK_MEM;
 static void *
 malloc_atfork (size_t sz, const void *caller)
 {
-  void *vptr = NULL;
   void *victim;
 
-  tsd_getspecific (arena_key, vptr);
-  if (vptr == ATFORK_ARENA_PTR)
+  if (thread_arena == ATFORK_ARENA_PTR)
     {
       /* We are the only thread that may allocate at all.  */
       if (save_malloc_hook != malloc_check)
@@ -172,7 +168,6 @@  malloc_atfork (size_t sz, const void *caller)
 static void
 free_atfork (void *mem, const void *caller)
 {
-  void *vptr = NULL;
   mstate ar_ptr;
   mchunkptr p;                          /* chunk corresponding to mem */
 
@@ -188,8 +183,7 @@  free_atfork (void *mem, const void *caller)
     }
 
   ar_ptr = arena_for_chunk (p);
-  tsd_getspecific (arena_key, vptr);
-  _int_free (ar_ptr, p, vptr == ATFORK_ARENA_PTR);
+  _int_free (ar_ptr, p, thread_arena == ATFORK_ARENA_PTR);
 }
 
 
@@ -212,9 +206,7 @@  ptmalloc_lock_all (void)
 
   if (mutex_trylock (&list_lock))
     {
-      void *my_arena;
-      tsd_getspecific (arena_key, my_arena);
-      if (my_arena == ATFORK_ARENA_PTR)
+      if (thread_arena == ATFORK_ARENA_PTR)
         /* This is the same thread which already locks the global list.
            Just bump the counter.  */
         goto out;
@@ -234,8 +226,8 @@  ptmalloc_lock_all (void)
   __malloc_hook = malloc_atfork;
   __free_hook = free_atfork;
   /* Only the current thread may perform malloc/free calls now. */
-  tsd_getspecific (arena_key, save_arena);
-  tsd_setspecific (arena_key, ATFORK_ARENA_PTR);
+  save_arena = thread_arena;
+  thread_arena = ATFORK_ARENA_PTR;
 out:
   ++atfork_recursive_cntr;
 }
@@ -251,7 +243,7 @@  ptmalloc_unlock_all (void)
   if (--atfork_recursive_cntr != 0)
     return;
 
-  tsd_setspecific (arena_key, save_arena);
+  thread_arena = save_arena;
   __malloc_hook = save_malloc_hook;
   __free_hook = save_free_hook;
   for (ar_ptr = &main_arena;; )
@@ -279,7 +271,7 @@  ptmalloc_unlock_all2 (void)
   if (__malloc_initialized < 1)
     return;
 
-  tsd_setspecific (arena_key, save_arena);
+  thread_arena = save_arena;
   __malloc_hook = save_malloc_hook;
   __free_hook = save_free_hook;
   free_list = NULL;
@@ -372,8 +364,7 @@  ptmalloc_init (void)
     __morecore = __failing_morecore;
 #endif
 
-  tsd_key_create (&arena_key, NULL);
-  tsd_setspecific (arena_key, (void *) &main_arena);
+  thread_arena = &main_arena;
   thread_atfork (ptmalloc_lock_all, ptmalloc_unlock_all, ptmalloc_unlock_all2);
   const char *s = NULL;
   if (__glibc_likely (_environ != NULL))
@@ -761,7 +752,7 @@  _int_new_arena (size_t size)
   set_head (top (a), (((char *) h + h->size) - ptr) | PREV_INUSE);
 
   LIBC_PROBE (memory_arena_new, 2, a, size);
-  tsd_setspecific (arena_key, (void *) a);
+  thread_arena = a;
   mutex_init (&a->mutex);
   (void) mutex_lock (&a->mutex);
 
@@ -794,7 +785,7 @@  get_free_list (void)
         {
           LIBC_PROBE (memory_arena_reuse_free_list, 1, result);
           (void) mutex_lock (&result->mutex);
-          tsd_setspecific (arena_key, (void *) result);
+	  thread_arena = result;
         }
     }
 
@@ -847,7 +838,7 @@  reused_arena (mstate avoid_arena)
 
 out:
   LIBC_PROBE (memory_arena_reuse, 2, result, avoid_arena);
-  tsd_setspecific (arena_key, (void *) result);
+  thread_arena = result;
   next_to_use = result->next;
 
   return result;
@@ -934,9 +925,8 @@  arena_get_retry (mstate ar_ptr, size_t bytes)
 static void __attribute__ ((section ("__libc_thread_freeres_fn")))
 arena_thread_freeres (void)
 {
-  void *vptr = NULL;
-  mstate a = tsd_getspecific (arena_key, vptr);
-  tsd_setspecific (arena_key, NULL);
+  mstate a = thread_arena;
+  thread_arena = NULL;
 
   if (a != NULL)
     {
diff --git a/manual/memory.texi b/manual/memory.texi
index 0729e70..cea2cd7 100644
--- a/manual/memory.texi
+++ b/manual/memory.texi
@@ -332,8 +332,6 @@  this function is in @file{stdlib.h}.
 @c __libc_malloc @asulock @aculock @acsfd @acsmem
 @c  force_reg ok
 @c  *malloc_hook unguarded
-@c  arena_lookup ok
-@c   tsd_getspecific ok, TLS
 @c  arena_lock @asulock @aculock @acsfd @acsmem
 @c   mutex_lock @asulock @aculock
 @c   arena_get2 @asulock @aculock @acsfd @acsmem
@@ -341,7 +339,6 @@  this function is in @file{stdlib.h}.
 @c     mutex_lock (list_lock) dup @asulock @aculock
 @c     mutex_unlock (list_lock) dup @aculock
 @c     mutex_lock (arena lock) dup @asulock @aculock [returns locked]
-@c     tsd_setspecific ok, TLS
 @c    __get_nprocs ext ok @acsfd
 @c    NARENAS_FROM_NCORES ok
 @c    catomic_compare_and_exchange_bool_acq ok
@@ -835,7 +832,6 @@  is declared in @file{stdlib.h}.
 @c  *__malloc_hook dup unguarded
 @c  memset dup ok
 @c  arena_get @asulock @aculock @acsfd @acsmem
-@c   arena_lookup dup ok
 @c   arena_lock dup @asulock @aculock @acsfd @acsmem
 @c  top dup ok
 @c  chunksize dup ok
diff --git a/sysdeps/generic/malloc-machine.h b/sysdeps/generic/malloc-machine.h
index 10f6e72..802d1f5 100644
--- a/sysdeps/generic/malloc-machine.h
+++ b/sysdeps/generic/malloc-machine.h
@@ -40,13 +40,6 @@  typedef int mutex_t;
 # define mutex_unlock(m)        (*(m) = 0)
 # define MUTEX_INITIALIZER      (0)
 
-typedef void *tsd_key_t;
-# define tsd_key_create(key, destr) do {} while(0)
-# define tsd_setspecific(key, data) ((key) = (data))
-# define tsd_getspecific(key, vptr) (vptr = (key))
-
-# define thread_atfork(prepare, parent, child) do {} while(0)
-
 #endif /* !defined mutex_init */
 
 #ifndef atomic_full_barrier
diff --git a/sysdeps/mach/hurd/malloc-machine.h b/sysdeps/mach/hurd/malloc-machine.h
index 1fdbd3d..9221d1b 100644
--- a/sysdeps/mach/hurd/malloc-machine.h
+++ b/sysdeps/mach/hurd/malloc-machine.h
@@ -52,16 +52,6 @@ 
 /* No we're *not* using pthreads.  */
 #define __pthread_initialize ((void (*)(void))0)
 
-/* thread specific data for glibc */
-
-#include <libc-tsd.h>
-
-typedef int tsd_key_t[1];	/* no key data structure, libc magic does it */
-__libc_tsd_define (static, void *, MALLOC)	/* declaration/common definition */
-#define tsd_key_create(key, destr)	((void) (key))
-#define tsd_setspecific(key, data)	__libc_tsd_set (void *, MALLOC, (data))
-#define tsd_getspecific(key, vptr)	((vptr) = __libc_tsd_get (void *, MALLOC))
-
 /* madvise is a stub on Hurd, so don't bother calling it.  */
 
 #include <sys/mman.h>
diff --git a/sysdeps/nptl/malloc-machine.h b/sysdeps/nptl/malloc-machine.h
index c0ec49e..8dea606 100644
--- a/sysdeps/nptl/malloc-machine.h
+++ b/sysdeps/nptl/malloc-machine.h
@@ -58,16 +58,6 @@  extern void *__dso_handle __attribute__ ((__weak__));
   __linkin_atfork (&atfork_mem)
 #endif
 
-/* thread specific data for glibc */
-
-#include <libc-tsd.h>
-
-typedef int tsd_key_t[1];	/* no key data structure, libc magic does it */
-__libc_tsd_define (static, void *, MALLOC)	/* declaration/common definition */
-#define tsd_key_create(key, destr)	((void) (key))
-#define tsd_setspecific(key, data)	__libc_tsd_set (void *, MALLOC, (data))
-#define tsd_getspecific(key, vptr)	((vptr) = __libc_tsd_get (void *, MALLOC))
-
 #include <sysdeps/generic/malloc-machine.h>
 
 #endif /* !defined(_MALLOC_MACHINE_H) */