[cxx-abi-dev] thread_local CONstructors
Jason Merrill
jason at redhat.com
Tue Sep 25 03:49:52 UTC 2012
On 09/24/2012 11:57 AM, Jason Merrill wrote:
> And I guess this means that we can't treat thread_local and __thread as
> equivalent; __thread will still need to require static initialization
> for C compatibility.
Jakub and I discussed this more on IRC today. It occurred to me that if
we use a weak reference to the initialization function we can avoid
breaking compatibility with C code that uses __thread, at least for
variables that are statically initialized. So a declaration
extern thread_local int i;
implies
extern void i_init() __attribute__ ((weak));
inline int& i_wrapper()
{
if (i_init) i_init();
return i;
}
so uses of i are replaced with calls to i_wrapper, and when i is defined
we emit i_init iff i has a dynamic initializer. For a statically
initialized variable, the runtime penalty is small (just comparing the
address of a symbol to zero).
Jakub suggested that it would be more efficient for variables that do
need dynamic initialization to have the wrapper check a guard variable
before calling the init function rather than from within the init
function. We could do that, too:
extern void i_init() __attribute ((weak));
extern thread_local bool i_done __attribute ((weak));
inline int& i_wrapper()
{
if (i_init && !i_done) i_init();
return i;
}
Note that we can't test the address of i_done to see if it's defined
because undefined weak TLS variables resolve to a non-null pointer
value. So we test the address of i_init instead.
Either of these maintains link-compatibility with __thread for
statically initialized variables (and even dynamically-initialized ones
as long as they are initialized before the C code tries to use them).
Jason
More information about the cxx-abi-dev
mailing list