Optionally use thread-local objects for struct _reent members

Corinna Vinschen vinschen@redhat.com
Mon Jan 10 12:56:21 GMT 2022


On Jan 10 10:28, Sebastian Huber wrote:
> Hello,
> 
> Newlib currently uses a huge object of type struct _reent to store
> thread-specific data. This object is returned by __getreent() if the
> __DYNAMIC_REENT__ Newlib configuration option is defined.
> 
> The reentrancy structure contains errno and also the standard input, output,
> and error file streams. This means that if an application only uses errno it
> has a dependency on the file stream support even if it does not use it. This
> is an issue for lower end targets and applications which need to qualify the
> software according to safety standards (for example ECSS-E-ST-40C,
> ECSS-Q-ST-80C, IEC 61508,
> ISO 26262, DO-178, DO-330, DO-333).
> 
> 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;
> 
> if a new configuration option is defined (for example _REENT_THREAD_LOCAL).
> 
> Newlib already has access macros for some struct _reent members, for
> example:
> 
> #define _REENT_SIGNGAM(ptr)     ((ptr)->_new._reent._gamma_signgam)
> #define _REENT_RAND_NEXT(ptr)   ((ptr)->_new._reent._rand_next)
> #define _REENT_RAND48_SEED(ptr) ((ptr)->_new._reent._r48._seed)
> #define _REENT_RAND48_MULT(ptr) ((ptr)->_new._reent._r48._mult)
> #define _REENT_RAND48_ADD(ptr)  ((ptr)->_new._reent._r48._add)
> 
> The member access macros are incomplete. We would have to add macros for all
> the struct _reent members. Would this be an approach acceptable for Newlib
> integration?

I think this would be acceptable, provided that the current
implementation stays available.  Cygwin relies on the reent struct being
part of a bigger TLS structure with constant offsets from the beginning
of the stack.  The beast is accessed from assembler code so any dynamic
allocation of parts of the TLS stuff would break the code.  It's
probably possible to ease this up, but it's quite a task.

Do we require a C11 compiler for building newlib yet?  I think not.


Corinna



More information about the Newlib mailing list