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.
This commit is contained in:
Matt Joyce
2022-05-23 12:27:56 +02:00
committed by Sebastian Huber
parent 57a569efe1
commit 6d4b390f99
7 changed files with 42 additions and 18 deletions

View File

@@ -57,7 +57,8 @@
extern "C" {
#endif
#ifdef _CONFIGURE_ENABLE_NEWLIB_REENTRANCY
#if defined(_CONFIGURE_ENABLE_NEWLIB_REENTRANCY) && \
!defined(_REENT_THREAD_LOCAL)
struct _reent *__getreent( void )
{
return _Thread_Get_executing()->libc_reent;

View File

@@ -159,7 +159,8 @@ struct Thread_Configured_control {
#if CONFIGURE_MAXIMUM_THREAD_NAME_SIZE > 1
char name[ CONFIGURE_MAXIMUM_THREAD_NAME_SIZE ];
#endif
#ifdef _CONFIGURE_ENABLE_NEWLIB_REENTRANCY
#if defined(_CONFIGURE_ENABLE_NEWLIB_REENTRANCY) && \
!defined(_REENT_THREAD_LOCAL)
struct _reent Newlib;
#endif
};
@@ -175,7 +176,8 @@ const Thread_Control_add_on _Thread_Control_add_ons[] = {
),
offsetof( Thread_Configured_control, API_RTEMS )
}
#ifdef _CONFIGURE_ENABLE_NEWLIB_REENTRANCY
#if defined(_CONFIGURE_ENABLE_NEWLIB_REENTRANCY) && \
!defined(_REENT_THREAD_LOCAL)
, {
offsetof(
Thread_Configured_control,

View File

@@ -96,27 +96,33 @@ extern int malloc_info(Heap_Information_block *the_info);
/*
* Prototypes required to install newlib reentrancy user extension
*/
#ifdef _REENT_THREAD_LOCAL
#define _NEWLIB_CREATE_HOOK NULL
#else
bool newlib_create_hook(
rtems_tcb *current_task,
rtems_tcb *creating_task
);
#define _NEWLIB_CREATE_HOOK newlib_create_hook
#endif
void newlib_terminate_hook(
rtems_tcb *current_task
);
#define RTEMS_NEWLIB_EXTENSION \
{ \
newlib_create_hook, /* rtems_task_create */ \
0, /* rtems_task_start */ \
0, /* rtems_task_restart */ \
0, /* rtems_task_delete */ \
0, /* task_switch */ \
0, /* task_begin */ \
0, /* task_exitted */ \
0, /* fatal */ \
newlib_terminate_hook /* thread terminate */ \
}
{ \
_NEWLIB_CREATE_HOOK, /* thread_create */ \
NULL, /* thread_start */ \
NULL, /* thread_restart */ \
NULL, /* thread_delete */ \
NULL, /* thread_switch */ \
NULL, /* thread_begin */ \
NULL, /* thread_exitted */ \
NULL, /* fatal */ \
newlib_terminate_hook /* thread_terminate */ \
}
typedef struct {
uint32_t active_barriers;

View File

@@ -921,8 +921,12 @@ struct _Thread_Control {
*/
Context_Control_fp *fp_context;
#endif
#ifndef _REENT_THREAD_LOCAL
/** This field points to the newlib reentrancy structure for this thread. */
struct _reent *libc_reent;
#endif
/** This array contains the API extension area pointers. */
void *API_Extensions[ THREAD_API_LAST + 1 ];

View File

@@ -15,8 +15,10 @@
#if defined(RTEMS_NEWLIB)
#include <sys/reent.h>
#ifndef _REENT_THREAD_LOCAL
struct _reent *__getreent(void)
{
return _GLOBAL_REENT;
}
#endif
#endif

View File

@@ -29,6 +29,7 @@
#include <rtems/libcsupport.h>
#include <rtems/score/threadimpl.h>
#ifndef _REENT_THREAD_LOCAL
bool newlib_create_hook(
rtems_tcb *current_task RTEMS_UNUSED,
rtems_tcb *creating_task
@@ -38,12 +39,17 @@ bool newlib_create_hook(
return true;
}
#endif
void newlib_terminate_hook(
rtems_tcb *current_task
)
{
#ifdef _REENT_THREAD_LOCAL
_reclaim_reent(NULL);
#else
_reclaim_reent(current_task->libc_reent);
#endif
}
#endif

View File

@@ -43,6 +43,10 @@
#include "tmacros.h"
#ifndef _REENT_CLEANUP
#define _REENT_CLEANUP(ptr) ((ptr)->__cleanup)
#endif
const char rtems_test_name[] = "NEWLIB 1";
static const char stdio_file_path[] = "/stdio-file";
@@ -129,7 +133,6 @@ static void test_lrand48(void)
static void stdio_file_worker(rtems_task_argument arg)
{
test_context *ctx = &test_instance;
struct _reent *reent = _REENT;
FILE *output;
char buf[1] = { 'x' };
size_t n;
@@ -137,7 +140,7 @@ static void stdio_file_worker(rtems_task_argument arg)
test_rand();
test_lrand48();
rtems_test_assert(reent->__cleanup == NULL);
rtems_test_assert(_REENT_CLEANUP(_REENT) == NULL);
output = stdout = fopen(&stdio_file_path[0], "r+");
rtems_test_assert(stdout != NULL);
@@ -145,9 +148,9 @@ static void stdio_file_worker(rtems_task_argument arg)
/*
* Check newlib's __sinit does not touch our assigned file pointer.
*/
rtems_test_assert(reent->__cleanup == NULL);
rtems_test_assert(_REENT_CLEANUP(_REENT) == NULL);
rtems_test_assert(fflush(stdout) == 0);
rtems_test_assert(reent->__cleanup != NULL);
rtems_test_assert(_REENT_CLEANUP(_REENT) != NULL);
rtems_test_assert(stdout == output);
n = fwrite(&buf[0], sizeof(buf), 1, stdout);