#4560 closed project (fixed)

Use thread-local storage for Newlib reentrancy objects

Reported by: Sebastian Huber Owned by: Sebastian Huber
Priority: normal Milestone: 6.1
Component: tool/newlib Version: 6
Severity: normal Keywords: SoC, newlib, executive, large, qualification
Cc: Blocked By: #4672
Blocking:

Description (last modified by Gedare Bloom)

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

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;

Newlib already has access macros for the 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)

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.

Skills

C and assembly

Difficulty

This is a large (350-hour) project of hard difficulty.

Attachments (2)

gcc-10-RTEMS-Use-local-exec-TLS-model-by-default.patch (10.1 KB) - added by Sebastian Huber on 08/08/22 at 11:00:15.
gcc-12-RTEMS-Use-local-exec-TLS-model-by-default.patch (10.1 KB) - added by Sebastian Huber on 08/08/22 at 11:00:32.

Download all attachments as: .zip

Change History (24)

comment:1 Changed on 12/03/21 at 17:29:59 by Joel Sherrill

One issue with this is that TLS is not supported on all architectures. We would either have to have two methods (current and TLS) to do this or fix TLS everywhere.

comment:2 Changed on 12/03/21 at 19:20:33 by Sebastian Huber

I am not sure what the Newlib maintainer say if we try to add a third reentrancy approach. I guess for backward compatibility they want to keep the existing methods anyway.

comment:3 Changed on 12/03/21 at 20:07:52 by Joel Sherrill

Keywords: SoC newlib added

comment:4 Changed on 12/06/21 at 08:19:37 by Chris Johns

I would like to see libdl support for TLS added to RTEMS.

comment:5 Changed on 01/28/22 at 07:35:58 by Sebastian Huber <sebastian.huber@…>

In b519e50/rtems:

sptests: Avoid a dependency on errno

Avoid a dependency on errno which might be a thread-local object. The tests
sp01, spstkalloc02, and sptls03 assume that no thread-local storage object is
present.

Update #4560.

comment:6 Changed on 01/28/22 at 07:38:25 by Sebastian Huber

comment:7 Changed on 02/04/22 at 18:54:45 by Gedare Bloom

Keywords: executive added

comment:8 Changed on 02/25/22 at 18:27:59 by Gedare Bloom

Description: modified (diff)
Keywords: large added

comment:9 Changed on 06/29/22 at 09:04:57 by Sebastian Huber

Milestone: 7.16.1
Version: 76

comment:10 Changed on 06/29/22 at 09:13:44 by Sebastian Huber

Blocked By: 4672 added

comment:11 Changed on 07/21/22 at 05:15:04 by Matt Joyce <matthew.joyce@…>

In 57a569e/rtems:

sptests: Disable Newlib reentrancy

Update #4560.

comment:12 Changed on 07/21/22 at 05:15:06 by Matt Joyce <matthew.joyce@…>

In 6d4b390/rtems:

Support _REENT_THREAD_LOCAL Newlib configuration

In case the Newlib _REENT_THREAD_LOCAL configuration option is enabled, the
struct _reent is not defined (there is only a forward declaration in
<sys/reent.h>). Instead, the usual members of struct _reent are available as
dedicatd thread-local storage objects.

Update #4560.

comment:13 Changed on 07/21/22 at 08:25:04 by Sebastian Huber <sebastian.huber@…>

In ae6e598/rtems-source-builder:

6/7: Update Newlib

This makes the --enable-newlib-reent-thread-local (_REENT_THREAD_LOCAL_STORAGE)
Newlib configuration option available.

Update #4560.

comment:14 Changed on 07/21/22 at 08:25:05 by Sebastian Huber <sebastian.huber@…>

In 958de50/rtems-source-builder:

newlib: Support --with/without-newlib-tls

This RSB option defines if the --enable-newlib-reent-thread-local
(_REENT_THREAD_LOCAL_STORAGE) Newlib configuration option is used or not.

Update #4560.

comment:15 Changed on 07/21/22 at 08:25:06 by Sebastian Huber <sebastian.huber@…>

In f4f5d43/rtems-source-builder:

6/7: Use TLS in Newlib for some targets by default

Use the --enable-newlib-reent-thread-local (_REENT_THREAD_LOCAL_STORAGE) Newlib
configuration option on the aarch64, arm, nios2, powerpc, riscv, and sparc
targets by default.

Update #4560.

comment:16 Changed on 08/08/22 at 18:23:20 by Sebastian Huber <sebastian.huber@…>

In eea3793/rtems-source-builder:

6: Use local-exec TLS model by default

Update #4560.

comment:17 Changed on 09/09/22 at 05:32:55 by Sebastian Huber <sebastian.huber@…>

In 91e8654/rtems-docs:

user: Document RSB --with/without-newlib-tls

Update #4560.

comment:18 Changed on 10/14/22 at 09:41:39 by Sebastian Huber <sebastian.huber@…>

In b9212e2/rtems:

sptls01: Disable file system and Newlib reentrancy

Update #4560.

comment:19 Changed on 11/29/22 at 22:38:23 by Chris Johns

Are we able to close this ticket?

comment:20 Changed on 11/30/22 at 08:59:07 by Sebastian Huber

Resolution: fixed
Status: assignedclosed

Yes, I recently were able to integrate the final patch for GCC 13. A follow up activity is #4765.

comment:21 Changed on 04/26/23 at 05:14:33 by Sebastian Huber <sebastian.huber@…>

In 908efe4/rtems-source-builder:

7: Use TLS in Newlib for m68k by default

Update #4560.

comment:22 Changed on 10/11/23 at 09:29:56 by Sebastian Huber

Keywords: qualification added
Note: See TracTickets for help on using tickets.