Require __thread support in compiler.
authorUlrich Drepper <drepper@redhat.com>
Sun, 11 Jan 2009 02:02:05 +0000 (18:02 -0800)
committerUlrich Drepper <drepper@redhat.com>
Sun, 11 Jan 2009 02:02:05 +0000 (18:02 -0800)
Rename --enable-tls to more appropriate --enable-thread-safety.

14 files changed:
ChangeLog
configure.ac
lib/ChangeLog
lib/eu-config.h
libasm/ChangeLog
libasm/Makefile.am
libasm/asm_error.c
libdw/ChangeLog
libdw/dwarf_error.c
libdwfl/ChangeLog
libdwfl/dwfl_error.c
libelf/ChangeLog
libelf/Makefile.am
libelf/elf_error.c

index 7433b21..554da44 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2009-01-10  Ulrich Drepper  <drepper@redhat.com>
+
+       * configure.ac: Require gcc with TLS support.
+       Rename USE_TLS to USE_LOCKS.  The option is renamed to
+       --enable-thread-safety.
+
 2009-01-08  Roland McGrath  <roland@redhat.com>
 
        * configure.ac (eu_ZIPLIB): Moved to m4/zip.am.
index 6a3b6a7..4b08e10 100644 (file)
@@ -48,13 +48,13 @@ AC_CONFIG_FILES([elfutils.spec:config/elfutils.spec.in])
 
 AC_CANONICAL_HOST
 
-AC_ARG_ENABLE([tls],
-AS_HELP_STRING([--enable-tls], [enable use of thread local storage]),
-use_tls=yes, use_tls=no)
-AM_CONDITIONAL(USE_TLS, test "$use_tls" = yes)
-AS_IF([test "$use_tls" = yes], [AC_DEFINE(USE_TLS)])
+AC_ARG_ENABLE([thread-safety],
+AS_HELP_STRING([--enable-thread-safety], [enable thread safety of libraries]),
+use_tls=locks, use_locks=no)
+AM_CONDITIONAL(USE_LOCKS, test "$use_locks" = yes)
+AS_IF([test "$use_locks" = yes], [AC_DEFINE(USE_LOCKS)])
 
-AH_TEMPLATE([USE_TLS], [Defined if thread local storage should be used.])
+AH_TEMPLATE([USE_LOCKS], [Defined if libraries should be thread-safe.])
 
 dnl Add all the languages for which translations are available.
 ALL_LINGUAS=
@@ -74,6 +74,13 @@ CFLAGS="$old_CFLAGS"])
 AS_IF([test "x$ac_cv_c99" != xyes],
       AC_MSG_ERROR([gcc with C99 support required]))
 
+AC_CACHE_CHECK([for gcc with TLS support], ac_cv_tls, [dnl
+AC_COMPILE_IFELSE([dnl
+__thread int a; int foo (int b) { return a + b; }],
+                 ac_cv_tls=yes, ac_cv_tls=no)])
+AS_IF([test "x$ac_cv_tls" != xyes],
+      AC_MSG_ERROR([gcc with TLS support required]))
+
 LOCALEDIR=$datadir
 AC_SUBST(LOCALEDIR)
 AC_DEFINE_UNQUOTED(LOCALEDIR, "$LOCALEDIR")
index f4c261a..8791640 100644 (file)
@@ -1,3 +1,9 @@
+2009-01-10  Ulrich Drepper  <drepper@redhat.com>
+
+       * eu-config.h: Remove tls_key_t, key_create, getspecific, setspecific,
+       once_define, and once_execute macros.  Use USE_LOCKS instead of
+       USE_TLS.
+
 2008-08-25  Roland McGrath  <roland@redhat.com>
 
        * eu-config.h [USE_TLS] (RWLOCK_CALL): New macro.
index c41cbb0..03dba76 100644 (file)
@@ -1,5 +1,5 @@
 /* Configuration definitions.
-   Copyright (C) 2008 Red Hat, Inc.
+   Copyright (C) 2008, 2009 Red Hat, Inc.
    This file is part of Red Hat elfutils.
 
    Red Hat elfutils is free software; you can redistribute it and/or modify
    Network licensing program, please visit www.openinventionnetwork.com
    <http://www.openinventionnetwork.com>.  */
 
-#ifdef USE_TLS
+#ifdef USE_LOCKS
 # include <pthread.h>
 # include <assert.h>
-# define tls_key_t                     __thread void *
-# define key_create(keyp, freefct)     (1)
-# define getspecific(key)              key
-# define setspecific(key,val)          key = val
-# define once_define(class,name)       class struct { } name
-# define once_execute(name,fct)                ((void) &name, (void) (fct))
 # define rwlock_define(class,name)     class pthread_rwlock_t name
 # define RWLOCK_CALL(call)             \
   ({ int _err = pthread_rwlock_ ## call; assert_perror (_err); })
 /* Eventually we will allow multi-threaded applications to use the
    libraries.  Therefore we will add the necessary locking although
    the macros used expand to nothing for now.  */
-# define lock_lock(lock) ((void) (lock))
 # define rwlock_define(class,name) class int name
 # define rwlock_init(lock) ((void) (lock))
 # define rwlock_fini(lock) ((void) (lock))
 # define rwlock_rdlock(lock) ((void) (lock))
 # define rwlock_wrlock(lock) ((void) (lock))
 # define rwlock_unlock(lock) ((void) (lock))
-# define tls_key_t void *
-# define key_create(keyp, freefct) (1)
-# define getspecific(key) key
-# define setspecific(key,val) key = val
-# define once_define(class,name) class int name
-# define once_execute(name,fct) \
-  do {                                                                       \
-    if (name == 0)                                                           \
-      fct ();                                                                \
-    name = 1;                                                                \
-  } while (0)
-#endif /* USE_TLS */
+#endif /* USE_LOCKS */
 
 /* gettext helper macro.  */
 #define N_(Str) Str
index c98deb6..d0d4039 100644 (file)
@@ -1,3 +1,8 @@
+2009-01-10  Ulrich Drepper  <drepper@redhat.com>
+
+       * Makefile.am: Use USE_LOCKS instead of USE_TLS.
+       * asm_error.c: Always use __thread.  Remove all !USE_TLS code.
+
 2008-12-03  Ulrich Drepper  <drepper@redhat.com>
 
        * Makefile.am [USE_TLS]: Like libasm.so with libpthread.
index 62b5ee2..7d5e25d 100644 (file)
@@ -1,6 +1,6 @@
 ## Process this file with automake to create Makefile.in
 ##
-## Copyright (C) 2002, 2004, 2005, 2006, 2008 Red Hat, Inc.
+## Copyright (C) 2002, 2004, 2005, 2006, 2008, 2009 Red Hat, Inc.
 ## This file is part of Red Hat elfutils.
 ##
 ## Red Hat elfutils is free software; you can redistribute it and/or modify
@@ -66,7 +66,7 @@ libasm_pic_a_SOURCES =
 am_libasm_pic_a_OBJECTS = $(libasm_a_SOURCES:.c=.os)
 
 libasm_so_LDLIBS =
-if USE_TLS
+if USE_LOCKS
 libasm_so_LDLIBS += -lpthread
 endif
 
index 29c54cb..4d249e9 100644 (file)
@@ -1,5 +1,5 @@
 /* Error handling in libasm.
-   Copyright (C) 2002, 2004, 2005 Red Hat, Inc.
+   Copyright (C) 2002, 2004, 2005, 2009 Red Hat, Inc.
    This file is part of Red Hat elfutils.
    Written by Ulrich Drepper <drepper@redhat.com>, 2002.
 
 
 
 /* This is the key for the thread specific memory.  */
-static tls_key_t key;
-
-/* The error number.  Used in non-threaded programs.  */
-static int global_error;
-static bool threaded;
-/* We need to initialize the thread-specific data.  */
-once_define (static, once);
-
-/* The initialization and destruction functions.  */
-static void init (void);
-static void free_key_mem (void *mem);
+static __thread int global_error;
 
 
 int
 asm_errno (void)
 {
-  int result;
-
-  /* If we have not yet initialized the buffer do it now.  */
-  once_execute (once, init);
-
-  if (threaded)
-    {
-      /* We have a key.  Use it to get the thread-specific buffer.  */
-      int *buffer = getspecific (key);
-      if (buffer == NULL)
-       {
-         /* No buffer allocated so far.  */
-         buffer = (int *) malloc (sizeof (int));
-         if (buffer == NULL)
-           /* No more memory available.  We use the static buffer.  */
-           buffer = &global_error;
-
-         setspecific (key, buffer);
-
-         *buffer = 0;
-       }
-
-      result = *buffer;
-      *buffer = ASM_E_NOERROR;
-      return result;
-    }
-
-  result = global_error;
+  int result = global_error;
   global_error = ASM_E_NOERROR;
   return result;
 }
@@ -89,27 +52,6 @@ void
 __libasm_seterrno (value)
      int value;
 {
-  /* If we have not yet initialized the buffer do it now.  */
-  once_execute (once, init);
-
-  if (threaded)
-    {
-      /* We have a key.  Use it to get the thread-specific buffer.  */
-      int *buffer = getspecific (key);
-      if (buffer == NULL)
-        {
-          /* No buffer allocated so far.  */
-          buffer = malloc (sizeof (int));
-          if (buffer == NULL)
-            /* No more memory available.  We use the static buffer.  */
-            buffer = &global_error;
-
-          setspecific (key, buffer);
-        }
-
-      *buffer = value;
-    }
-
   global_error = value;
 }
 
@@ -133,31 +75,7 @@ const char *
 asm_errmsg (error)
      int error;
 {
-  int last_error;
-
-  /* If we have not yet initialized the buffer do it now.  */
-  once_execute (once, init);
-
-  if ((error == 0 || error == -1) && threaded)
-    {
-      /* We have a key.  Use it to get the thread-specific buffer.  */
-      int *buffer = (int *) getspecific (key);
-      if (buffer == NULL)
-       {
-         /* No buffer allocated so far.  */
-         buffer = (int *) malloc (sizeof (int));
-         if (buffer == NULL)
-           /* No more memory available.  We use the static buffer.  */
-           buffer = &global_error;
-
-         setspecific (key, buffer);
-         *buffer = 0;
-       }
-
-      last_error = *buffer;
-    }
-  else
-    last_error = global_error;
+  int last_error = global_error;
 
   if (error < -1)
     return _("unknown error");
@@ -173,25 +91,3 @@ asm_errmsg (error)
 
   return _(msgs[last_error]);
 }
-
-
-/* Free the thread specific data, this is done if a thread terminates.  */
-static void
-free_key_mem (void *mem)
-{
-  free (mem);
-  setspecific (key, NULL);
-}
-
-
-/* Initialize the key for the global variable.  */
-static void
-init (void)
-{
-  // XXX Screw you, gcc4, the unused function attribute does not work.
-  __asm ("" :: "r" (free_key_mem));
-
-  if (key_create (&key, free_key_mem) == 0)
-    /* Creating the key succeeded.  */
-    threaded = true;
-}
index fb1a8b0..aaca747 100644 (file)
@@ -1,3 +1,7 @@
+2009-01-10  Ulrich Drepper  <drepper@redhat.com>
+
+       * dwarf_error.c: Always use __thread.  Remove all !USE_TLS code.
+
 2009-01-08  Roland McGrath  <roland@redhat.com>
 
        * Makefile.am (libdw.so): Don't depend on $(zip_LIBS), just link it in.
index fe91664..86ff821 100644 (file)
@@ -1,5 +1,5 @@
 /* Retrieve ELF descriptor used for DWARF access.
-   Copyright (C) 2002, 2003, 2004, 2005 Red Hat, Inc.
+   Copyright (C) 2002, 2003, 2004, 2005, 2009 Red Hat, Inc.
    This file is part of Red Hat elfutils.
    Written by Ulrich Drepper <drepper@redhat.com>, 2002.
 
 #include "libdwP.h"
 
 
-#ifdef USE_TLS
 /* The error number.  */
 static __thread int global_error;
-#else
-/* This is the key for the thread specific memory.  */
-static tls_key_t key;
-
-/* The error number.  Used in non-threaded programs.  */
-static int global_error;
-static bool threaded;
-/* We need to initialize the thread-specific data.  */
-once_define (static, once);
-
-/* The initialization and destruction functions.  */
-static void init (void);
-static void free_key_mem (void *mem);
-#endif /* TLS */
 
 
 int
 dwarf_errno (void)
 {
-  int result;
-
-#ifndef USE_TLS
-  /* If we have not yet initialized the buffer do it now.  */
-  once_execute (once, init);
-
-  if (threaded)
-    {
-    /* We do not allocate memory for the data.  It is only a word.
-       We can store it in place of the pointer.  */
-      result = (intptr_t) getspecific (key);
-
-      setspecific (key, (void *) (intptr_t) DWARF_E_NOERROR);
-      return result;
-    }
-#endif /* TLS */
-
-  result = global_error;
+  int result = global_error;
   global_error = DWARF_E_NOERROR;
   return result;
 }
@@ -151,16 +119,6 @@ void
 __libdw_seterrno (value)
      int value;
 {
-#ifndef USE_TLS
-  /* If we have not yet initialized the buffer do it now.  */
-  once_execute (once, init);
-
-  if (threaded)
-    /* We do not allocate memory for the data.  It is only a word.
-       We can store it in place of the pointer.  */
-    setspecific (key, (void *) (intptr_t) value);
-#endif /* TLS */
-
   global_error = (value >= 0 && value < (int) nerrmsgs
                  ? value : DWARF_E_UNKNOWN_ERROR);
 }
@@ -170,19 +128,7 @@ const char *
 dwarf_errmsg (error)
      int error;
 {
-  int last_error;
-
-#ifndef USE_TLS
-  /* If we have not yet initialized the buffer do it now.  */
-  once_execute (once, init);
-
-  if ((error == 0 || error == -1) && threaded)
-    /* We do not allocate memory for the data.  It is only a word.
-       We can store it in place of the pointer.  */
-    last_error = (intptr_t) getspecific (key);
-  else
-#endif /* TLS */
-    last_error = global_error;
+  int last_error = global_error;
 
   if (error == 0)
     return last_error != 0 ? _(errmsgs[last_error]) : NULL;
@@ -192,26 +138,3 @@ dwarf_errmsg (error)
   return _(errmsgs[error == -1 ? last_error : error]);
 }
 INTDEF(dwarf_errmsg)
-
-
-#ifndef USE_TLS
-/* Free the thread specific data, this is done if a thread terminates.  */
-static void
-free_key_mem (void *mem __attribute__ ((unused)))
-{
-  setspecific (key, NULL);
-}
-
-
-/* Initialize the key for the global variable.  */
-static void
-init (void)
-{
-  // XXX Screw you, gcc4, the unused function attribute does not work.
-  __asm ("" :: "r" (free_key_mem));
-
-  if (key_create (&key, free_key_mem) == 0)
-    /* Creating the key succeeded.  */
-    threaded = true;
-}
-#endif /* TLS */
index 2ddfc3a..f0ab1ac 100644 (file)
@@ -1,3 +1,7 @@
+2009-01-10  Ulrich Drepper  <drepper@redhat.com>
+
+       * dwfl_error.c: Always use __thread.  Remove all !USE_TLS code.
+
 2009-01-08  Roland McGrath  <roland@redhat.com>
 
        * linux-kernel-modules.c (dwfl_linux_kernel_report_offline):
index 414fbaf..df2765a 100644 (file)
@@ -1,5 +1,5 @@
 /* Error handling in libdwfl.
-   Copyright (C) 2005, 2006 Red Hat, Inc.
+   Copyright (C) 2005, 2006, 2009 Red Hat, Inc.
    This file is part of Red Hat elfutils.
 
    Red Hat elfutils is free software; you can redistribute it and/or modify
 #include "libdwflP.h"
 
 
-#ifdef USE_TLS
 /* The error number.  */
 static __thread int global_error;
-#else
-/* This is the key for the thread specific memory.  */
-static tls_key_t key;
-
-/* The error number.  Used in non-threaded programs.  */
-static int global_error;
-static bool threaded;
-/* We need to initialize the thread-specific data.  */
-once_define (static, once);
-
-/* The initialization and destruction functions.  */
-static void init (void);
-static void free_key_mem (void *mem);
-#endif /* TLS */
 
 
 int
 dwfl_errno (void)
 {
-  int result;
-
-#ifndef USE_TLS
-  /* If we have not yet initialized the buffer do it now.  */
-  once_execute (once, init);
-
-  if (threaded)
-    {
-      /* We do not allocate memory for the data.  It is only a word.
-        We can store it in place of the pointer.  */
-      result = (intptr_t) getspecific (key);
-
-      setspecific (key, (void *) (intptr_t) DWFL_E_NOERROR);
-      return result;
-    }
-#endif /* TLS */
-
-  result = global_error;
+  int result = global_error;
   global_error = DWFL_E_NOERROR;
   return result;
 }
@@ -172,19 +140,7 @@ void
 internal_function
 __libdwfl_seterrno (Dwfl_Error error)
 {
-  int value = canonicalize (error);
-
-#ifndef USE_TLS
-  /* If we have not yet initialized the buffer do it now.  */
-  once_execute (once, init);
-
-  if (threaded)
-    /* We do not allocate memory for the data.  It is only a word.
-       We can store it in place of the pointer.  */
-    setspecific (key, (void *) (intptr_t) value);
-#endif /* TLS */
-
-  global_error = value;
+  global_error = canonicalize (error);
 }
 
 
@@ -194,19 +150,7 @@ dwfl_errmsg (error)
 {
   if (error == 0 || error == -1)
     {
-      int last_error;
-
-#ifndef USE_TLS
-      /* If we have not yet initialized the buffer do it now.  */
-      once_execute (once, init);
-
-      if (threaded)
-       /* We do not allocate memory for the data.  It is only a word.
-          We can store it in place of the pointer.  */
-       last_error = (intptr_t) getspecific (key);
-      else
-#endif /* TLS */
-       last_error = global_error;
+      int last_error = global_error;
 
       if (error == 0 && last_error == 0)
        return NULL;
@@ -233,26 +177,3 @@ dwfl_errmsg (error)
                          ? error : DWFL_E_UNKNOWN_ERROR]]);
 }
 INTDEF (dwfl_errmsg)
-
-
-#ifndef USE_TLS
-/* Free the thread specific data, this is done if a thread terminates.  */
-static void
-free_key_mem (void *mem __attribute__ ((unused)))
-{
-  setspecific (key, NULL);
-}
-
-
-/* Initialize the key for the global variable.  */
-static void
-init (void)
-{
-  // XXX Screw you, gcc4, the unused function attribute does not work.
-  __asm ("" :: "r" (free_key_mem));
-
-  if (key_create (&key, free_key_mem) == 0)
-    /* Creating the key succeeded.  */
-    threaded = true;
-}
-#endif /* TLS */
index 9578f8b..768346d 100644 (file)
@@ -1,3 +1,8 @@
+2009-01-10  Ulrich Drepper  <drepper@redhat.com>
+
+       * Makefile.am: Use USE_LOCKS instead of USE_TLS.
+       * elf_error.c: Always use __thread.  Remove all !USE_TLS code.
+
 2008-12-11  Roland McGrath  <roland@redhat.com>
 
        * elf32_updatefile.c (__elfw2(LIBELFBITS,updatemmap)): Handle
index 2458ecb..84b01a8 100644 (file)
@@ -1,6 +1,6 @@
 ## Process this file with automake to create Makefile.in
 ##
-## Copyright (C) 1996-2006, 2007, 2008 Red Hat, Inc.
+## Copyright (C) 1996-2006, 2007, 2008, 2009 Red Hat, Inc.
 ## This file is part of Red Hat elfutils.
 ##
 ## Red Hat elfutils is free software; you can redistribute it and/or modify
@@ -106,7 +106,7 @@ libelf_pic_a_SOURCES =
 am_libelf_pic_a_OBJECTS = $(libelf_a_SOURCES:.c=.os)
 
 libelf_so_LDLIBS =
-if USE_TLS
+if USE_LOCKS
 libelf_so_LDLIBS += -lpthread
 endif
 
index 5e00372..dc58782 100644 (file)
@@ -1,5 +1,5 @@
 /* Error handling in libelf.
-   Copyright (C) 1998, 1999, 2000, 2002, 2003, 2004, 2005, 2006 Red Hat, Inc.
+   Copyright (C) 1998,1999,2000,2002,2003,2004,2005,2006,2009 Red Hat, Inc.
    This file is part of Red Hat elfutils.
    Written by Ulrich Drepper <drepper@redhat.com>, 1998.
 
 #include "libelfP.h"
 
 
-#ifdef USE_TLS
 /* The error number.  */
 static __thread int global_error;
-#else
-/* This is the key for the thread specific memory.  */
-static tls_key_t key;
-
-/* The error number.  Used in non-threaded programs.  */
-static int global_error;
-static bool threaded;
-/* We need to initialize the thread-specific data.  */
-once_define (static, once);
-
-/* The initialization and destruction functions.  */
-static void init (void);
-static void free_key_mem (void *mem);
-#endif /* TLS */
 
 
 int
 elf_errno (void)
 {
-  int result;
-
-#ifndef USE_TLS
-  /* If we have not yet initialized the buffer do it now.  */
-  once_execute (once, init);
-
-  if (threaded)
-    {
-    /* We do not allocate memory for the data.  It is only a word.
-       We can store it in place of the pointer.  */
-      result = (intptr_t) getspecific (key);
-
-      setspecific (key, (void *) (intptr_t) ELF_E_NOERROR);
-      return result;
-    }
-#endif /* TLS */
-
-  result = global_error;
+  int result = global_error;
   global_error = ELF_E_NOERROR;
   return result;
 }
@@ -339,16 +307,6 @@ void
 __libelf_seterrno (value)
      int value;
 {
-#ifndef USE_TLS
-  /* If we have not yet initialized the buffer do it now.  */
-  once_execute (once, init);
-
-  if (threaded)
-    /* We do not allocate memory for the data.  It is only a word.
-       We can store it in place of the pointer.  */
-    setspecific (key, (void *) (intptr_t) value);
-#endif /* TLS */
-
   global_error = value >= 0 && value < nmsgidx ? value : ELF_E_UNKNOWN_ERROR;
 }
 
@@ -357,19 +315,7 @@ const char *
 elf_errmsg (error)
      int error;
 {
-  int last_error;
-
-#ifndef USE_TLS
-  /* If we have not yet initialized the buffer do it now.  */
-  once_execute (once, init);
-
-  if ((error == 0 || error == -1) && threaded)
-    /* We do not allocate memory for the data.  It is only a word.
-       We can store it in place of the pointer.  */
-    last_error = (intptr_t) getspecific (key);
-  else
-#endif /* TLS */
-    last_error = global_error;
+  int last_error = global_error;
 
   if (error == 0)
     {
@@ -382,26 +328,3 @@ elf_errmsg (error)
   assert (msgidx[error == -1 ? last_error : error] < sizeof (msgstr));
   return _(msgstr + msgidx[error == -1 ? last_error : error]);
 }
-
-
-#ifndef USE_TLS
-/* Free the thread specific data, this is done if a thread terminates.  */
-static void
-free_key_mem (void *mem __attribute__ ((unused)))
-{
-  setspecific (key, NULL);
-}
-
-
-/* Initialize the key for the global variable.  */
-static void
-init (void)
-{
-  // XXX Screw you, gcc4, the unused function attribute does not work.
-  __asm ("" :: "r" (free_key_mem));
-
-  if (key_create (&key, free_key_mem) == 0)
-    /* Creating the key succeeded.  */
-    threaded = true;
-}
-#endif /* TLS */