diff options
Diffstat (limited to 'newlib/libc')
28 files changed, 215 insertions, 0 deletions
diff --git a/newlib/libc/errno/errno.c b/newlib/libc/errno/errno.c index 7040292..384b07f 100644 --- a/newlib/libc/errno/errno.c +++ b/newlib/libc/errno/errno.c @@ -5,6 +5,10 @@ #include <errno.h> #include <reent.h> +#ifdef _REENT_THREAD_LOCAL +_Thread_local int _tls_errno; +#else /* !_REENT_THREAD_LOCAL */ + #ifndef _REENT_ONLY int * @@ -14,3 +18,5 @@ __errno () } #endif + +#endif /* _REENT_THREAD_LOCAL */ diff --git a/newlib/libc/include/sys/config.h b/newlib/libc/include/sys/config.h index 4bce10d..5dcc77a 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 995f30e..f150971 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 90f8481..71342be 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. */ diff --git a/newlib/libc/locale/locale.c b/newlib/libc/locale/locale.c index 9686427..e523d23 100644 --- a/newlib/libc/locale/locale.c +++ b/newlib/libc/locale/locale.c @@ -166,6 +166,10 @@ No supporting OS subroutines are required. #include "../ctype/ctype_.h" #include "../stdlib/local.h" +#ifdef _REENT_THREAD_LOCAL +_Thread_local struct __locale_t *_tls_locale; +#endif + #ifdef __CYGWIN__ /* Has to be kept available as exported symbol for backward compatibility. Set it in setlocale, but otherwise ignore it. Applications compiled after diff --git a/newlib/libc/reent/impure.c b/newlib/libc/reent/impure.c index 9290c9c..a87b91f 100644 --- a/newlib/libc/reent/impure.c +++ b/newlib/libc/reent/impure.c @@ -1,5 +1,7 @@ #include <reent.h> +#ifndef _REENT_THREAD_LOCAL + /* Redeclare these symbols locally as weak so that the file containing their definitions (along with a lot of other stuff) isn't sucked in unless they are actually used by other compilation units. This is @@ -14,3 +16,5 @@ struct _reent __ATTRIBUTE_IMPURE_DATA__ _impure_data = _REENT_INIT (_impure_data extern struct _reent reent_data __attribute__ ((alias("_impure_data"))); #endif struct _reent *__ATTRIBUTE_IMPURE_PTR__ _impure_ptr = &_impure_data; + +#endif /* _REENT_THREAD_LOCAL */ diff --git a/newlib/libc/reent/reent.c b/newlib/libc/reent/reent.c index 4e9485c..db80ca0 100644 --- a/newlib/libc/reent/reent.c +++ b/newlib/libc/reent/reent.c @@ -30,7 +30,9 @@ int errno; void _reclaim_reent (struct _reent *ptr) { +#ifndef _REENT_THREAD_LOCAL if (ptr != _impure_ptr) +#endif { /* used by mprec routines. */ #ifdef _REENT_SMALL diff --git a/newlib/libc/signal/signal.c b/newlib/libc/signal/signal.c index 3f14b47..77d78f0 100644 --- a/newlib/libc/signal/signal.c +++ b/newlib/libc/signal/signal.c @@ -88,6 +88,10 @@ int _dummy_simulated_signal; #include <reent.h> #include <_syslist.h> +#ifdef _REENT_THREAD_LOCAL +_Thread_local void (**_tls_sig_func)(int); +#endif + int _init_signal_r (struct _reent *ptr) { diff --git a/newlib/libc/stdio/findfp.c b/newlib/libc/stdio/findfp.c index fbdb7f2..c430282 100644 --- a/newlib/libc/stdio/findfp.c +++ b/newlib/libc/stdio/findfp.c @@ -32,6 +32,13 @@ __FILE __sf[3]; struct _glue __sglue = {NULL, 3, &__sf[0]}; +#ifdef _REENT_THREAD_LOCAL +_Thread_local __FILE *_tls_stdin = &__sf[0]; +_Thread_local __FILE *_tls_stdout = &__sf[1]; +_Thread_local __FILE *_tls_stderr = &__sf[2]; +_Thread_local void (*_tls_cleanup)(struct _reent *); +#endif + #ifdef _STDIO_BSD_SEMANTICS /* BSD and Glibc systems only flush streams which have been written to at exit time. Calling flush rather than close for speed, as on diff --git a/newlib/libc/stdio/tmpnam.c b/newlib/libc/stdio/tmpnam.c index 2767b4b..51dfd1c 100644 --- a/newlib/libc/stdio/tmpnam.c +++ b/newlib/libc/stdio/tmpnam.c @@ -82,6 +82,11 @@ The global pointer <<environ>> is also required. #include <reent.h> #include <errno.h> +#ifdef _REENT_THREAD_LOCAL +_Thread_local int _tls_inc; +_Thread_local char _tls_emergency; +#endif + /* Try to open the file specified, if it can't be opened then try another one. Return nonzero if successful, otherwise zero. */ diff --git a/newlib/libc/stdlib/dtoa.c b/newlib/libc/stdlib/dtoa.c index e47a8bc..198fa66 100644 --- a/newlib/libc/stdlib/dtoa.c +++ b/newlib/libc/stdlib/dtoa.c @@ -32,6 +32,11 @@ #include <string.h> #include "mprec.h" +#ifdef _REENT_THREAD_LOCAL +_Thread_local struct _Bigint *_tls_mp_result; +_Thread_local int _tls_mp_result_k; +#endif + static int quorem (_Bigint * b, _Bigint * S) { diff --git a/newlib/libc/stdlib/ecvtbuf.c b/newlib/libc/stdlib/ecvtbuf.c index 05f3151..5148966 100644 --- a/newlib/libc/stdlib/ecvtbuf.c +++ b/newlib/libc/stdlib/ecvtbuf.c @@ -57,6 +57,11 @@ Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>, #include "mprec.h" #include "local.h" +#ifdef _REENT_THREAD_LOCAL +_Thread_local char *_tls_cvtbuf; +_Thread_local int _tls_cvtlen; +#endif + static void print_f (struct _reent *ptr, char *buf, diff --git a/newlib/libc/stdlib/l64a.c b/newlib/libc/stdlib/l64a.c index 45282e3..6f12b61 100644 --- a/newlib/libc/stdlib/l64a.c +++ b/newlib/libc/stdlib/l64a.c @@ -24,6 +24,10 @@ #include <stdlib.h> #include <reent.h> +#ifdef _REENT_THREAD_LOCAL +_Thread_local char _tls_l64a_buf[8]; +#endif + static const char R64_ARRAY[] = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; char * diff --git a/newlib/libc/stdlib/lcong48.c b/newlib/libc/stdlib/lcong48.c index 78e9e57..d1109f0 100644 --- a/newlib/libc/stdlib/lcong48.c +++ b/newlib/libc/stdlib/lcong48.c @@ -13,6 +13,14 @@ #include "rand48.h" +#ifdef _REENT_THREAD_LOCAL +_Thread_local unsigned short _tls_rand48_seed[3] = {_RAND48_SEED_0, _RAND48_SEED_1, + _RAND48_SEED_2}; +_Thread_local unsigned short _tls_rand48_mult[3] = {_RAND48_MULT_0, _RAND48_MULT_1, + _RAND48_MULT_2}; +_Thread_local unsigned short _tls_rand48_add = _RAND48_ADD; +#endif + void _lcong48_r (struct _reent *r, unsigned short p[7]) diff --git a/newlib/libc/stdlib/mblen.c b/newlib/libc/stdlib/mblen.c index 3753d36..24df615 100644 --- a/newlib/libc/stdlib/mblen.c +++ b/newlib/libc/stdlib/mblen.c @@ -42,6 +42,10 @@ effects vary with the locale. #include <wchar.h> #include "local.h" +#ifdef _REENT_THREAD_LOCAL +_Thread_local _mbstate_t _tls_mblen_state; +#endif + int mblen (const char *s, size_t n) diff --git a/newlib/libc/stdlib/mbrlen.c b/newlib/libc/stdlib/mbrlen.c index 57a733f..39e175e 100644 --- a/newlib/libc/stdlib/mbrlen.c +++ b/newlib/libc/stdlib/mbrlen.c @@ -5,6 +5,10 @@ #include <stdio.h> #include <errno.h> +#ifdef _REENT_THREAD_LOCAL +_Thread_local _mbstate_t _tls_mbrlen_state; +#endif + size_t mbrlen(const char *__restrict s, size_t n, mbstate_t *__restrict ps) { diff --git a/newlib/libc/stdlib/mbrtowc.c b/newlib/libc/stdlib/mbrtowc.c index 521b7a5..e641b8c 100644 --- a/newlib/libc/stdlib/mbrtowc.c +++ b/newlib/libc/stdlib/mbrtowc.c @@ -7,6 +7,10 @@ #include <string.h> #include "local.h" +#ifdef _REENT_THREAD_LOCAL +_Thread_local _mbstate_t _tls_mbrtowc_state; +#endif + size_t _mbrtowc_r (struct _reent *ptr, wchar_t *pwc, diff --git a/newlib/libc/stdlib/mbsnrtowcs.c b/newlib/libc/stdlib/mbsnrtowcs.c index 8f94b1d..2effc50 100644 --- a/newlib/libc/stdlib/mbsnrtowcs.c +++ b/newlib/libc/stdlib/mbsnrtowcs.c @@ -70,6 +70,10 @@ PORTABILITY #include <stdio.h> #include <errno.h> +#ifdef _REENT_THREAD_LOCAL +_Thread_local _mbstate_t _tls_mbsrtowcs_state; +#endif + size_t _mbsnrtowcs_r (struct _reent *r, wchar_t *dst, diff --git a/newlib/libc/stdlib/mbtowc.c b/newlib/libc/stdlib/mbtowc.c index 2dc413f..fbd8df6 100644 --- a/newlib/libc/stdlib/mbtowc.c +++ b/newlib/libc/stdlib/mbtowc.c @@ -49,6 +49,10 @@ effects vary with the locale. #include <wchar.h> #include "local.h" +#ifdef _REENT_THREAD_LOCAL +_Thread_local _mbstate_t _tls_mbtowc_state; +#endif + int mbtowc (wchar_t *__restrict pwc, const char *__restrict s, diff --git a/newlib/libc/stdlib/mprec.c b/newlib/libc/stdlib/mprec.c index 930c984..1f534b0 100644 --- a/newlib/libc/stdlib/mprec.c +++ b/newlib/libc/stdlib/mprec.c @@ -86,6 +86,11 @@ #include <reent.h> #include "mprec.h" +#ifdef _REENT_THREAD_LOCAL +_Thread_local struct _Bigint *_tls_mp_p5s; +_Thread_local struct _Bigint **_tls_mp_freelist; +#endif + /* This is defined in sys/reent.h as (sizeof (size_t) << 3) now, as in NetBSD. The old value of 15 was wrong and made newlib vulnerable against buffer overrun attacks (CVE-2009-0689), same as other implementations of gdtoa diff --git a/newlib/libc/stdlib/rand.c b/newlib/libc/stdlib/rand.c index 209cb32..ba9cc80 100644 --- a/newlib/libc/stdlib/rand.c +++ b/newlib/libc/stdlib/rand.c @@ -58,6 +58,10 @@ on two different systems. #include <stdlib.h> #include <reent.h> +#ifdef _REENT_THREAD_LOCAL +_Thread_local unsigned long long _tls_rand_next = 1; +#endif + void srand (unsigned int seed) { diff --git a/newlib/libc/stdlib/wcrtomb.c b/newlib/libc/stdlib/wcrtomb.c index 6d670e2..1b84720 100644 --- a/newlib/libc/stdlib/wcrtomb.c +++ b/newlib/libc/stdlib/wcrtomb.c @@ -6,6 +6,10 @@ #include <errno.h> #include "local.h" +#ifdef _REENT_THREAD_LOCAL +_Thread_local _mbstate_t _tls_wcrtomb_state; +#endif + size_t _wcrtomb_r (struct _reent *ptr, char *s, diff --git a/newlib/libc/stdlib/wcsnrtombs.c b/newlib/libc/stdlib/wcsnrtombs.c index dfd974f..abef7ac 100644 --- a/newlib/libc/stdlib/wcsnrtombs.c +++ b/newlib/libc/stdlib/wcsnrtombs.c @@ -72,6 +72,10 @@ PORTABILITY #include "local.h" #include "../locale/setlocale.h" +#ifdef _REENT_THREAD_LOCAL +_Thread_local _mbstate_t _tls_wcsrtombs_state; +#endif + size_t _wcsnrtombs_l (struct _reent *r, char *dst, const wchar_t **src, size_t nwc, size_t len, mbstate_t *ps, struct __locale_t *loc) diff --git a/newlib/libc/stdlib/wctomb.c b/newlib/libc/stdlib/wctomb.c index e908d22..f56dccf 100644 --- a/newlib/libc/stdlib/wctomb.c +++ b/newlib/libc/stdlib/wctomb.c @@ -45,6 +45,10 @@ effects vary with the locale. #include <errno.h> #include "local.h" +#ifdef _REENT_THREAD_LOCAL +_Thread_local _mbstate_t _tls_wctomb_state; +#endif + int wctomb (char *s, wchar_t wchar) diff --git a/newlib/libc/string/strsignal.c b/newlib/libc/string/strsignal.c index 544857b..89d39fe 100644 --- a/newlib/libc/string/strsignal.c +++ b/newlib/libc/string/strsignal.c @@ -52,6 +52,10 @@ QUICKREF #include <stdlib.h> #include <reent.h> +#ifdef _REENT_THREAD_LOCAL +_Thread_local char _tls_signal_buf[_REENT_SIGNAL_SIZE]; +#endif + char * strsignal (int signal) { diff --git a/newlib/libc/string/strtok.c b/newlib/libc/string/strtok.c index 801f51a..2a11c91 100644 --- a/newlib/libc/string/strtok.c +++ b/newlib/libc/string/strtok.c @@ -74,6 +74,10 @@ QUICKREF #include <_ansi.h> #include <reent.h> +#ifdef _REENT_THREAD_LOCAL +_Thread_local char *_tls_strtok_last; +#endif + #ifndef _REENT_ONLY extern char *__strtok_r (char *, const char *, char **, int); diff --git a/newlib/libc/time/asctime.c b/newlib/libc/time/asctime.c index 9aa26c3..a815061 100644 --- a/newlib/libc/time/asctime.c +++ b/newlib/libc/time/asctime.c @@ -45,6 +45,10 @@ ANSI C requires <<asctime>>. #include <_ansi.h> #include <reent.h> +#ifdef _REENT_THREAD_LOCAL +_Thread_local char _tls_asctime_buf[_REENT_ASCTIME_SIZE]; +#endif + #ifndef _REENT_ONLY char * diff --git a/newlib/libc/time/gmtime.c b/newlib/libc/time/gmtime.c index 08e0111..a78d554 100644 --- a/newlib/libc/time/gmtime.c +++ b/newlib/libc/time/gmtime.c @@ -47,6 +47,10 @@ ANSI C requires <<gmtime>>. #define _GMT_OFFSET 0 +#ifdef _REENT_THREAD_LOCAL +_Thread_local struct __tm _tls_localtime_buf; +#endif + #ifndef _REENT_ONLY struct tm * |