[RTEMS Project] #4560: Use thread-local storage for Newlib reentrancy objects

RTEMS trac trac at rtems.org
Fri Dec 3 09:04:00 UTC 2021


#4560: Use thread-local storage for Newlib reentrancy objects
------------------------------+-----------------------------
  Reporter:  Sebastian Huber  |      Owner:  Sebastian Huber
      Type:  project          |     Status:  assigned
  Priority:  normal           |  Milestone:  7.1
 Component:  tool/newlib      |    Version:  7
  Severity:  normal           |   Keywords:
Blocked By:                   |   Blocking:
------------------------------+-----------------------------
 = Problem

 The state of the art architectures supported by RTEMS have all efficient
 support for thread-local storage (MIPS has issues with thread-local
 storage, however, is MIPS state of the art?).

 Newlib currently uses a huge object of type `struct _reent` to store
 thread-specific data. This object is returned by `__getreent()`. It is
 related to the `__DYNAMIC_REENT__` Newlib configuration option which is
 always defined for RTEMS.

 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 event if it
 does not use it. This is an issue for lower end targets and the pre-
 qualification of RTEMS.

 = Solution

 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
 {{{#!c
 struct _reent {
   int _errno;
   __FILE *_stdin;
   __FILE *_stdout;
   __FILE *_stderr;
 };
 }}}
 use
 {{{#!c
 _Thread_local int _errno;
 _Thread_local __FILE *_stdin;
 _Thread_local __FILE *_stdout;
 _Thread_local __FILE *_stderr;
 }}}

 Newlib already has access macros for the `struct _reent` members, for
 example:
 {{{#!c
 #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)
 }}}

 = How-to Implement

 The member access macros are incomplete. The first step is to use the
 Newlib configuration for RTEMS as is and rename all `struct _reent`
 members, for example add an `TEMPORARY` prefix to all member names,
 `_errno` to `TEMPORARY_errno`. Then add member access macros until Newlib
 builds again. Install this Newlib and check that RTEMS and libbsd
 compiles. Run the RTEMS and libbsd test suites to check for regressions.

 In a second step to this for the `_REENT_SMALL` configuration of Newlib.

 The third step is to add a new Newlib configuration option, for example
 `_REENT_THREAD_LOCAL` which turns the `struct _reent` members into thread-
 local objects with corresponding "member" access macros. Define `_REENT`
 to `NULL`.

--
Ticket URL: <http://devel.rtems.org/ticket/4560>
RTEMS Project <http://www.rtems.org/>
RTEMS Project


More information about the bugs mailing list