Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatt Joyce <matthew.joyce@embedded-brains.de>2022-05-16 12:51:54 +0300
committerSebastian Huber <sebastian.huber@embedded-brains.de>2022-07-13 07:55:46 +0300
commitea99f21ce6c8a332845439ea87f792dbaf679d42 (patch)
tree94cfcaf461882955f7461b09d6c4c0e2f321e66e /newlib/libc/include
parent1a0908203606527b6ac0ed438669b5bcd247a5f9 (diff)
Add --enable-newlib-reent-thread-local option
By default, Newlib uses a huge object of type struct _reent to store thread-specific data. This object is returned by __getreent() if the __DYNAMIC_REENT__ Newlib configuration option is defined. The reentrancy structure contains for example errno and 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 even if it does not use it. This is an issue for lower end targets and applications which need to qualify the software according to safety standards (for example ECSS-E-ST-40C, ECSS-Q-ST-80C, IEC 61508, ISO 26262, DO-178, DO-330, DO-333). If the new _REENT_THREAD_LOCAL configuration option is enabled, then struct _reent is replaced by dedicated thread-local objects for each struct _reent member. The thread-local objects are defined in translation units which use the corresponding object.
Diffstat (limited to 'newlib/libc/include')
-rw-r--r--newlib/libc/include/sys/config.h6
-rw-r--r--newlib/libc/include/sys/errno.h6
-rw-r--r--newlib/libc/include/sys/reent.h92
3 files changed, 104 insertions, 0 deletions
diff --git a/newlib/libc/include/sys/config.h b/newlib/libc/include/sys/config.h
index 4bce10de3..5dcc77a80 100644
--- a/newlib/libc/include/sys/config.h
+++ b/newlib/libc/include/sys/config.h
@@ -297,6 +297,12 @@
#endif
#endif
+#ifdef _WANT_REENT_THREAD_LOCAL
+#ifndef _REENT_THREAD_LOCAL
+#define _REENT_THREAD_LOCAL
+#endif
+#endif
+
/* If _MB_EXTENDED_CHARSETS_ALL is set, we want all of the extended
charsets. The extended charsets add a few functions and a couple
of tables of a few K each. */
diff --git a/newlib/libc/include/sys/errno.h b/newlib/libc/include/sys/errno.h
index 995f30e05..f1509712e 100644
--- a/newlib/libc/include/sys/errno.h
+++ b/newlib/libc/include/sys/errno.h
@@ -10,11 +10,17 @@ extern "C" {
#include <sys/reent.h>
+#ifdef _REENT_THREAD_LOCAL
+#define errno (_tls_errno)
+#else /* _REENT_THREAD_LOCAL */
+
#ifndef _REENT_ONLY
#define errno (*__errno())
extern int *__errno (void);
#endif
+#endif /* _REENT_THREAD_LOCAL */
+
/* Please don't use these variables directly.
Use strerror instead. */
extern __IMPORT const char * const _sys_errlist[];
diff --git a/newlib/libc/include/sys/reent.h b/newlib/libc/include/sys/reent.h
index 90f848180..71342bebc 100644
--- a/newlib/libc/include/sys/reent.h
+++ b/newlib/libc/include/sys/reent.h
@@ -301,6 +301,8 @@ struct _rand48 {
#define _REENT_ASCTIME_SIZE 26
#define _REENT_SIGNAL_SIZE 24
+#ifndef _REENT_THREAD_LOCAL
+
#ifdef _REENT_BACKWARD_BINARY_COMPAT
#define _REENT_INIT_RESERVED_0 0,
#define _REENT_INIT_RESERVED_1 0,
@@ -767,6 +769,96 @@ extern struct _reent _impure_data __ATTRIBUTE_IMPURE_DATA__;
#define _GLOBAL_REENT (&_impure_data)
+#else /* _REENT_THREAD_LOCAL */
+
+#define _REENT NULL
+#define _GLOBAL_REENT NULL
+
+/*
+ * Since _REENT is defined as NULL, this macro ensures that calls to
+ * CHECK_INIT() do not automatically fail.
+ */
+#define _REENT_IS_NULL(_ptr) 0
+
+#define _REENT_CHECK_RAND48(ptr) /* nothing */
+#define _REENT_CHECK_MP(ptr) /* nothing */
+#define _REENT_CHECK_TM(ptr) /* nothing */
+#define _REENT_CHECK_ASCTIME_BUF(ptr) /* nothing */
+#define _REENT_CHECK_EMERGENCY(ptr) /* nothing */
+#define _REENT_CHECK_MISC(ptr) /* nothing */
+#define _REENT_CHECK_SIGNAL_BUF(ptr) /* nothing */
+
+extern _Thread_local char _tls_asctime_buf[_REENT_ASCTIME_SIZE];
+#define _REENT_ASCTIME_BUF(_ptr) (_tls_asctime_buf)
+extern _Thread_local char *_tls_cvtbuf;
+#define _REENT_CVTBUF(_ptr) (_tls_cvtbuf)
+extern _Thread_local int _tls_cvtlen;
+#define _REENT_CVTLEN(_ptr) (_tls_cvtlen)
+extern _Thread_local void (*_tls_cleanup)(struct _reent *);
+#define _REENT_CLEANUP(_ptr) (_tls_cleanup)
+extern _Thread_local char _tls_emergency;
+#define _REENT_EMERGENCY(_ptr) (_tls_emergency)
+extern _Thread_local int _tls_errno;
+#define _REENT_ERRNO(_ptr) (_tls_errno)
+extern _Thread_local int _tls_getdate_err;
+#define _REENT_GETDATE_ERR_P(_ptr) (&_tls_getdate_err)
+extern _Thread_local int _tls_inc;
+#define _REENT_INC(_ptr) (_tls_inc)
+extern _Thread_local char _tls_l64a_buf[8];
+#define _REENT_L64A_BUF(_ptr) (_tls_l64a_buf)
+extern _Thread_local struct __locale_t *_tls_locale;
+#define _REENT_LOCALE(_ptr) (_tls_locale)
+extern _Thread_local _mbstate_t _tls_mblen_state;
+#define _REENT_MBLEN_STATE(_ptr) (_tls_mblen_state)
+extern _Thread_local _mbstate_t _tls_mbrlen_state;
+#define _REENT_MBRLEN_STATE(_ptr) (_tls_mbrlen_state)
+extern _Thread_local _mbstate_t _tls_mbrtowc_state;
+#define _REENT_MBRTOWC_STATE(_ptr) (_tls_mbrtowc_state)
+extern _Thread_local _mbstate_t _tls_mbsrtowcs_state;
+#define _REENT_MBSRTOWCS_STATE(_ptr) (_tls_mbsrtowcs_state)
+extern _Thread_local _mbstate_t _tls_mbtowc_state;
+#define _REENT_MBTOWC_STATE(_ptr) (_tls_mbtowc_state)
+extern _Thread_local struct _Bigint **_tls_mp_freelist;
+#define _REENT_MP_FREELIST(_ptr) (_tls_mp_freelist)
+extern _Thread_local struct _Bigint *_tls_mp_p5s;
+#define _REENT_MP_P5S(_ptr) (_tls_mp_p5s)
+extern _Thread_local struct _Bigint *_tls_mp_result;
+#define _REENT_MP_RESULT(_ptr) (_tls_mp_result)
+extern _Thread_local int _tls_mp_result_k;
+#define _REENT_MP_RESULT_K(_ptr) (_tls_mp_result_k)
+extern _Thread_local unsigned short _tls_rand48_add;
+#define _REENT_RAND48_ADD(_ptr) (_tls_rand48_add)
+extern _Thread_local unsigned short _tls_rand48_mult[3];
+#define _REENT_RAND48_MULT(_ptr) (_tls_rand48_mult)
+extern _Thread_local unsigned short _tls_rand48_seed[3];
+#define _REENT_RAND48_SEED(_ptr) (_tls_rand48_seed)
+extern _Thread_local unsigned long long _tls_rand_next;
+#define _REENT_RAND_NEXT(_ptr) (_tls_rand_next)
+extern _Thread_local void (**_tls_sig_func)(int);
+#define _REENT_SIG_FUNC(_ptr) (_tls_sig_func)
+extern _Thread_local char _tls_signal_buf[_REENT_SIGNAL_SIZE];
+#define _REENT_SIGNAL_BUF(_ptr) (_tls_signal_buf)
+extern _Thread_local int _tls_gamma_signgam;
+#define _REENT_SIGNGAM(_ptr) (_tls_gamma_signgam)
+extern _Thread_local __FILE *_tls_stdin;
+#define _REENT_STDIN(_ptr) (_tls_stdin)
+extern _Thread_local __FILE *_tls_stdout;
+#define _REENT_STDOUT(_ptr) (_tls_stdout)
+extern _Thread_local __FILE *_tls_stderr;
+#define _REENT_STDERR(_ptr) (_tls_stderr)
+extern _Thread_local char *_tls_strtok_last;
+#define _REENT_STRTOK_LAST(_ptr) (_tls_strtok_last)
+extern _Thread_local struct __tm _tls_localtime_buf;
+#define _REENT_TM(_ptr) (&_tls_localtime_buf)
+extern _Thread_local _mbstate_t _tls_wctomb_state;
+#define _REENT_WCTOMB_STATE(_ptr) (_tls_wctomb_state)
+extern _Thread_local _mbstate_t _tls_wcrtomb_state;
+#define _REENT_WCRTOMB_STATE(_ptr) (_tls_wcrtomb_state)
+extern _Thread_local _mbstate_t _tls_wcsrtombs_state;
+#define _REENT_WCSRTOMBS_STATE(_ptr) (_tls_wcsrtombs_state)
+
+#endif /* !_REENT_THREAD_LOCAL */
+
/* This value is used in stdlib/misc.c. reent/reent.c has to know it
as well to make sure the freelist is correctly free'd. Therefore
we define it here, rather than in stdlib/misc.c, as before. */