This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: [PATCH v3] Destructor support for C++11 thread_local variables- abilist entries
- From: Siddhesh Poyarekar <siddhesh at redhat dot com>
- To: libc-alpha at sourceware dot org
- Cc: Jakub Jelinek <jakub at redhat dot com>, Jason Merrill <jason at redhat dot com>, Roland McGrath <roland at hack dot frob dot com>
- Date: Mon, 29 Oct 2012 08:52:07 +0530
- Subject: Re: [PATCH v3] Destructor support for C++11 thread_local variables- abilist entries
- References: <20121017184033.109bcd89@spoyarek>
Ping, any feedback on this? I'm also waiting for Jakub or Jason to
confirm if thread_local is definitely going to make it into gcc-4.8.
If it is then I could write the test case into glibc.
http://sourceware.org/ml/libc-alpha/2012-10/msg00444.html
Thanks,
Siddhesh
On Wed, 17 Oct 2012 18:40:33 +0530, Siddhesh wrote:
> Hi,
>
> Here is an updated patch based on feedback so far. For context of
> this change, please see the following thread:
>
> http://sourceware.org/ml/libc-alpha/2012-10/msg00289.html
>
> To summarize, this patch adds destructor support for the C++11
> variables of the thread_local scope. it adds a new function
> __cxa_thread_atexit_impl, that libstdc++ calls to register destructors
> for the thread_local objects it constructs. The destructors will then
> be called at either thread exit or program exit. The current
> iteration of the patch adds support to allow unloading a DSO that has
> thread_local variables provided that all threads that constructed the
> variables have exited and their destructors called. This is
> implemented by adding an extra field in struct link_map to count the
> destructors that were registered, decrementing when a destructor is
> called.
>
> I have verified that the latter functionality works with the help of
> the following program:
>
> $ cat foo.cc:
>
> #include "thread_local.h"
> extern "C" void do_foo (void)
> {
> thread_local A b;
> }
>
> $ cat thread_local.cc:
>
> #include <dlfcn.h>
> #include <pthread.h>
> #include <stdio.h>
> #include <unistd.h>
> #include "thread_local.h"
>
> int c;
> int d;
>
> void (*foo) (void);
> pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
>
> void f()
> {
> thread_local A a;
> }
>
> void *
> load (void *u)
> {
> pthread_mutex_lock (&m);
> void *h = dlopen ("./libfoo.so", RTLD_LAZY);
> foo = (void (*) (void)) dlsym(h, "do_foo");
>
> foo ();
> dlclose (h);
> pthread_mutex_unlock (&m);
> }
>
> void *
> thr (void *u)
> {
> /* wait till foo is initialized. */
> while (!foo);
>
> pthread_mutex_lock (&m);
> foo ();
> pthread_mutex_unlock (&m);
> }
>
> int main()
> {
>
> pthread_t t, dsot;
>
> pthread_create (&t, NULL, thr, NULL);
> sleep (1);
> pthread_create (&dsot, NULL, load, NULL);
>
> pthread_join (t, NULL);
> pthread_join (dsot, NULL);
> printf ("%d, %d\n", c, d);
> }
>
> $ tls-g++ -g -fPIC -std=c++11 thread_local.cc -ldl -pthread
> $ tls-g++ -fPIC -std=c++11 -shared -o libfoo.so foo.cc
>
>
> Regards,
> Siddhesh
>
> ChangeLog:
>
> * include/link.h (struct link_map): New member
> l_tls_dtor_count.
> * include/stdlib.h (__cxa_thread_atexit_impl): Declare.
> (__call_tls_dtors): Likewise.
> * sysdeps/unix/sysv/linux/i386/nptl/libc.abilist: Add
> __cxa_thread_atexit_impl.
> *
> sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/nptl/libc.abilist:
> Likewise.
> * sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libc.abilist:
> Likewise.
> * sysdeps/unix/sysv/linux/s390/s390-32/nptl/libc.abilist:
> Likewise.
> * sysdeps/unix/sysv/linux/s390/s390-64/nptl/libc.abilist:
> Likewise.
> * sysdeps/unix/sysv/linux/sh/nptl/libc.abilist: Likewise.
> * sysdeps/unix/sysv/linux/sparc/sparc32/nptl/libc.abilist:
> Likewise.
> * sysdeps/unix/sysv/linux/sparc/sparc64/nptl/libc.abilist:
> Likewise.
> * sysdeps/unix/sysv/linux/x86_64/64/nptl/libc.abilist:
> Likewise.
> * sysdeps/unix/sysv/linux/x86_64/x32/nptl/libc.abilist:
> Likewise.
> * stdlib/Makefile (routines): Add __cxa_thread_atexit_impl.
> * stdlib/Versions (GLIBC_2.17): Likewise.
> (GLIBC_PRIVATE): Add __call_tls_dtors.
> * stdlib/cxa_thread_atexit_impl.c: New file with helper
> function for libstdc++.
> * stdlib/exit.c (__run_exit_handlers): Call __call_tls_dtors.
>
> nptl/ChangeLog:
>
> * pthread_create.c (start_thread): Call __call_tls_dtors.
>
> ChangeLog.alpha:
> 2012-10-11 Siddhesh Poyarekar <siddhesh@redhat.com>
>
> * sysdeps/unix/sysv/linux/alpha/nptl/libc.abilist: Add
> __cxa_thread_atexit_impl.
>
>
> ChangeLog.arm:
> 2012-10-11 Siddhesh Poyarekar <siddhesh@redhat.com>
>
> * sysdeps/unix/sysv/linux/arm/nptl/libc.abilist: Add
> __cxa_thread_atexit_impl.
>
>
> ChangeLog.ia64:
> 2012-10-11 Siddhesh Poyarekar <siddhesh@redhat.com>
>
> * sysdeps/unix/sysv/linux/ia64/nptl/libc.abilist: Add
> __cxa_thread_atexit_impl.
>
>
> ChangeLog.m68k:
> 2012-10-11 Siddhesh Poyarekar <siddhesh@redhat.com>
>
> * sysdeps/unix/sysv/linux/m68k/coldfire/nptl/libc.abilist: Add
> __cxa_thread_atexit_impl.
> * sysdeps/unix/sysv/linux/m68k/m680x0/nptl/libc.abilist:
> Likewise.
>
>
> ChangeLog.mips:
> 2012-10-11 Siddhesh Poyarekar <siddhesh@redhat.com>
>
> * sysdeps/unix/sysv/linux/mips/mips32/nptl/libc.abilist: Add
> __cxa_thread_atexit_impl.
> * sysdeps/unix/sysv/linux/mips/mips64/n32/nptl/libc.abilist:
> Likewise.