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: "Carlos O'Donell" <carlos at redhat dot com>
- To: Siddhesh Poyarekar <siddhesh 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 13:37:17 -0500
- 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> <20130215053351.GC27403@spoyarek.pnq.redhat.com>
On 02/15/2013 12:33 AM, Siddhesh Poyarekar wrote:
> 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.
Thanks.
>> 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.
OK.
>>> + {
>>> + 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.
As Jason pointed out this is a symbol.
The problem I have with using DSO handle is that it's a confusing
term already used within glibc to mean the return of a call to
dlopen.
>>
>> Could we please create a utility function and get that patch
>> checked in first?
>
> OK, will do that.
Thanks, I reviewed it.
>> (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.
Thanks. Feel free to explain that the symbol is *named* `__dso_handle',
but that it is just another symbol.
Cheers,
Carlos.