From cf684340ce723e2ec50e8f82d8c10947360518d2 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Mon, 2 Sep 2002 07:09:08 +0000 Subject: [PATCH] * ctype/ctype.h (__ctype_b, __ctype_toupper, __ctype_tolower): Variable declarations removed. (__ctype_b_loc, __ctype_toupper_loc, __ctype_tolower_loc): Declare these functions to replace them. (__isctype, tolower, toupper, _tolower, _toupper): Use those accessor functions plus an indirection rather than the old global variables. * include/ctype.h (__isctype, tolower, _tolower, toupper, _toupper): Macros removed. (__ctype_b_loc, __ctype_toupper_loc, __ctype_tolower_loc): New extern inline functions. * ctype/ctype-info.c: Revert last reversion back the other way. Define tsd vars CTYPE_B, CTYPE_TOLOWER, CTYPE_TOUPPER. Define real function versions of include/ctype.h inlines here. * ctype/Versions (libc: GLIBC_2.3): Add __ctype_b_loc, __ctype_tolower_loc, __ctype_toupper_loc. * locale/lc-ctype.c: Revert last reversion back the other way. (_nl_postload_ctype): If current thread uses the global locale, update its tsd vars. * locale/uselocale.c (__uselocale): Update tsd vars from new locale. * hurd/hurd/threadvar.h (enum __hurd_threadvar_index): Add CTYPE_B, CTYPE_TOLOWER, CTYPE_TOUPPER. * sysdeps/generic/bits/libc-tsd.h (__libc_tsd_address): New macro. * sysdeps/mach/hurd/bits/libc-tsd.h (__libc_tsd_address): Renamed from __libc_tsd_threadvar_location. (__libc_tsd_set, __libc_tsd_get): Update uses. --- ChangeLog | 29 +++++++++++ bits/libc-tsd.h | 4 ++ ctype/Versions | 3 ++ ctype/ctype-info.c | 56 +++++++++----------- ctype/ctype.h | 28 ++++++---- hurd/hurd/threadvar.h | 5 +- include/ctype.h | 77 +++++++++++++++++----------- linuxthreads/ChangeLog | 13 +++++ linuxthreads/sysdeps/pthread/bits/libc-tsd.h | 10 ++++ locale/lc-ctype.c | 76 ++++++++++++++------------- locale/uselocale.c | 6 +++ sysdeps/generic/bits/libc-tsd.h | 4 ++ sysdeps/mach/hurd/bits/libc-tsd.h | 11 ++-- 13 files changed, 207 insertions(+), 115 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8e78415..0f914b1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,32 @@ +2002-09-01 Roland McGrath + + * ctype/ctype.h (__ctype_b, __ctype_toupper, __ctype_tolower): + Variable declarations removed. + (__ctype_b_loc, __ctype_toupper_loc, __ctype_tolower_loc): Declare + these functions to replace them. + (__isctype, tolower, toupper, _tolower, _toupper): Use those accessor + functions plus an indirection rather than the old global variables. + * include/ctype.h (__isctype, tolower, _tolower, toupper, _toupper): + Macros removed. + (__ctype_b_loc, __ctype_toupper_loc, __ctype_tolower_loc): New extern + inline functions. + * ctype/ctype-info.c: Revert last reversion back the other way. + Define tsd vars CTYPE_B, CTYPE_TOLOWER, CTYPE_TOUPPER. + Define real function versions of include/ctype.h inlines here. + * ctype/Versions (libc: GLIBC_2.3): Add __ctype_b_loc, + __ctype_tolower_loc, __ctype_toupper_loc. + * locale/lc-ctype.c: Revert last reversion back the other way. + (_nl_postload_ctype): If current thread uses the global locale, + update its tsd vars. + * locale/uselocale.c (__uselocale): Update tsd vars from new locale. + * hurd/hurd/threadvar.h (enum __hurd_threadvar_index): Add CTYPE_B, + CTYPE_TOLOWER, CTYPE_TOUPPER. + + * sysdeps/generic/bits/libc-tsd.h (__libc_tsd_address): New macro. + * sysdeps/mach/hurd/bits/libc-tsd.h (__libc_tsd_address): Renamed + from __libc_tsd_threadvar_location. + (__libc_tsd_set, __libc_tsd_get): Update uses. + 2002-09-01 Ulrich Drepper * ctype/ctype.h: Undo the patch before the last one. Put back the diff --git a/bits/libc-tsd.h b/bits/libc-tsd.h index 3c77e15..ce25601 100644 --- a/bits/libc-tsd.h +++ b/bits/libc-tsd.h @@ -28,6 +28,8 @@ keys used in only one source file, empty for global definitions, or `extern' for global declarations. + __libc_tsd_address(KEY) -- Return the `void **' pointing to + the current thread's datum for KEY. __libc_tsd_get(KEY) -- Return the `void *' datum for KEY. __libc_tsd_set(KEY, VALUE) -- Set the datum for KEY to VALUE. @@ -52,11 +54,13 @@ #if USE_TLS && HAVE___THREAD # define __libc_tsd_define(CLASS, KEY) CLASS __thread void *__libc_tsd_##KEY; +# define __libc_tsd_address(KEY) (&__libc_tsd_##KEY) # define __libc_tsd_get(KEY) (__libc_tsd_##KEY) # define __libc_tsd_set(KEY, VALUE) (__libc_tsd_##KEY = (VALUE)) #else # define __libc_tsd_define(CLASS, KEY) CLASS void *__libc_tsd_##KEY##_data; +# define __libc_tsd_address(KEY) (&__libc_tsd_##KEY) # define __libc_tsd_get(KEY) (__libc_tsd_##KEY##_data) # define __libc_tsd_set(KEY, VALUE) (__libc_tsd_##KEY##_data = (VALUE)) #endif diff --git a/ctype/Versions b/ctype/Versions index f77b5be..8cf0338 100644 --- a/ctype/Versions +++ b/ctype/Versions @@ -17,5 +17,8 @@ libc { } GLIBC_2.3 { isctype; __isctype; + + # functions used by optimized macros in ctype.h + __ctype_b_loc; __ctype_tolower_loc; __ctype_toupper_loc; } } diff --git a/ctype/ctype-info.c b/ctype/ctype-info.c index d29edb7..30c6d55 100644 --- a/ctype/ctype-info.c +++ b/ctype/ctype-info.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991,92,95,96,97,99,2000,2002 Free Software Foundation, Inc. +/* Copyright (C) 1991,92,95,96,97,99,2000,02 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -16,9 +16,18 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ +#define CTYPE_EXTERN_INLINE /* Define real functions for accessors. */ #include #include +__libc_tsd_define (, CTYPE_B) +__libc_tsd_define (, CTYPE_TOLOWER) +__libc_tsd_define (, CTYPE_TOUPPER) + + +#include +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3) + /* Defined in locale/C-ctype.c. */ extern const char _nl_C_LC_CTYPE_class[] attribute_hidden; extern const char _nl_C_LC_CTYPE_class32[] attribute_hidden; @@ -36,36 +45,21 @@ extern const char _nl_C_LC_CTYPE_class_blank[] attribute_hidden; extern const char _nl_C_LC_CTYPE_class_cntrl[] attribute_hidden; extern const char _nl_C_LC_CTYPE_class_punct[] attribute_hidden; extern const char _nl_C_LC_CTYPE_class_alnum[] attribute_hidden; -extern const char _nl_C_LC_CTYPE_map_toupper[] attribute_hidden; -extern const char _nl_C_LC_CTYPE_map_tolower[] attribute_hidden; -extern const char _nl_C_LC_CTYPE_width[] attribute_hidden; #define b(t,x,o) (((const t *) _nl_C_LC_CTYPE_##x) + o) -const unsigned short int *__ctype_b = b (unsigned short int, class, 128); -const __uint32_t *__ctype32_b = b (__uint32_t, class32, 0); -const __int32_t *__ctype_tolower = b (__int32_t, tolower, 128); -const __int32_t *__ctype_toupper = b (__int32_t, toupper, 128); -const __uint32_t *__ctype32_tolower = b (__uint32_t, tolower, 128); -const __uint32_t *__ctype32_toupper = b (__uint32_t, toupper, 128); -const char *__ctype32_wctype[12] attribute_hidden = -{ - b(char, class_upper, 32), - b(char, class_lower, 32), - b(char, class_alpha, 32), - b(char, class_digit, 32), - b(char, class_xdigit, 32), - b(char, class_space, 32), - b(char, class_print, 32), - b(char, class_graph, 32), - b(char, class_blank, 32), - b(char, class_cntrl, 32), - b(char, class_punct, 32), - b(char, class_alnum, 32) -}; -const char *__ctype32_wctrans[2] attribute_hidden = -{ - b(char, map_toupper, 0), - b(char, map_tolower, 0) -}; -const char *__ctype32_width attribute_hidden = b (char, width, 0); +const unsigned short int *__ctype_old_b = b (unsigned short int, class, 128); +const __uint32_t *__ctype32_old_b = b (__uint32_t, class32, 0); +const __int32_t *__ctype_old_tolower = b (__int32_t, tolower, 128); +const __int32_t *__ctype_old_toupper = b (__int32_t, toupper, 128); +const __uint32_t *__ctype32_old_tolower = b (__uint32_t, tolower, 128); +const __uint32_t *__ctype32_old_toupper = b (__uint32_t, toupper, 128); + +compat_symbol (libc, __ctype_old_b, __ctype_b, GLIBC_2_0); +compat_symbol (libc, __ctype_old_tolower, __ctype_tolower, GLIBC_2_0); +compat_symbol (libc, __ctype_old_toupper, __ctype_toupper, GLIBC_2_0); +compat_symbol (libc, __ctype32_old_b, __ctype32_b, GLIBC_2_0); +compat_symbol (libc, __ctype32_old_tolower, __ctype32_tolower, GLIBC_2_2); +compat_symbol (libc, __ctype32_old_toupper, __ctype32_toupper, GLIBC_2_2); + +#endif diff --git a/ctype/ctype.h b/ctype/ctype.h index 28aec6b..c7290ed 100644 --- a/ctype/ctype.h +++ b/ctype/ctype.h @@ -65,6 +65,11 @@ enum /* These are defined in ctype-info.c. The declarations here must match those in localeinfo.h. + In the thread-specific locale model (see `uselocale' in ) + we cannot use global variables for these as was done in the past. + Instead, the following accessor functions return the address of + each variable, which is local to the current thread if multithreaded. + These point into arrays of 384, so they can be indexed by any `unsigned char' value [0,255]; by EOF (-1); or by any `signed char' value [-128,-1). ISO C requires that the ctype functions work for `unsigned @@ -73,12 +78,15 @@ enum rather than `unsigned char's because tolower (EOF) must be EOF, which doesn't fit into an `unsigned char'. But today more important is that the arrays are also used for multi-byte character sets. */ -extern __const unsigned short int *__ctype_b; /* Characteristics. */ -extern __const __int32_t *__ctype_tolower; /* Case conversions. */ -extern __const __int32_t *__ctype_toupper; /* Case conversions. */ +extern __const unsigned short int **__ctype_b_loc (void) + __attribute__ ((__const)); +extern __const __int32_t **__ctype_tolower_loc (void) + __attribute__ ((__const)); +extern __const __int32_t **__ctype_toupper_loc (void) + __attribute__ ((__const)); #define __isctype(c, type) \ - (__ctype_b[(int) (c)] & (unsigned short int) type) + ((*__ctype_b_loc ())[(int) (c)] & (unsigned short int) type) #define __isascii(c) (((c) & ~0x7f) == 0) /* If C is a 7 bit value. */ #define __toascii(c) ((c) & 0x7f) /* Mask off high bits. */ @@ -182,27 +190,27 @@ __exctype (_tolower); extern __inline int tolower (int __c) __THROW { - return __c >= -128 && __c < 256 ? __ctype_tolower[__c] : __c; + return __c >= -128 && __c < 256 ? (*__ctype_tolower_loc ())[__c] : __c; } extern __inline int toupper (int __c) __THROW { - return __c >= -128 && __c < 256 ? __ctype_toupper[__c] : __c; + return __c >= -128 && __c < 256 ? (*__ctype_toupper_loc ())[__c] : __c; } # endif # if __GNUC__ >= 2 && defined __OPTIMIZE__ && !defined __cplusplus -# define tolower(c) __tobody (c, tolower, __ctype_tolower, (c)) -# define toupper(c) __tobody (c, toupper, __ctype_toupper, (c)) +# define tolower(c) __tobody (c, tolower, *__ctype_tolower_loc (), (c)) +# define toupper(c) __tobody (c, toupper, *__ctype_toupper_loc (), (c)) # endif /* Optimizing gcc */ # if defined __USE_SVID || defined __USE_MISC || defined __USE_XOPEN # define isascii(c) __isascii (c) # define toascii(c) __toascii (c) -# define _tolower(c) ((int) __ctype_tolower[(int) (c)]) -# define _toupper(c) ((int) __ctype_toupper[(int) (c)]) +# define _tolower(c) ((int) (*__ctype_tolower_loc ())[(int) (c)]) +# define _toupper(c) ((int) (*__ctype_toupper_loc ())[(int) (c)]) # endif #endif /* Not __NO_CTYPE. */ diff --git a/hurd/hurd/threadvar.h b/hurd/hurd/threadvar.h index bf36872..5e7441f 100644 --- a/hurd/hurd/threadvar.h +++ b/hurd/hurd/threadvar.h @@ -65,7 +65,10 @@ enum __hurd_threadvar_index _HURD_THREADVAR_MALLOC, /* For use of malloc. */ _HURD_THREADVAR_DL_ERROR, /* For use of -ldl and dynamic linker. */ _HURD_THREADVAR_RPC_VARS, /* For state of RPC functions. */ - _HURD_THREADVAR_LOCALE, /* For thread-locale locale setting. */ + _HURD_THREADVAR_LOCALE, /* For thread-local locale setting. */ + _HURD_THREADVAR_CTYPE_B, /* Cache of thread-local locale data. */ + _HURD_THREADVAR_CTYPE_TOLOWER, /* Cache of thread-local locale data. */ + _HURD_THREADVAR_CTYPE_TOUPPER, /* Cache of thread-local locale data. */ _HURD_THREADVAR_MAX /* Default value for __hurd_threadvar_max. */ }; diff --git a/include/ctype.h b/include/ctype.h index b58306d..ca3c3dd 100644 --- a/include/ctype.h +++ b/include/ctype.h @@ -2,39 +2,58 @@ extern int __isctype (int __c, int __mask); -# include - # ifndef NOT_IN_libc -/* The optimized macros are not defined for users because they can't see - the thread-local locale state. For inside libc, define them using the - _NL_CURRENT accessors. We don't use _NL_CURRENT_LOCALE->__ctype_b here - because we want to cause a link-time ref to _nl_current_LC_CTYPE under +/* These accessors are used by the optimized macros to find the + thread-local cache of ctype information from the current thread's + locale. For inside libc, define them as inlines using the _NL_CURRENT + accessors. We don't use _NL_CURRENT_LOCALE->__ctype_b here because we + want to cause a link-time ref to _nl_current_LC_CTYPE under NL_CURRENT_INDIRECT. */ # include "../locale/localeinfo.h" -# ifndef __NO_CTYPE -# undef __isctype -# define __isctype(c, type) \ - (((uint16_t *) _NL_CURRENT (LC_CTYPE, _NL_CTYPE_CLASS) + 128) \ - [(int) (c)] & (uint16_t) type) - -# undef tolower -# define tolower(c) \ - __tobody (c, tolower, \ - (uint32_t *) _NL_CURRENT (LC_CTYPE, _NL_CTYPE_TOLOWER) + 128, \ - (c)) -# undef _tolower -# define _tolower(c) tolower (c) -# undef toupper -# define toupper(c) \ - __tobody (c, toupper, \ - (uint32_t *) _NL_CURRENT (LC_CTYPE, _NL_CTYPE_TOUPPER) + 128, \ - (c)) -# undef _toupper -# define _toupper(c) toupper (c) - -# endif /* Not __NO_CTYPE. */ -# endif /* _LIBC_REENTRANT. */ +# include + +# ifndef CTYPE_EXTERN_INLINE /* Used by ctype/ctype-info.c, which see. */ +# define CTYPE_EXTERN_INLINE extern inline +# endif + +__libc_tsd_define (extern, CTYPE_B) +__libc_tsd_define (extern, CTYPE_TOUPPER) +__libc_tsd_define (extern, CTYPE_TOLOWER) + +CTYPE_EXTERN_INLINE const uint16_t ** __attribute__ ((const)) +__ctype_b_loc (void) +{ + const uint16_t **tablep = + (const uint16_t **) __libc_tsd_address (CTYPE_B); + if (__builtin_expect (*tablep == NULL, 0)) + *tablep = (const uint16_t *) _NL_CURRENT (LC_CTYPE, _NL_CTYPE_CLASS) + 128; + return tablep; +} + +CTYPE_EXTERN_INLINE const int32_t ** __attribute__ ((const)) +__ctype_toupper_loc (void) +{ + const int32_t **tablep = + (const int32_t **) __libc_tsd_address (CTYPE_TOUPPER); + if (__builtin_expect (*tablep == NULL, 0)) + *tablep = ((int32_t *) _NL_CURRENT (LC_CTYPE, _NL_CTYPE_TOUPPER) + 128); + return tablep; +} + +CTYPE_EXTERN_INLINE const int32_t ** __attribute__ ((const)) +__ctype_tolower_loc (void) +{ + const int32_t **tablep = + (const int32_t **) __libc_tsd_address (CTYPE_TOLOWER); + if (__builtin_expect (*tablep == NULL, 0)) + *tablep = ((int32_t *) _NL_CURRENT (LC_CTYPE, _NL_CTYPE_TOLOWER) + 128); + return tablep; +} + +# endif /* Not NOT_IN_libc. */ + +# include #endif /* ctype.h */ diff --git a/linuxthreads/ChangeLog b/linuxthreads/ChangeLog index 2b6f223..0e698ba 100644 --- a/linuxthreads/ChangeLog +++ b/linuxthreads/ChangeLog @@ -1,3 +1,16 @@ +2002-09-01 Roland McGrath + + * sysdeps/pthread/bits/libc-tsd.h (enum __libc_tsd_key_t): Add new keys + CTYPE_B, CTYPE_TOLOWER, CTYPE_TOUPPER. + + * sysdeps/pthread/bits/libc-tsd.h (__libc_tsd_address): New macro. + (__libc_internal_tsd_address): Declare it. + * Versions (libc, ld, libpthread: GLIBC_PRIVATE): Add + __libc_internal_tsd_address. + * specific.c (libc_internal_tsd_address): New function. + (__libc_internal_tsd_address): New variable. + * no-tsd.c (__libc_internal_tsd_address): New variable. + 2002-08-31 Ulrich Drepper * Makefile: Don't use rule for crt%.o, spell it out as rules for diff --git a/linuxthreads/sysdeps/pthread/bits/libc-tsd.h b/linuxthreads/sysdeps/pthread/bits/libc-tsd.h index 34bac12..e37faf6 100644 --- a/linuxthreads/sysdeps/pthread/bits/libc-tsd.h +++ b/linuxthreads/sysdeps/pthread/bits/libc-tsd.h @@ -25,6 +25,9 @@ enum __libc_tsd_key_t { _LIBC_TSD_KEY_MALLOC = 0, _LIBC_TSD_KEY_DL_ERROR, _LIBC_TSD_KEY_RPC_VARS, _LIBC_TSD_KEY_LOCALE, + _LIBC_TSD_KEY_CTYPE_B, + _LIBC_TSD_KEY_CTYPE_TOLOWER, + _LIBC_TSD_KEY_CTYPE_TOUPPER, _LIBC_TSD_KEY_N }; #include @@ -39,6 +42,13 @@ enum __libc_tsd_key_t { _LIBC_TSD_KEY_MALLOC = 0, extern void *(*__libc_internal_tsd_get) (enum __libc_tsd_key_t) __THROW; extern int (*__libc_internal_tsd_set) (enum __libc_tsd_key_t, __const void *) __THROW; +extern void **(*const __libc_internal_tsd_address) (enum __libc_tsd_key_t) + __THROW __attribute__ ((__const__)); + +#define __libc_tsd_address(KEY) \ + (__libc_internal_tsd_address != NULL \ + ? __libc_internal_tsd_address (_LIBC_TSD_KEY_##KEY) \ + : &__libc_tsd_##KEY##_data) #define __libc_tsd_define(CLASS, KEY) CLASS void *__libc_tsd_##KEY##_data; #define __libc_tsd_get(KEY) \ diff --git a/locale/lc-ctype.c b/locale/lc-ctype.c index 59ff701..3011f4e 100644 --- a/locale/lc-ctype.c +++ b/locale/lc-ctype.c @@ -25,46 +25,48 @@ _NL_CURRENT_DEFINE (LC_CTYPE); /* We are called after loading LC_CTYPE data to load it into - the variables used by the ctype.h macros. - - There are three arrays of short ints which need to be indexable - from -128 to 255 inclusive. Stored in the locale data file are - a copy of each for each byte order. */ + the variables used by the ctype.h macros. */ void _nl_postload_ctype (void) { - const struct locale_data *data = _NL_CURRENT_DATA (LC_CTYPE); - -#define paste(a,b) paste1(a,b) -#define paste1(a,b) a##b - #define current(type,x,offset) \ - ((const type *) _NL_CURRENT (LC_CTYPE, paste(_NL_CTYPE_,x)) + offset) - - extern const uint32_t *__ctype32_b; - extern const uint32_t *__ctype32_toupper; - extern const uint32_t *__ctype32_tolower; - extern const char *__ctype32_wctype[12] attribute_hidden; - extern const char *__ctype32_wctrans[2] attribute_hidden; - extern const char *__ctype32_width attribute_hidden; - - size_t offset, cnt; - - __ctype_b = current (uint16_t, CLASS, 128); - __ctype_toupper = current (uint32_t, TOUPPER, 128); - __ctype_tolower = current (uint32_t, TOLOWER, 128); - __ctype32_b = current (uint32_t, CLASS32, 0); - __ctype32_toupper = current (uint32_t, TOUPPER32, 0); - __ctype32_tolower = current (uint32_t, TOLOWER32, 0); - - offset = _NL_CURRENT_WORD (LC_CTYPE, _NL_CTYPE_CLASS_OFFSET); - for (cnt = 0; cnt < 12; cnt++) - __ctype32_wctype[cnt] = data->values[offset + cnt].string; - - offset = _NL_CURRENT_WORD (LC_CTYPE, _NL_CTYPE_MAP_OFFSET); - for (cnt = 0; cnt < 2; cnt++) - __ctype32_wctrans[cnt] = data->values[offset + cnt].string; - - __ctype32_width = current (char, WIDTH, 0); + ((const type *) _NL_CURRENT (LC_CTYPE, _NL_CTYPE_##x) + offset) + +/* These are defined in ctype-info.c. + The declarations here must match those in localeinfo.h. + + These point into arrays of 384, so they can be indexed by any `unsigned + char' value [0,255]; by EOF (-1); or by any `signed char' value + [-128,-1). ISO C requires that the ctype functions work for `unsigned + char' values and for EOF; we also support negative `signed char' values + for broken old programs. The case conversion arrays are of `int's + rather than `unsigned char's because tolower (EOF) must be EOF, which + doesn't fit into an `unsigned char'. But today more important is that + the arrays are also used for multi-byte character sets. */ + + if (_NL_CURRENT_LOCALE == &_nl_global_locale) + { + __libc_tsd_set (CTYPE_B, (void *) current (uint16_t, CLASS, 128)); + __libc_tsd_set (CTYPE_TOUPPER, (void *) current (int32_t, TOUPPER, 128)); + __libc_tsd_set (CTYPE_TOLOWER, (void *) current (int32_t, TOLOWER, 128)); + } + +#include +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3) + extern __const unsigned short int *__ctype_old_b; /* Characteristics. */ + extern __const __int32_t *__ctype_old_tolower; /* Case conversions. */ + extern __const __int32_t *__ctype_old_toupper; /* Case conversions. */ + + extern const uint32_t *__ctype32_old_b; + extern const uint32_t *__ctype32_old_toupper; + extern const uint32_t *__ctype32_old_tolower; + + __ctype_old_b = current (uint16_t, CLASS, 128); + __ctype_old_toupper = current (uint32_t, TOUPPER, 128); + __ctype_old_tolower = current (uint32_t, TOLOWER, 128); + __ctype32_old_b = current (uint32_t, CLASS32, 0); + __ctype32_old_toupper = current (uint32_t, TOUPPER32, 0); + __ctype32_old_tolower = current (uint32_t, TOLOWER32, 0); +#endif } diff --git a/locale/uselocale.c b/locale/uselocale.c index d19ae50..e2f38c1 100644 --- a/locale/uselocale.c +++ b/locale/uselocale.c @@ -19,6 +19,7 @@ #include #include "localeinfo.h" +#include /* Switch the current thread's locale to DATASET. If DATASET is null, instead just return the current setting. @@ -60,6 +61,11 @@ __uselocale (locale_t newloc) # include "categories.def" # undef DEFINE_CATEGORY #endif + + /* Update the special tsd cache of some locale data. */ + __libc_tsd_set (CTYPE_B, (void *) locobj->__ctype_b); + __libc_tsd_set (CTYPE_TOLOWER, (void *) locobj->__ctype_tolower); + __libc_tsd_set (CTYPE_TOUPPER, (void *) locobj->__ctype_toupper); } return oldloc == &_nl_global_locale ? LC_GLOBAL_LOCALE : oldloc; diff --git a/sysdeps/generic/bits/libc-tsd.h b/sysdeps/generic/bits/libc-tsd.h index 3c77e15..ce25601 100644 --- a/sysdeps/generic/bits/libc-tsd.h +++ b/sysdeps/generic/bits/libc-tsd.h @@ -28,6 +28,8 @@ keys used in only one source file, empty for global definitions, or `extern' for global declarations. + __libc_tsd_address(KEY) -- Return the `void **' pointing to + the current thread's datum for KEY. __libc_tsd_get(KEY) -- Return the `void *' datum for KEY. __libc_tsd_set(KEY, VALUE) -- Set the datum for KEY to VALUE. @@ -52,11 +54,13 @@ #if USE_TLS && HAVE___THREAD # define __libc_tsd_define(CLASS, KEY) CLASS __thread void *__libc_tsd_##KEY; +# define __libc_tsd_address(KEY) (&__libc_tsd_##KEY) # define __libc_tsd_get(KEY) (__libc_tsd_##KEY) # define __libc_tsd_set(KEY, VALUE) (__libc_tsd_##KEY = (VALUE)) #else # define __libc_tsd_define(CLASS, KEY) CLASS void *__libc_tsd_##KEY##_data; +# define __libc_tsd_address(KEY) (&__libc_tsd_##KEY) # define __libc_tsd_get(KEY) (__libc_tsd_##KEY##_data) # define __libc_tsd_set(KEY, VALUE) (__libc_tsd_##KEY##_data = (VALUE)) #endif diff --git a/sysdeps/mach/hurd/bits/libc-tsd.h b/sysdeps/mach/hurd/bits/libc-tsd.h index 1dbdbb1..56393e9 100644 --- a/sysdeps/mach/hurd/bits/libc-tsd.h +++ b/sysdeps/mach/hurd/bits/libc-tsd.h @@ -1,5 +1,5 @@ /* libc-internal interface for thread-specific data. Hurd version. - Copyright (C) 1998 Free Software Foundation, Inc. + Copyright (C) 1998,2002 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -24,14 +24,11 @@ #define __libc_tsd_define(CLASS, KEY) /* nothing, always have threadvars */ -#define __libc_tsd_threadvar_location(KEY) \ +#define __libc_tsd_address(KEY) \ ((void **) __hurd_threadvar_location (_HURD_THREADVAR_##KEY)) -#define __libc_tsd_get(KEY) \ - (*__libc_tsd_threadvar_location (KEY)) - -#define __libc_tsd_set(KEY, VALUE) \ - (*__libc_tsd_threadvar_location (KEY) = (VALUE)) +#define __libc_tsd_get(KEY) (*__libc_tsd_address (KEY)) +#define __libc_tsd_set(KEY, VALUE) (*__libc_tsd_address (KEY) = (VALUE)) #endif /* bits/libc-tsd.h */ -- 2.7.4