diff options
author | Bruno Haible <bruno@clisp.org> | 2018-10-22 02:38:39 +0200 |
---|---|---|
committer | Bruno Haible <bruno@clisp.org> | 2018-10-22 02:38:39 +0200 |
commit | de62ab01a4b868acadc33ea6edec95d279664aa7 (patch) | |
tree | c5be9bf0986a4cb81e4a79082be55db38ae8cffe /lib/localename.c | |
parent | ff999a89d151ac2f43df80321e4ea88555bd81ec (diff) | |
download | gnulib-de62ab01a4b868acadc33ea6edec95d279664aa7.tar.gz |
localename: Fine-tune support for per-thread locales on Solaris 11.4.
* lib/localename-table.h: New file, extracted from lib/localename.c.
* lib/localename-table.c: Likewise.
* lib/localename.c: Include localename-table.h.
(get_locale_t_name, newlocale, duplocale, freelocale): Invoke
locale_hash_function instead of pointer_hash.
* modules/localename (Files): Add lib/localename-table.h,
lib/localename-table.c.
(lib_SOURCES): Add localename-table.c.
* m4/intlsolaris.m4 (gt_INTL_SOLARIS): Require AC_CANONICAL_HOST. Test
for Solaris 11.4 locale system only on Solaris. Test for it
independently whether getlocalename_l exists.
* m4/intl.m4 (gt_INTL_SUBDIR_CORE): Don't test for 'uselocale' and
'getlocalename_l'. Instead, invoke gt_INTL_SOLARIS. Set
HAVE_NAMELESS_LOCALES.
* modules/gettext (Files): Add m4/intlsolaris.m4.
Diffstat (limited to 'lib/localename.c')
-rw-r--r-- | lib/localename.c | 53 |
1 files changed, 9 insertions, 44 deletions
diff --git a/lib/localename.c b/lib/localename.c index 93fee9b920..04e6d42b34 100644 --- a/lib/localename.c +++ b/lib/localename.c @@ -52,7 +52,7 @@ extern char * getlocalename_l(int, locale_t); # endif # if HAVE_NAMELESS_LOCALES # include <errno.h> -# include <stdint.h> +# include "localename-table.h" # endif #endif @@ -2707,43 +2707,8 @@ struniq (const char *string) #if HAVE_USELOCALE && HAVE_NAMELESS_LOCALES /* Solaris >= 11.4 */ /* The 'locale_t' object does not contain the names of the locale categories. - We have to associate them with the object through a hash table. */ - -struct locale_categories_names - { - /* Locale category -> name (allocated with indefinite extent). */ - const char *category_name[6]; - }; - -/* A hash function for pointers. */ -static size_t _GL_ATTRIBUTE_CONST -pointer_hash (const void *x) -{ - uintptr_t p = (uintptr_t) x; - size_t h = ((p % 4177) << 12) + ((p % 79) << 6) + (p % 61); - return h; -} - -/* A hash table of fixed size. Multiple threads can access it read-only - simultaneously, but only one thread can insert into it or remove from it - at the same time. */ - -/* A node in a hash bucket collision list. */ -struct locale_hash_node - { - struct locale_hash_node *next; - locale_t locale; - struct locale_categories_names names; - }; - -# define LOCALE_HASH_TABLE_SIZE 101 -static struct locale_hash_node * locale_hash_table[LOCALE_HASH_TABLE_SIZE] - /* = { NULL, ..., NULL } */; - -/* This lock protects the locale_hash_table against multiple simultaneous - accesses (except that multiple simultaneous read accesses are allowed). */ - -gl_rwlock_define_initialized(static, locale_lock) + We have to associate them with the object through a hash table. + The hash table is defined in localename-table.[hc]. */ /* Returns the name of a given locale category in a given locale_t object, allocated as a string with indefinite extent. */ @@ -2763,7 +2728,7 @@ get_locale_t_name (int category, locale_t locale) else { /* Look up the names in the hash table. */ - size_t hashcode = pointer_hash (locale); + size_t hashcode = locale_hash_function (locale); size_t slot = hashcode % LOCALE_HASH_TABLE_SIZE; /* If the locale was not found in the table, return "". This can happen if the application uses the original newlocale()/duplocale() @@ -2898,7 +2863,7 @@ newlocale (int category_mask, const char *name, locale_t base) /* Lock while looking up the hash node. */ gl_rwlock_rdlock (locale_lock); - for (p = locale_hash_table[pointer_hash (base) % LOCALE_HASH_TABLE_SIZE]; + for (p = locale_hash_table[locale_hash_function (base) % LOCALE_HASH_TABLE_SIZE]; p != NULL; p = p->next) if (p->locale == base) @@ -2961,7 +2926,7 @@ newlocale (int category_mask, const char *name, locale_t base) /* Insert it in the hash table. */ { - size_t hashcode = pointer_hash (result); + size_t hashcode = locale_hash_function (result); size_t slot = hashcode % LOCALE_HASH_TABLE_SIZE; struct locale_hash_node *p; @@ -3036,7 +3001,7 @@ duplocale (locale_t locale) /* Lock once, for the lookup and the insertion. */ gl_rwlock_wrlock (locale_lock); - for (p = locale_hash_table[pointer_hash (locale) % LOCALE_HASH_TABLE_SIZE]; + for (p = locale_hash_table[locale_hash_function (locale) % LOCALE_HASH_TABLE_SIZE]; p != NULL; p = p->next) if (p->locale == locale) @@ -3057,7 +3022,7 @@ duplocale (locale_t locale) /* Insert it in the hash table. */ { - size_t hashcode = pointer_hash (result); + size_t hashcode = locale_hash_function (result); size_t slot = hashcode % LOCALE_HASH_TABLE_SIZE; struct locale_hash_node *p; @@ -3094,7 +3059,7 @@ freelocale (locale_t locale) abort (); { - size_t hashcode = pointer_hash (locale); + size_t hashcode = locale_hash_function (locale); size_t slot = hashcode % LOCALE_HASH_TABLE_SIZE; struct locale_hash_node *found; struct locale_hash_node **p; |