Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date: Mon, 24 Jan 2022 08:28:35 +0100
From: Sebastian Huber <>
To:, Keith Packard <>
Subject: Re: Constructors/destructors for thread-local objects?

On 24/01/2022 05:01, Keith Packard wrote:
> Sebastian Huber <> writes:
>> One approach to disentangle the dependencies introduced by struct _reent
>> is to get rid of this structure and replace the individual members of
>> the structure with thread-local objects. For example, instead of
>> struct _reent {
>>     int _errno;
>>     __FILE *_stdin;
>>     __FILE *_stdout;
>>     __FILE *_stderr;
>> };
>> use
>> _Thread_local int _errno;
>> _Thread_local __FILE *_stdin;
>> _Thread_local __FILE *_stdout;
>> _Thread_local __FILE *_stderr;
> This has already been done in picolibc; that was the principle reason
> picolibc became a fork of newlib rather than simply a sequence of minor
> fixes -- there's no way to preserve newlib ABI with this change. So, if
> you're interested in this approach, I already have an existence proof
> that it can work.

Our approach is to introduce a new configuration option for Newlib and 
use macros to access the members of struct _reent or the thread-local 

>> Now, there is a problem with the clean up of resources when a thread is
>> deleted. There is currently no standard way for constructors and
>> destructors of thread-local objects in C.
> Given that embedded systems (those likely to be running picolibc) don't
> really have any notion of 'exit' anyways, I've wondered at times if it
> would be reasonable to re-purpose the existing init/fini handlers to be
> thread start/thread exit instead of 'process' start and termination. I
> eventually decided that this wasn't the case as we still need global
> system initialization to be invoked through the .init handlers. So, yes,
> I agree that we could use such a mechanism for applications which have
> TLS variables that need cleanup on thread exit.
> picolibc defines a set of APIs to help operating systems enable TLS
> support; adding a couple more to run the TLS initializers/finalizers
> would be a nice extension to this concept.
>> Do we need .tls_preinit_array?
> I'd prefer to skip it; this requires another chunk of code in the thread
> initialization sequence which can't be optimized away as the length of
> the arrays aren't known until link time.
>> It is unlikely that another C library will use this, but anyway, I would
>> like to use some names which could be used elsewhere as well.
> Picolibc (and other embedded C libaries) could use the same mechanism.
> In picolibc, there's a couple of TLS variables that would need .fini
> handlers in the legacy stdio implementation of printf, and
> gcvt/ecvt/fcvt. These are only used in a non-standard build of picolibc,
> so for now they leak memory on multi-threaded systems on thread exit.
> Do you have other places in newlib that need TLS data cleanup done on
> thread exit? Because at this point, I would only be providing this
> mechanism for application support, in it's normal configuration,
> picolibc wouldn't need it.

In Newlib __reclaim_reent() needs to be called at thread exit:;a=blob;f=newlib/libc/reent/reent.c;h=7c57e2019b82c0a70df16257cead1c27d3ea2b63;hb=HEAD

This would need to to be split up into thread-local object destructors 
which are get pulled in if the application references the corresponding 


embedded brains GmbH
Herr Sebastian HUBER
Dornierstr. 4
82178 Puchheim
phone: +49-89-18 94 741 - 16
fax:   +49-89-18 94 741 - 08

Registergericht: Amtsgericht München
Registernummer: HRB 157899
Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler
Unsere Datenschutzerklärung finden Sie hier:

Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.