This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: [PATCH v5] 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:40:26 -0500
- Subject: Re: [PATCH v5] 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> <20130215115044.GK27403@spoyarek.pnq.redhat.com>
On 02/15/2013 06:50 AM, Siddhesh Poyarekar wrote:
> Hi,
>
> Here's an updated version of the C++11 thread_local destructor
> implementation. I have made a couple of updates to the patch,
> including those that Carlos suggested in his review. I found that the
> patch broke checklocalplt since a PLT entry was generated for
> __call_tls_dtors. I have fixed that now. Built and regression tested
> on x86_64.
OK to checkin once you get the naming straight.
> +static __thread struct dtor_list *tls_dtor_list;
> +static __thread void *dso_handle_cache;
s/handle/symbol/g
> +static __thread struct link_map *lm_cache;
> +
> +/* Register a destructor for TLS variables declared with the 'thread_local'
> + keyword. This function is only called from code generated by the C++
> + compiler. */
Explain in the comment that `dso_symbol' is a per-DSO hidden symbol
named `__dso_handle' used to identify the DSO.
> +int
> +__cxa_thread_atexit_impl (dtor_func func, void *obj, void *dso_handle)
s/handle/symbol/g
> +{
> + /* Prepend. */
> + struct dtor_list *new = calloc (1, sizeof (struct dtor_list));
> + new->func = func;
> + new->obj = obj;
> + new->next = tls_dtor_list;
> + tls_dtor_list = new;
> +
> + /* See if we already encountered the DSO. */
> + __rtld_lock_lock_recursive (GL(dl_load_lock));
> +
> + if (__builtin_expect (dso_handle_cache != dso_handle, 0))
> + {
> + ElfW(Addr) caller = (ElfW(Addr)) dso_handle;
> +
> + struct link_map *l = _dl_find_dso_for_object (caller);
Now that we call it a symbol it makes sense to me that we need to
translate the symbol into an actual handle :-)
> +
> + /* If the address is not recognized the call comes from the main
> + program (we hope). */
> + lm_cache = l ? l : GL(dl_ns)[LM_ID_BASE]._ns_loaded;
> + }
> + /* A destructor could result in a thread_local construction and the former
> + could have cleared the flag. */
> + if (lm_cache->l_type == lt_loaded && lm_cache->l_tls_dtor_count == 0)
> + lm_cache->l_flags_1 |= DF_1_NODELETE;
> +
> + new->map = lm_cache;
> + new->map->l_tls_dtor_count++;
> +
> + __rtld_lock_unlock_recursive (GL(dl_load_lock));
> +
> + return 0;
> +}
Cheers,
Carlos.