diff options
Diffstat (limited to 'libpthread/linuxthreads')
| -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). */  | 
