forked from Imagelibrary/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.
This commit is contained in:
committed by
Sebastian Huber
parent
57a569efe1
commit
6d4b390f99
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 ];
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user