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? -- embedded brains GmbH Herr Sebastian HUBER Dornierstr. 4 82178 Puchheim Germany email: sebastian.huber@embedded-brains.de 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: https://embedded-brains.de/datenschutzerklaerung/
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
On 10/01/2022 13:56, Corinna Vinschen wrote: >> 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. The existing struct _reent implementation will be still the default. Targets will get a new configuration option (for example _REENT_THREAD_LOCAL) to use thread-local objects instead of members in a structure. There will be several of new _REENT_XZY(ptr) macros to enable this alternative implementation. -- embedded brains GmbH Herr Sebastian HUBER Dornierstr. 4 82178 Puchheim Germany email: sebastian.huber@embedded-brains.de 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: https://embedded-brains.de/datenschutzerklaerung/
Hello, I just would like to give a short status update. With the recent patches using _REENT_GLOBAL is no longer required. The global state of Newlib is managed by dedicated objects (for example the FILE object list or the exit handlers). This enables us to use thread-local objects for all members of struct _reent. We should have a patch ready for review soon. It would help if we could make the _REENT_GLOBAL_STDIO_STREAMS option the default behaviour and remove the associated conditional code. It is currently enabled by Cygwin and RTEMS. I will send a patch to discuss this next week. We didn't work on the support for constructors/destructors for thread-local objects yet, see: https://www.openwall.com/lists/libc-coord/2022/01/21/1 My approach would be to first add a prototype implementation to Newlib using a dedicated linker set and then make a proposal for the ELF support. -- embedded brains GmbH Herr Sebastian HUBER Dornierstr. 4 82178 Puchheim Germany email: sebastian.huber@embedded-brains.de 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: https://embedded-brains.de/datenschutzerklaerung/