This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: [PATCH v4] Destructor support for C++11 thread_local variables
- From: Siddhesh Poyarekar <siddhesh at redhat dot com>
- To: "Carlos O'Donell" <carlos at redhat dot com>
- Cc: libc-alpha at sourceware dot org, Jakub Jelinek <jakub at redhat dot com>, Jason Merrill <jason at redhat dot com>, Roland McGrath <roland at hack dot frob dot com>
- Date: Fri, 15 Feb 2013 11:03:51 +0530
- Subject: Re: [PATCH v4] Destructor support for C++11 thread_local variables
- References: <20121017184033.109bcd89@spoyarek><20121029085207.21957cd2@spoyarek><20121029063837.GH1752@tucnak.redhat.com><20121030193603.3993aa3c@spoyarek><20121030200754.3680c8ba@spoyarek><511D7339.4000705@redhat.com>
On Thu, Feb 14, 2013 at 06:28:57PM -0500, Carlos O'Donell wrote:
> You mentioned in the wiki page of the description of this patch
> that because thread_local is destroyed *before* the key destructors
> are called that you can't use thread_local in the key destructors.
>
> This needs to be documented. Please create a pthreads section in
> the manual, create an empty definition for pthread_key_create and
> document that C++11 thread_local may not be used by those registered
> destructors.
Sure, will post a manual patch once this patch goes in.
> Is there any way to avoid this restriction? Why can't we destory
> the thread_local variables *after* calling the key destructors?
It was a choice between either allowing thread_local destructors to
use pthread_keys or allowing pthread_keys to allow thread_local
destructors; we can't do both. It's just a choice I made since it is
unlikely that an implementation will use both and interleave them in
such a manner.
> > + if (__builtin_expect (dso_handle_cache != dso_handle, 0))
>
> IIUC this is simply an optimization for registering a series of thread_local
> destructors for the same library?
Yes.
> > + {
> > + ElfW(Addr) caller = (ElfW(Addr)) dso_handle;
> > +
> > + /* If the address is not recognized the call comes from the main
> > + program (we hope). */
> > + lm_cache = GL(dl_ns)[LM_ID_BASE]._ns_loaded;
> > +
> > + /* Find the highest-addressed object that DSO_HANDLE is not below. */
> > + for (Lmid_t ns = 0; ns < GL(dl_nns); ++ns)
> > + for (struct link_map *l = GL(dl_ns)[ns]._ns_loaded; l != NULL;
> > + l = l->l_next)
> > + if (caller >= l->l_map_start && caller < l->l_map_end
> > + && (l->l_contiguous || _dl_addr_inside_object (l, caller)))
> > + {
> > + lm_cache = l;
> > + break;
> > + }
> > +
>
> OK, I need some clarification here, is DSO_HANDLE a handle returned by
> dlopen() or simply a symbol within the DSO that the compiler has?
> I assume the latter, otherwise I don't think this would work.
It's a symbol added (I think) by the linker.
>
> Could we please create a utility function and get that patch
> checked in first?
OK, will do that.
> (2) Do not use the word "DSO handle" since that might confuse people.
>
> If it's a symbol from within the DSO that the compiler is using to mark
> that DSO in some way then say "DSO symbol". A handle is what is returned
> from dlopen.
But that symbol has always been called the dso_handle. Anyway, it
doesn't matter to me what it's called, so I think I'll call it
dso_symbol.
Siddhesh