diff options
Diffstat (limited to 'libpthread')
-rw-r--r-- | libpthread/linuxthreads/Makefile | 5 | ||||
-rw-r--r-- | libpthread/linuxthreads/internals.h | 6 | ||||
-rw-r--r-- | libpthread/linuxthreads/locale.c | 58 | ||||
-rw-r--r-- | libpthread/linuxthreads/manager.c | 9 | ||||
-rw-r--r-- | libpthread/linuxthreads/pthread.c | 14 |
5 files changed, 92 insertions, 0 deletions
diff --git a/libpthread/linuxthreads/Makefile b/libpthread/linuxthreads/Makefile index 748776e71..880fda291 100644 --- a/libpthread/linuxthreads/Makefile +++ b/libpthread/linuxthreads/Makefile @@ -45,6 +45,11 @@ CSRC=attr.c cancel.c condvar.c errno.c events.c join.c lockfile.c manager.c \ mutex.c oldsemaphore.c pt-machine.c ptfork.c pthread.c \ ptlongjmp.c rwlock.c semaphore.c signals.c specific.c spinlock.c \ wrapsyscall.c #weaks.c + +ifeq ($(UCLIBC_HAS_XLOCALE),y) + CSRC += locale.c +endif + COBJS=$(patsubst %.c,%.o, $(CSRC)) OBJS=$(COBJS) diff --git a/libpthread/linuxthreads/internals.h b/libpthread/linuxthreads/internals.h index 528acddc3..bce6b7efe 100644 --- a/libpthread/linuxthreads/internals.h +++ b/libpthread/linuxthreads/internals.h @@ -28,6 +28,9 @@ #include "pt-machine.h" #include "semaphore.h" #include "../linuxthreads_db/thread_dbP.h" +#ifdef __UCLIBC_HAS_XLOCALE__ +#include <bits/uClibc_locale.h> +#endif /* __UCLIBC_HAS_XLOCALE__ */ /* Use a funky version in a probably vein attempt at preventing gdb * from dlopen()'ing glibc's libthread_db library... */ @@ -172,6 +175,9 @@ struct _pthread_descr_struct { pthread_readlock_info *p_readlock_free; /* Free list of structs */ int p_untracked_readlock_count; /* Readlocks not tracked by list */ /* New elements must be added at the end. */ +#ifdef __UCLIBC_HAS_XLOCALE__ + __locale_t locale; /* thread-specific locale from uselocale() only! */ +#endif /* __UCLIBC_HAS_XLOCALE__ */ } __attribute__ ((aligned(32))); /* We need to align the structure so that doubles are aligned properly. This is 8 bytes on MIPS and 16 bytes on MIPS64. diff --git a/libpthread/linuxthreads/locale.c b/libpthread/linuxthreads/locale.c new file mode 100644 index 000000000..c3ebbc285 --- /dev/null +++ b/libpthread/linuxthreads/locale.c @@ -0,0 +1,58 @@ +/* Copyright (C) 2003 Manuel Novoa III + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#define _GNU_SOURCE +#include <features.h> +#include "pthread.h" +#include "internals.h" +#include <locale.h> +#include <assert.h> +#include <stdlib.h> + +extern struct _pthread_descr_struct __pthread_initial_thread; + +__locale_t __curlocale(void) +{ + pthread_descr self = thread_self(); + +#ifdef NDEBUG + return THREAD_GETMEM (self, locale); +#else + { + __locale_t r = THREAD_GETMEM (self, locale); + + assert(r); + + return r; + } +#endif +} + +__locale_t __curlocale_set(__locale_t newloc) +{ + __locale_t oldloc; + pthread_descr self = thread_self(); + + oldloc = THREAD_GETMEM (self, locale); + + assert(newloc != LC_GLOBAL_LOCALE); + assert(oldloc); + + THREAD_SETMEM (self, locale, newloc); + + return oldloc; +} diff --git a/libpthread/linuxthreads/manager.c b/libpthread/linuxthreads/manager.c index f1c9b93af..f7301bc52 100644 --- a/libpthread/linuxthreads/manager.c +++ b/libpthread/linuxthreads/manager.c @@ -134,6 +134,11 @@ int __pthread_manager(void *arg) __pthread_manager_thread.p_errnop = &__pthread_manager_thread.p_errno; __pthread_manager_thread.p_h_errnop = &__pthread_manager_thread.p_h_errno; +#ifdef __UCLIBC_HAS_XLOCALE__ + /* Initialize thread's locale to the global locale. */ + __pthread_manager_thread.locale = __global_locale; +#endif /* __UCLIBC_HAS_XLOCALE__ */ + /* Block all signals except __pthread_sig_cancel and SIGTRAP */ sigfillset(&manager_mask); sigdelset(&manager_mask, __pthread_sig_cancel); /* for thread termination */ @@ -506,6 +511,10 @@ static int pthread_handle_create(pthread_t *thread, const pthread_attr_t *attr, new_thread->p_canceltype = PTHREAD_CANCEL_DEFERRED; new_thread->p_errnop = &new_thread->p_errno; new_thread->p_h_errnop = &new_thread->p_h_errno; +#ifdef __UCLIBC_HAS_XLOCALE__ + /* Initialize thread's locale to the global locale. */ + new_thread->locale = __global_locale; +#endif /* __UCLIBC_HAS_XLOCALE__ */ new_thread->p_guardaddr = guardaddr; new_thread->p_guardsize = guardsize; new_thread->p_self = new_thread; diff --git a/libpthread/linuxthreads/pthread.c b/libpthread/linuxthreads/pthread.c index 22e3f6a9c..1c24cccd8 100644 --- a/libpthread/linuxthreads/pthread.c +++ b/libpthread/linuxthreads/pthread.c @@ -99,6 +99,10 @@ struct _pthread_descr_struct __pthread_initial_thread = { NULL, /* pthread_readlock_info *p_readlock_list; */ NULL, /* pthread_readlock_info *p_readlock_free; */ 0 /* int p_untracked_readlock_count; */ +#ifdef __UCLIBC_HAS_XLOCALE__ + , + NULL, /* __locale_t locale; */ +#endif /* __UCLIBC_HAS_XLOCALE__ */ }; /* Descriptor of the manager thread; none of this is used but the error @@ -151,6 +155,10 @@ struct _pthread_descr_struct __pthread_manager_thread = { NULL, /* pthread_readlock_info *p_readlock_list; */ NULL, /* pthread_readlock_info *p_readlock_free; */ 0 /* int p_untracked_readlock_count; */ +#ifdef __UCLIBC_HAS_XLOCALE__ + , + NULL, /* __locale_t locale; */ +#endif /* __UCLIBC_HAS_XLOCALE__ */ }; /* Pointer to the main thread (the father of the thread manager thread) */ @@ -318,6 +326,12 @@ static void pthread_initialize(void) /* The errno/h_errno variable of the main thread are the global ones. */ __pthread_initial_thread.p_errnop = &_errno; __pthread_initial_thread.p_h_errnop = &_h_errno; + +#ifdef __UCLIBC_HAS_XLOCALE__ + /* The locale of the main thread is the current locale in use. */ + __pthread_initial_thread.locale = __curlocale_var; +#endif /* __UCLIBC_HAS_XLOCALE__ */ + /* Play with the stack size limit to make sure that no stack ever grows beyond STACK_SIZE minus two pages (one page for the thread descriptor immediately beyond, and one page to act as a guard page). */ |