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" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _CONFIGURE_ENABLE_NEWLIB_REENTRANCY
|
#if defined(_CONFIGURE_ENABLE_NEWLIB_REENTRANCY) && \
|
||||||
|
!defined(_REENT_THREAD_LOCAL)
|
||||||
struct _reent *__getreent( void )
|
struct _reent *__getreent( void )
|
||||||
{
|
{
|
||||||
return _Thread_Get_executing()->libc_reent;
|
return _Thread_Get_executing()->libc_reent;
|
||||||
|
|||||||
@@ -159,7 +159,8 @@ struct Thread_Configured_control {
|
|||||||
#if CONFIGURE_MAXIMUM_THREAD_NAME_SIZE > 1
|
#if CONFIGURE_MAXIMUM_THREAD_NAME_SIZE > 1
|
||||||
char name[ CONFIGURE_MAXIMUM_THREAD_NAME_SIZE ];
|
char name[ CONFIGURE_MAXIMUM_THREAD_NAME_SIZE ];
|
||||||
#endif
|
#endif
|
||||||
#ifdef _CONFIGURE_ENABLE_NEWLIB_REENTRANCY
|
#if defined(_CONFIGURE_ENABLE_NEWLIB_REENTRANCY) && \
|
||||||
|
!defined(_REENT_THREAD_LOCAL)
|
||||||
struct _reent Newlib;
|
struct _reent Newlib;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
@@ -175,7 +176,8 @@ const Thread_Control_add_on _Thread_Control_add_ons[] = {
|
|||||||
),
|
),
|
||||||
offsetof( Thread_Configured_control, API_RTEMS )
|
offsetof( Thread_Configured_control, API_RTEMS )
|
||||||
}
|
}
|
||||||
#ifdef _CONFIGURE_ENABLE_NEWLIB_REENTRANCY
|
#if defined(_CONFIGURE_ENABLE_NEWLIB_REENTRANCY) && \
|
||||||
|
!defined(_REENT_THREAD_LOCAL)
|
||||||
, {
|
, {
|
||||||
offsetof(
|
offsetof(
|
||||||
Thread_Configured_control,
|
Thread_Configured_control,
|
||||||
|
|||||||
@@ -96,27 +96,33 @@ extern int malloc_info(Heap_Information_block *the_info);
|
|||||||
/*
|
/*
|
||||||
* Prototypes required to install newlib reentrancy user extension
|
* Prototypes required to install newlib reentrancy user extension
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef _REENT_THREAD_LOCAL
|
||||||
|
#define _NEWLIB_CREATE_HOOK NULL
|
||||||
|
#else
|
||||||
bool newlib_create_hook(
|
bool newlib_create_hook(
|
||||||
rtems_tcb *current_task,
|
rtems_tcb *current_task,
|
||||||
rtems_tcb *creating_task
|
rtems_tcb *creating_task
|
||||||
);
|
);
|
||||||
|
#define _NEWLIB_CREATE_HOOK newlib_create_hook
|
||||||
|
#endif
|
||||||
|
|
||||||
void newlib_terminate_hook(
|
void newlib_terminate_hook(
|
||||||
rtems_tcb *current_task
|
rtems_tcb *current_task
|
||||||
);
|
);
|
||||||
|
|
||||||
#define RTEMS_NEWLIB_EXTENSION \
|
#define RTEMS_NEWLIB_EXTENSION \
|
||||||
{ \
|
{ \
|
||||||
newlib_create_hook, /* rtems_task_create */ \
|
_NEWLIB_CREATE_HOOK, /* thread_create */ \
|
||||||
0, /* rtems_task_start */ \
|
NULL, /* thread_start */ \
|
||||||
0, /* rtems_task_restart */ \
|
NULL, /* thread_restart */ \
|
||||||
0, /* rtems_task_delete */ \
|
NULL, /* thread_delete */ \
|
||||||
0, /* task_switch */ \
|
NULL, /* thread_switch */ \
|
||||||
0, /* task_begin */ \
|
NULL, /* thread_begin */ \
|
||||||
0, /* task_exitted */ \
|
NULL, /* thread_exitted */ \
|
||||||
0, /* fatal */ \
|
NULL, /* fatal */ \
|
||||||
newlib_terminate_hook /* thread terminate */ \
|
newlib_terminate_hook /* thread_terminate */ \
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t active_barriers;
|
uint32_t active_barriers;
|
||||||
|
|||||||
@@ -921,8 +921,12 @@ struct _Thread_Control {
|
|||||||
*/
|
*/
|
||||||
Context_Control_fp *fp_context;
|
Context_Control_fp *fp_context;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef _REENT_THREAD_LOCAL
|
||||||
/** This field points to the newlib reentrancy structure for this thread. */
|
/** This field points to the newlib reentrancy structure for this thread. */
|
||||||
struct _reent *libc_reent;
|
struct _reent *libc_reent;
|
||||||
|
#endif
|
||||||
|
|
||||||
/** This array contains the API extension area pointers. */
|
/** This array contains the API extension area pointers. */
|
||||||
void *API_Extensions[ THREAD_API_LAST + 1 ];
|
void *API_Extensions[ THREAD_API_LAST + 1 ];
|
||||||
|
|
||||||
|
|||||||
@@ -15,8 +15,10 @@
|
|||||||
#if defined(RTEMS_NEWLIB)
|
#if defined(RTEMS_NEWLIB)
|
||||||
#include <sys/reent.h>
|
#include <sys/reent.h>
|
||||||
|
|
||||||
|
#ifndef _REENT_THREAD_LOCAL
|
||||||
struct _reent *__getreent(void)
|
struct _reent *__getreent(void)
|
||||||
{
|
{
|
||||||
return _GLOBAL_REENT;
|
return _GLOBAL_REENT;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|||||||
@@ -29,6 +29,7 @@
|
|||||||
#include <rtems/libcsupport.h>
|
#include <rtems/libcsupport.h>
|
||||||
#include <rtems/score/threadimpl.h>
|
#include <rtems/score/threadimpl.h>
|
||||||
|
|
||||||
|
#ifndef _REENT_THREAD_LOCAL
|
||||||
bool newlib_create_hook(
|
bool newlib_create_hook(
|
||||||
rtems_tcb *current_task RTEMS_UNUSED,
|
rtems_tcb *current_task RTEMS_UNUSED,
|
||||||
rtems_tcb *creating_task
|
rtems_tcb *creating_task
|
||||||
@@ -38,12 +39,17 @@ bool newlib_create_hook(
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void newlib_terminate_hook(
|
void newlib_terminate_hook(
|
||||||
rtems_tcb *current_task
|
rtems_tcb *current_task
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
#ifdef _REENT_THREAD_LOCAL
|
||||||
|
_reclaim_reent(NULL);
|
||||||
|
#else
|
||||||
_reclaim_reent(current_task->libc_reent);
|
_reclaim_reent(current_task->libc_reent);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -43,6 +43,10 @@
|
|||||||
|
|
||||||
#include "tmacros.h"
|
#include "tmacros.h"
|
||||||
|
|
||||||
|
#ifndef _REENT_CLEANUP
|
||||||
|
#define _REENT_CLEANUP(ptr) ((ptr)->__cleanup)
|
||||||
|
#endif
|
||||||
|
|
||||||
const char rtems_test_name[] = "NEWLIB 1";
|
const char rtems_test_name[] = "NEWLIB 1";
|
||||||
|
|
||||||
static const char stdio_file_path[] = "/stdio-file";
|
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)
|
static void stdio_file_worker(rtems_task_argument arg)
|
||||||
{
|
{
|
||||||
test_context *ctx = &test_instance;
|
test_context *ctx = &test_instance;
|
||||||
struct _reent *reent = _REENT;
|
|
||||||
FILE *output;
|
FILE *output;
|
||||||
char buf[1] = { 'x' };
|
char buf[1] = { 'x' };
|
||||||
size_t n;
|
size_t n;
|
||||||
@@ -137,7 +140,7 @@ static void stdio_file_worker(rtems_task_argument arg)
|
|||||||
test_rand();
|
test_rand();
|
||||||
test_lrand48();
|
test_lrand48();
|
||||||
|
|
||||||
rtems_test_assert(reent->__cleanup == NULL);
|
rtems_test_assert(_REENT_CLEANUP(_REENT) == NULL);
|
||||||
|
|
||||||
output = stdout = fopen(&stdio_file_path[0], "r+");
|
output = stdout = fopen(&stdio_file_path[0], "r+");
|
||||||
rtems_test_assert(stdout != NULL);
|
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.
|
* 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(fflush(stdout) == 0);
|
||||||
rtems_test_assert(reent->__cleanup != NULL);
|
rtems_test_assert(_REENT_CLEANUP(_REENT) != NULL);
|
||||||
rtems_test_assert(stdout == output);
|
rtems_test_assert(stdout == output);
|
||||||
|
|
||||||
n = fwrite(&buf[0], sizeof(buf), 1, stdout);
|
n = fwrite(&buf[0], sizeof(buf), 1, stdout);
|
||||||
|
|||||||
Reference in New Issue
Block a user