[PATCH 2/2] Support _REENT_THREAD_LOCAL Newlib configuration
Sebastian Huber
sebastian.huber at embedded-brains.de
Wed Jul 13 09:28:40 UTC 2022
From: Matt Joyce <matthew.joyce at embedded-brains.de>
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.
---
cpukit/include/rtems/confdefs/newlib.h | 3 ++-
cpukit/include/rtems/confdefs/threads.h | 6 ++++--
cpukit/include/rtems/libcsupport.h | 28 +++++++++++++++----------
cpukit/include/rtems/score/thread.h | 4 ++++
cpukit/libcsupport/src/newlibc_reent.c | 6 ++++++
testsuites/libtests/newlib01/init.c | 11 ++++++----
6 files changed, 40 insertions(+), 18 deletions(-)
diff --git a/cpukit/include/rtems/confdefs/newlib.h b/cpukit/include/rtems/confdefs/newlib.h
index 96bf850163..fef71a8855 100644
--- a/cpukit/include/rtems/confdefs/newlib.h
+++ b/cpukit/include/rtems/confdefs/newlib.h
@@ -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;
diff --git a/cpukit/include/rtems/confdefs/threads.h b/cpukit/include/rtems/confdefs/threads.h
index 503a4b20ec..8e4537f90b 100644
--- a/cpukit/include/rtems/confdefs/threads.h
+++ b/cpukit/include/rtems/confdefs/threads.h
@@ -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,
diff --git a/cpukit/include/rtems/libcsupport.h b/cpukit/include/rtems/libcsupport.h
index 212eb16e59..67a09dc2a2 100644
--- a/cpukit/include/rtems/libcsupport.h
+++ b/cpukit/include/rtems/libcsupport.h
@@ -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;
diff --git a/cpukit/include/rtems/score/thread.h b/cpukit/include/rtems/score/thread.h
index dd32b51a5f..94eab18ea3 100644
--- a/cpukit/include/rtems/score/thread.h
+++ b/cpukit/include/rtems/score/thread.h
@@ -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 ];
diff --git a/cpukit/libcsupport/src/newlibc_reent.c b/cpukit/libcsupport/src/newlibc_reent.c
index 2dccfd0375..ee82f00858 100644
--- a/cpukit/libcsupport/src/newlibc_reent.c
+++ b/cpukit/libcsupport/src/newlibc_reent.c
@@ -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
diff --git a/testsuites/libtests/newlib01/init.c b/testsuites/libtests/newlib01/init.c
index 0bb3c4628b..6edae3adbd 100644
--- a/testsuites/libtests/newlib01/init.c
+++ b/testsuites/libtests/newlib01/init.c
@@ -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);
--
2.35.3
More information about the devel
mailing list