From 7e678fa3f6051f7ef24b4610c9a66cab858b6b6e Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Sat, 10 Jan 2009 18:02:05 -0800 Subject: [PATCH] Require __thread support in compiler. Rename --enable-tls to more appropriate --enable-thread-safety. --- ChangeLog | 6 +++ configure.ac | 19 ++++++--- lib/ChangeLog | 6 +++ lib/eu-config.h | 24 ++--------- libasm/ChangeLog | 5 +++ libasm/Makefile.am | 4 +- libasm/asm_error.c | 112 ++------------------------------------------------- libdw/ChangeLog | 4 ++ libdw/dwarf_error.c | 83 ++------------------------------------ libdwfl/ChangeLog | 4 ++ libdwfl/dwfl_error.c | 87 ++------------------------------------- libelf/ChangeLog | 5 +++ libelf/Makefile.am | 4 +- libelf/elf_error.c | 83 ++------------------------------------ 14 files changed, 64 insertions(+), 382 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7433b21..554da44 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2009-01-10 Ulrich Drepper + + * 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 * configure.ac (eu_ZIPLIB): Moved to m4/zip.am. diff --git a/configure.ac b/configure.ac index 6a3b6a7..4b08e10 100644 --- a/configure.ac +++ b/configure.ac @@ -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") diff --git a/lib/ChangeLog b/lib/ChangeLog index f4c261a..8791640 100644 --- a/lib/ChangeLog +++ b/lib/ChangeLog @@ -1,3 +1,9 @@ +2009-01-10 Ulrich Drepper + + * 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 * eu-config.h [USE_TLS] (RWLOCK_CALL): New macro. diff --git a/lib/eu-config.h b/lib/eu-config.h index c41cbb0..03dba76 100644 --- a/lib/eu-config.h +++ b/lib/eu-config.h @@ -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 @@ -46,15 +46,9 @@ Network licensing program, please visit www.openinventionnetwork.com . */ -#ifdef USE_TLS +#ifdef USE_LOCKS # include # include -# 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); }) @@ -67,25 +61,13 @@ /* 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 diff --git a/libasm/ChangeLog b/libasm/ChangeLog index c98deb6..d0d4039 100644 --- a/libasm/ChangeLog +++ b/libasm/ChangeLog @@ -1,3 +1,8 @@ +2009-01-10 Ulrich Drepper + + * 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 * Makefile.am [USE_TLS]: Like libasm.so with libpthread. diff --git a/libasm/Makefile.am b/libasm/Makefile.am index 62b5ee2..7d5e25d 100644 --- a/libasm/Makefile.am +++ b/libasm/Makefile.am @@ -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 diff --git a/libasm/asm_error.c b/libasm/asm_error.c index 29c54cb..4d249e9 100644 --- a/libasm/asm_error.c +++ b/libasm/asm_error.c @@ -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 , 2002. @@ -36,50 +36,13 @@ /* 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; -} diff --git a/libdw/ChangeLog b/libdw/ChangeLog index fb1a8b0..aaca747 100644 --- a/libdw/ChangeLog +++ b/libdw/ChangeLog @@ -1,3 +1,7 @@ +2009-01-10 Ulrich Drepper + + * dwarf_error.c: Always use __thread. Remove all !USE_TLS code. + 2009-01-08 Roland McGrath * Makefile.am (libdw.so): Don't depend on $(zip_LIBS), just link it in. diff --git a/libdw/dwarf_error.c b/libdw/dwarf_error.c index fe91664..86ff821 100644 --- a/libdw/dwarf_error.c +++ b/libdw/dwarf_error.c @@ -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 , 2002. @@ -58,46 +58,14 @@ #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 */ diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog index 2ddfc3a..f0ab1ac 100644 --- a/libdwfl/ChangeLog +++ b/libdwfl/ChangeLog @@ -1,3 +1,7 @@ +2009-01-10 Ulrich Drepper + + * dwfl_error.c: Always use __thread. Remove all !USE_TLS code. + 2009-01-08 Roland McGrath * linux-kernel-modules.c (dwfl_linux_kernel_report_offline): diff --git a/libdwfl/dwfl_error.c b/libdwfl/dwfl_error.c index 414fbaf..df2765a 100644 --- a/libdwfl/dwfl_error.c +++ b/libdwfl/dwfl_error.c @@ -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 @@ -61,46 +61,14 @@ #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 */ diff --git a/libelf/ChangeLog b/libelf/ChangeLog index 9578f8b..768346d 100644 --- a/libelf/ChangeLog +++ b/libelf/ChangeLog @@ -1,3 +1,8 @@ +2009-01-10 Ulrich Drepper + + * 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 * elf32_updatefile.c (__elfw2(LIBELFBITS,updatemmap)): Handle diff --git a/libelf/Makefile.am b/libelf/Makefile.am index 2458ecb..84b01a8 100644 --- a/libelf/Makefile.am +++ b/libelf/Makefile.am @@ -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 diff --git a/libelf/elf_error.c b/libelf/elf_error.c index 5e00372..dc58782 100644 --- a/libelf/elf_error.c +++ b/libelf/elf_error.c @@ -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 , 1998. @@ -61,46 +61,14 @@ #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 */ -- 2.7.4