[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