This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Proposal: Slow dynamic TLS for internal glibc use
- From: Florian Weimer <fweimer at redhat dot com>
- To: libc-alpha at sourceware dot org
- Date: Tue, 23 Oct 2018 14:18:52 +0200
- Subject: Proposal: Slow dynamic TLS for internal glibc use
We have a lot of legacy interfaces which are not thread-safe: strtok,
many, many NSS functions such as gethostbyname, wide character functions
when invoked with a NULL state parameter, strerror, getpass, rpmatch,
localtime and so on.
Currently, most of these functions use global variables which take up
space in .bss. This introduces overhead even if they are never used,
and these functions are of course not thread-safe.
I would like to suggest that we add very slow TLS (slower than
global-dynamic) to support these functions in a thread-safe manner.
Memory usage will be larger if these interfaces are actually used, but
if they are not, there is no overhead whatsoever (beyond a slight
increase in code size), lower than what we have today.
The interface I have in mind looks like this. The keys should be
addresses of global glibc functions.
- void *__libc_slow_tls_get (void *key);
Return an existing TLS allocation for KEY if one exists, or NULL
otherwise.
- void *__libc_slow_tls_get_or_allocate (void *key, size_t size);
If a TLS allocation for KEY exists, return it, otherwise create a new
allocation on the heap for SIZE bytes, and return the pointer for that.
Return NULL on allocation error, with errno set appropriately.
- void *__libc_slow_tls_reallocate (void *key, size_t new_size);
Create a new TLS allocation for KEY of NEW_SIZE if none exists yet, or
resize an existing allocation. Return a pointer to the allocation, or
NULL on allocation error, with errno set appropriately.
These allocations are automatically freed if a thread exits. A single
per-thread pointer is used to point to the root of the data structure.
The rest of the memory will be heap-allocated.
I'm working to get clarification for C2X that this is a valid
implementation for the functions where C11 wasn't updated accordingly
when objects of thread storage duration were introduced.
Using these new functions, c32rtomb would look like this:
size_t
c32rtomb (char *s, char32_t c32, mbstate_t *ps)
{
if (ps == NULL)
{
ps = __libc_slow_tls_get_or_allocate (c32rtomb, sizeof (*ps));
if (ps == NULL)
return;
}
return wcrtomb (s, c32, ps);
}
And “static mbstate_t state;” would be gone.
In contrast, for strtok, we should simply use regular TLS state because
this function is actually used in inner loops, and there is no good way
to report errors.
Comments?
Thanks,
Florian