diff options
Diffstat (limited to 'libpthread/linuxthreads.old')
68 files changed, 1351 insertions, 1132 deletions
diff --git a/libpthread/linuxthreads.old/Makefile.in b/libpthread/linuxthreads.old/Makefile.in index fe29f2cd1..6be2099d2 100644 --- a/libpthread/linuxthreads.old/Makefile.in +++ b/libpthread/linuxthreads.old/Makefile.in @@ -1,21 +1,22 @@ # Makefile for uClibc # # Copyright (C) 2003 Paul Mundt <lethal@linux-sh.org> -# Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org> +# Copyright (C) 2000-2008 Erik Andersen <andersen@uclibc.org> # # Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. # -CFLAGS-dir_linuxthreads.old := -DNOT_IN_libc -DIS_IN_libpthread -CFLAGS-linuxthreads.old := $(CFLAGS-dir_linuxthreads.old) $(SSP_ALL_CFLAGS) +subdirs += libpthread/linuxthreads.old -CFLAGS-libpthread/linuxthreads.old/sysdeps/$(TARGET_ARCH)/ := $(CFLAGS-linuxthreads.old) +CFLAGS-dir_linuxthreads.old := -DNOT_IN_libc -DIS_IN_libpthread +CFLAGS-libpthread/linuxthreads.old := $(CFLAGS-dir_linuxthreads.old) $(SSP_ALL_CFLAGS) ifeq ($(PTHREADS_DEBUG_SUPPORT),y) LDFLAGS-libpthread.so := $(LDFLAGS_NOSTRIP) -Wl,-z,defs else LDFLAGS-libpthread.so := $(LDFLAGS) endif +LDFLAGS-$(UCLIBC_FORMAT_DSBT_ELF)-libpthread.so := -Wl,--dsbt-index=10 LIBS-libpthread.so := $(LIBS) $(ldso) @@ -31,15 +32,12 @@ libpthread_OUT := $(top_builddir)libpthread/linuxthreads.old libpthread_SRC := \ 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 ptlongjmp.c \ + mutex.c pt-machine.c ptfork.c pthread.c ptlongjmp.c \ rwlock.c semaphore.c signals.c specific.c spinlock.c wrapsyscall.c ifeq ($(UCLIBC_HAS_XLOCALE),y) libpthread_SRC += locale.c endif -libpthread_SPEC_SRC := pthread.c -libpthread_SPEC_SRC := $(patsubst %.c,$(libpthread_DIR)/%.c,$(libpthread_SPEC_SRC)) - # remove generic sources, if arch specific version is present ifneq ($(strip $(libpthread_ARCH_SRC)),) libpthread_SRC := $(filter-out $(patsubst %.c,$(libpthread_DIR)/%.c,$(notdir $(libpthread_ARCH_SRC))),$(libpthread_SRC)) @@ -59,28 +57,22 @@ libpthread_libc_OBJ := $(patsubst %.c, $(libpthread_OUT)/%.o,$(libpthread_libc_ libc-static-y += $(libpthread_OUT)/libc_pthread_init.o libc-shared-y += $(libpthread_libc_OBJ:.o=.oS) -libpthread-static-y += $(patsubst $(libpthread_DIR)/%.c,$(libpthread_OUT)/%.o,$(libpthread_SPEC_SRC)) -libpthread-shared-y += $(patsubst $(libpthread_DIR)/%.c,$(libpthread_OUT)/%.oS,$(libpthread_SPEC_SRC)) - ifeq ($(DOPIC),y) -libpthread-a-y += $(libpthread_OBJ:.o=.os) $(libpthread-static-y:.o=.os) +libpthread-a-y += $(libpthread_OBJ:.o=.os) else -libpthread-a-y += $(libpthread_OBJ) $(libpthread-static-y) +libpthread-a-y += $(libpthread_OBJ) endif -libpthread-so-y += $(libpthread_OBJ:.o=.os) $(libpthread-shared-y) +libpthread-so-y += $(libpthread_OBJ:.o=.oS) lib-a-$(UCLIBC_HAS_THREADS) += $(top_builddir)lib/libpthread.a lib-so-$(UCLIBC_HAS_THREADS) += $(top_builddir)lib/libpthread.so -objclean-y += libpthread_clean -headers-$(UCLIBC_HAS_THREADS) += linuxthreads_headers -headers_clean-y += linuxthreads_headers_clean #ifeq ($(DOMULTI),n) $(top_builddir)lib/libpthread.so: $(libpthread_OUT)/libpthread_so.a $(libc.depend) - $(call link.so,$(libpthread_FULL_NAME),$(MAJOR_VERSION)) + $(call link.so,$(libpthread_FULL_NAME),$(ABI_VERSION)) #else #$(top_builddir)lib/libpthread.so: $(libpthread_OUT)/libpthread.oS | $(libc.depend) -# $(call linkm.so,$(libpthread_FULL_NAME),$(MAJOR_VERSION)) +# $(call linkm.so,$(libpthread_FULL_NAME),$(ABI_VERSION)) #endif ifeq ($(PTHREADS_DEBUG_SUPPORT),y) @@ -93,7 +85,7 @@ $(libpthread_OUT)/libpthread_so.a: $(libpthread-so-y) ifeq ($(PTHREADS_DEBUG_SUPPORT),y) $(libpthread_OUT)/libpthread.oS: STRIP_FLAGS:=$(STRIP_FLAGS:-x=-X --strip-debug) endif -$(libpthread_OUT)/libpthread.oS: $(libpthread_SRC) $(libpthread_SPEC_SRC) +$(libpthread_OUT)/libpthread.oS: $(libpthread_SRC) $(Q)$(RM) $@ $(compile-m) @@ -105,19 +97,23 @@ $(top_builddir)lib/libpthread.a: $(libpthread-a-y) $(Q)$(RM) $@ $(do_ar) -include/pthread.h: - $(do_ln) ../$(PTDIR)/sysdeps/pthread/$(@F) $(top_builddir)$@ -include/semaphore.h: - $(do_ln) ../$(PTDIR)/$(@F) $(top_builddir)$@ -include/bits/pthreadtypes.h: | include/bits - $(do_ln) ../../$(PTDIR)/sysdeps/pthread/bits/$(@F) $(top_builddir)$@ -linuxthreads_headers: include/pthread.h include/semaphore.h \ - include/bits/pthreadtypes.h - -linuxthreads_headers_clean: - $(RM) $(top_builddir)include/pthread.h \ - $(top_builddir)include/semaphore.h \ - $(top_builddir)include/bits/pthreadtypes.h - -libpthread_clean: - $(RM) $(libpthread_OUT)/*.{o,os,oS,a} +$(top_builddir)include/pthread.h: + $(do_ln) $(call rel_srcdir)$(PTDIR)/sysdeps/pthread/$(@F) $@ +$(top_builddir)include/semaphore.h: + $(do_ln) $(call rel_srcdir)$(PTDIR)/$(@F) $@ +$(top_builddir)include/bits/pthreadtypes.h: | $(top_builddir)include/bits + $(do_ln) $(call rel_srcdir)$(PTDIR)/sysdeps/pthread/bits/$(@F) $@ + +linuxthreads_headers := $(top_builddir)include/pthread.h \ + $(top_builddir)include/semaphore.h \ + $(top_builddir)include/bits/pthreadtypes.h +$(linuxthreads_headers): $(wildcard $(addprefix $(top_builddir)include/config/linuxthreads/,old.h new.h)) +headers-$(UCLIBC_HAS_THREADS) += $(linuxthreads_headers) + +objclean-y += CLEAN_libpthread/linuxthreads.old +headers_clean-y += HEADERCLEAN_libpthread/linuxthreads.old +HEADERCLEAN_libpthread/linuxthreads.old: + $(do_rm) $(linuxthreads_headers) + +CLEAN_libpthread/linuxthreads.old: + $(do_rm) $(addprefix $(libpthread_OUT)/*., o os oS a) diff --git a/libpthread/linuxthreads.old/attr.c b/libpthread/linuxthreads.old/attr.c index 30294afe4..8465c234c 100644 --- a/libpthread/linuxthreads.old/attr.c +++ b/libpthread/linuxthreads.old/attr.c @@ -42,7 +42,7 @@ libpthread_hidden_proto(pthread_attr_setscope) * Therefore, define the function pthread_attr_init() here using * a strong symbol. */ -//int __pthread_attr_init_2_1(pthread_attr_t *attr) +/*int __pthread_attr_init_2_1(pthread_attr_t *attr)*/ int pthread_attr_init(pthread_attr_t *attr) { size_t ps = getpagesize (); @@ -61,7 +61,7 @@ int pthread_attr_init(pthread_attr_t *attr) libpthread_hidden_def(pthread_attr_init) /* uClibc: leave out this for now. */ -#if DO_PTHREAD_VERSIONING_WITH_UCLIBC +#if defined DO_PTHREAD_VERSIONING_WITH_UCLIBC #if defined __PIC__ && defined DO_VERSIONING default_symbol_version (__pthread_attr_init_2_1, pthread_attr_init, GLIBC_2.1); @@ -201,6 +201,7 @@ int __pthread_attr_getguardsize(const pthread_attr_t *attr, size_t *guardsize) } weak_alias (__pthread_attr_getguardsize, pthread_attr_getguardsize) +#if 0 /* uClibc: deprecated stuff disabled */ int __pthread_attr_setstackaddr(pthread_attr_t *attr, void *stackaddr) { attr->__stackaddr = stackaddr; @@ -218,6 +219,7 @@ int __pthread_attr_getstackaddr(const pthread_attr_t *attr, void **stackaddr) return 0; } weak_alias (__pthread_attr_getstackaddr, pthread_attr_getstackaddr) +#endif int __pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize) { diff --git a/libpthread/linuxthreads.old/cancel.c b/libpthread/linuxthreads.old/cancel.c index 239b821f1..392d1d586 100644 --- a/libpthread/linuxthreads.old/cancel.c +++ b/libpthread/linuxthreads.old/cancel.c @@ -14,8 +14,6 @@ /* Thread cancellation */ -#define __FORCE_GLIBC -#include <features.h> #include <errno.h> #include "pthread.h" #include "internals.h" @@ -31,7 +29,7 @@ extern void __rpc_thread_destroy(void); #ifdef _STACK_GROWS_DOWN # define FRAME_LEFT(frame, other) ((char *) frame >= (char *) other) -#elif _STACK_GROWS_UP +#elif defined _STACK_GROWS_UP # define FRAME_LEFT(frame, other) ((char *) frame <= (char *) other) #else # error "Define either _STACK_GROWS_DOWN or _STACK_GROWS_UP" @@ -193,10 +191,10 @@ void __pthread_perform_cleanup(char *currentframe) for (c = THREAD_GETMEM(self, p_cleanup); c != NULL; c = c->__prev) { -#if _STACK_GROWS_DOWN +#ifdef _STACK_GROWS_DOWN if ((char *) c <= currentframe) break; -#elif _STACK_GROWS_UP +#elif defined _STACK_GROWS_UP if ((char *) c >= currentframe) break; #else @@ -213,9 +211,9 @@ void __pthread_perform_cleanup(char *currentframe) } #ifndef __PIC__ -/* We need a hook to force the cancelation wrappers to be linked in when +/* We need a hook to force the cancellation wrappers to be linked in when static libpthread is used. */ -extern const int __pthread_provide_wrappers; -static const int * const __pthread_require_wrappers = +extern const char __pthread_provide_wrappers; +static const char *const __pthread_require_wrappers = &__pthread_provide_wrappers; #endif diff --git a/libpthread/linuxthreads.old/condvar.c b/libpthread/linuxthreads.old/condvar.c index 23e71393c..35daacf15 100644 --- a/libpthread/linuxthreads.old/condvar.c +++ b/libpthread/linuxthreads.old/condvar.c @@ -25,16 +25,6 @@ #include "queue.h" #include "restart.h" -libpthread_hidden_proto(pthread_cond_broadcast) -libpthread_hidden_proto(pthread_cond_destroy) -libpthread_hidden_proto(pthread_cond_init) -libpthread_hidden_proto(pthread_cond_signal) -libpthread_hidden_proto(pthread_cond_wait) -libpthread_hidden_proto(pthread_cond_timedwait) - -libpthread_hidden_proto(pthread_condattr_destroy) -libpthread_hidden_proto(pthread_condattr_init) - int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *cond_attr attribute_unused) { diff --git a/libpthread/linuxthreads.old/errno.c b/libpthread/linuxthreads.old/errno.c index f5778f98a..748c1d512 100644 --- a/libpthread/linuxthreads.old/errno.c +++ b/libpthread/linuxthreads.old/errno.c @@ -14,8 +14,6 @@ /* Define the location of errno for the remainder of the C library */ -#define __FORCE_GLIBC -#include <features.h> #include <errno.h> #include <netdb.h> #include "pthread.h" diff --git a/libpthread/linuxthreads.old/events.c b/libpthread/linuxthreads.old/events.c index a4bf1f898..2a76f91d4 100644 --- a/libpthread/linuxthreads.old/events.c +++ b/libpthread/linuxthreads.old/events.c @@ -14,8 +14,7 @@ You should have received a copy of the GNU Library General Public License along with the GNU C Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ + see <http://www.gnu.org/licenses/>. */ /* The functions contained here do nothing, they just return. */ diff --git a/libpthread/linuxthreads.old/forward.c b/libpthread/linuxthreads.old/forward.c index eeaefd7a3..5a1771b90 100644 --- a/libpthread/linuxthreads.old/forward.c +++ b/libpthread/linuxthreads.old/forward.c @@ -13,30 +13,31 @@ Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ #include <features.h> #include <stdlib.h> #include <dlfcn.h> /* psm: keep this before internals.h */ -libc_hidden_proto(exit) -/* vda: here's why: +#if 0 +vda: here is why: +headers contain libc_hidden_proto(foo). In libpthread/linuxthreads.old/sysdeps/pthread/bits/libc-lock.h adding libc_hidden_proto(foo) just before weak_extern (__pthread_initialize) will not warn: - //libc_hidden_proto(foo) + /* libc_hidden_proto(foo) */ weak_extern (__pthread_initialize) - //libc_hidden_proto(foo) + /* libc_hidden_proto(foo) */ but adding after will! Which is extremely strange - weak_extern expands into just "#pragma weak __pthread_initialize". TODO: determine whether it is a gcc bug or what -(see gcc.gnu.org/bugzilla/show_bug.cgi?id=36282). +(see gcc.gnu.org/PR36282). For now, just include all headers before internals.h (they are again included in internals.h - maybe remove them there later) -*/ +#endif + #include <string.h> #include <limits.h> #include <setjmp.h> @@ -44,6 +45,7 @@ For now, just include all headers before internals.h #include <unistd.h> #include <sys/types.h> #include <sys/wait.h> +#include <sys/time.h> #include "internals.h" @@ -160,8 +162,12 @@ FORWARD (pthread_setcancelstate, (int state, int *oldstate), (state, oldstate), FORWARD (pthread_setcanceltype, (int type, int *oldtype), (type, oldtype), 0) +#if 0 FORWARD2 (_pthread_cleanup_push, void, (struct _pthread_cleanup_buffer * buffer, void (*routine)(void *), void * arg), (buffer, routine, arg), return) +#endif FORWARD2 (_pthread_cleanup_push_defer, void, (struct _pthread_cleanup_buffer * buffer, void (*routine)(void *), void * arg), (buffer, routine, arg), return) +#if 0 FORWARD2 (_pthread_cleanup_pop, void, (struct _pthread_cleanup_buffer * buffer, int execute), (buffer, execute), return) +#endif FORWARD2 (_pthread_cleanup_pop_restore, void, (struct _pthread_cleanup_buffer * buffer, int execute), (buffer, execute), return) diff --git a/libpthread/linuxthreads.old/internals.h b/libpthread/linuxthreads.old/internals.h index 38290a5fe..ea274d824 100644 --- a/libpthread/linuxthreads.old/internals.h +++ b/libpthread/linuxthreads.old/internals.h @@ -36,9 +36,7 @@ /* Use a funky version in a probably vein attempt at preventing gdb * from dlopen()'ing glibc's libthread_db library... */ -#define STRINGIFY(s) STRINGIFY2 (s) -#define STRINGIFY2(s) #s -#define VERSION STRINGIFY(__UCLIBC_MAJOR__) "." STRINGIFY(__UCLIBC_MINOR__) "." STRINGIFY(__UCLIBC_SUBLEVEL__) +#define VERSION __stringify(__UCLIBC_MAJOR__) "." __stringify(__UCLIBC_MINOR__) "." __stringify(__UCLIBC_SUBLEVEL__) #ifndef THREAD_GETMEM # define THREAD_GETMEM(descr, member) descr->member @@ -254,17 +252,25 @@ extern pthread_descr __pthread_main_thread; Initially 0, meaning that the current thread is (by definition) the initial thread. */ -/* For non-MMU systems also remember to stack top of the initial thread. - * This is adapted when other stacks are malloc'ed since we don't know - * the bounds a-priori. -StS */ - extern char *__pthread_initial_thread_bos; #ifndef __ARCH_USE_MMU__ -extern char *__pthread_initial_thread_tos; +/* For non-MMU systems, we have no idea the bounds of the initial thread + * stack, so we have to track it on the fly relative to other stacks. Do + * so by scaling back our assumptions on the limits of the bos/tos relative + * to the known mid point. See also the comments in pthread_initialize(). */ +extern char *__pthread_initial_thread_tos, *__pthread_initial_thread_mid; #define NOMMU_INITIAL_THREAD_BOUNDS(tos,bos) \ - if ((tos)>=__pthread_initial_thread_bos \ - && (bos)<__pthread_initial_thread_tos) \ - __pthread_initial_thread_bos = (tos)+1 + do { \ + char *__tos = (tos); \ + char *__bos = (bos); \ + if (__tos >= __pthread_initial_thread_bos && \ + __bos < __pthread_initial_thread_tos) { \ + if (__bos < __pthread_initial_thread_mid) \ + __pthread_initial_thread_bos = __tos; \ + else \ + __pthread_initial_thread_tos = __bos; \ + } \ + } while (0) #else #define NOMMU_INITIAL_THREAD_BOUNDS(tos,bos) /* empty */ #endif /* __ARCH_USE_MMU__ */ @@ -321,32 +327,28 @@ static __inline__ int invalid_handle(pthread_handle h, pthread_t id) /* The page size we can get from the system. This should likely not be changed by the machine file but, you never know. */ -extern size_t __pagesize; -#include <bits/uClibc_page.h> -#ifndef PAGE_SIZE -#define PAGE_SIZE (sysconf (_SC_PAGESIZE)) -#endif +#define __PAGE_SIZE (sysconf (_SC_PAGESIZE)) /* The max size of the thread stack segments. If the default THREAD_SELF implementation is used, this must be a power of two and - a multiple of PAGE_SIZE. */ + a multiple of __PAGE_SIZE. */ #ifndef STACK_SIZE #ifdef __ARCH_USE_MMU__ #define STACK_SIZE (2 * 1024 * 1024) #else -#define STACK_SIZE (4 * __pagesize) +#define STACK_SIZE (4 * __PAGE_SIZE) #endif #endif -/* The initial size of the thread stack. Must be a multiple of PAGE_SIZE. */ +/* The initial size of the thread stack. Must be a multiple of __PAGE_SIZE. */ #ifndef INITIAL_STACK_SIZE -#define INITIAL_STACK_SIZE (4 * __pagesize) +#define INITIAL_STACK_SIZE (4 * __PAGE_SIZE) #endif /* Size of the thread manager stack. The "- 32" avoids wasting space with some malloc() implementations. */ #ifndef THREAD_MANAGER_STACK_SIZE -#define THREAD_MANAGER_STACK_SIZE (2 * __pagesize - 32) +#define THREAD_MANAGER_STACK_SIZE (2 * __PAGE_SIZE - 32) #endif /* The base of the "array" of thread stacks. The array will grow down from @@ -379,7 +381,7 @@ extern size_t __pagesize; /* Recover thread descriptor for the current thread */ -extern pthread_descr __pthread_find_self (void) __attribute__ ((const)); +extern pthread_descr __pthread_find_self (void) __attribute__ ((const)) attribute_hidden; static __inline__ pthread_descr thread_self (void) __attribute__ ((const)); static __inline__ pthread_descr thread_self (void) @@ -449,17 +451,18 @@ extern int __librt_multiple_threads; /* Internal global functions */ void __pthread_do_exit (void *retval, char *currentframe) - __attribute__ ((__noreturn__)); -void __pthread_destroy_specifics(void); -void __pthread_perform_cleanup(char *currentframe); -int __pthread_initialize_manager(void); -void __pthread_message(char * fmt, ...); -int __pthread_manager(void *reqfd); -int __pthread_manager_event(void *reqfd); -void __pthread_manager_sighandler(int sig); -void __pthread_reset_main_thread(void); -void __fresetlockfiles(void); -void __pthread_manager_adjust_prio(int thread_prio); + __attribute__ ((__noreturn__)) attribute_hidden; +void __pthread_destroy_specifics(void) attribute_hidden; +void __pthread_perform_cleanup(char *currentframe) attribute_hidden; +int __pthread_initialize_manager(void) attribute_hidden; +void __pthread_message(char * fmt, ...) + __attribute__ ((__format__ (printf, 1, 2))) attribute_hidden; +int __pthread_manager(void *reqfd) attribute_hidden; +int __pthread_manager_event(void *reqfd) attribute_hidden; +void __pthread_manager_sighandler(int sig) attribute_hidden; +void __pthread_reset_main_thread(void) attribute_hidden; +void __fresetlockfiles(void) attribute_hidden; +void __pthread_manager_adjust_prio(int thread_prio) attribute_hidden; void __pthread_initialize_minimal (void); extern void __pthread_exit (void *retval) @@ -468,53 +471,47 @@ extern void __pthread_exit (void *retval) #endif ; -extern int __pthread_attr_setguardsize __P ((pthread_attr_t *__attr, - size_t __guardsize)); -extern int __pthread_attr_getguardsize __P ((__const pthread_attr_t *__attr, - size_t *__guardsize)); -extern int __pthread_attr_setstackaddr __P ((pthread_attr_t *__attr, - void *__stackaddr)); -extern int __pthread_attr_getstackaddr __P ((__const pthread_attr_t *__attr, - void **__stackaddr)); -extern int __pthread_attr_setstacksize __P ((pthread_attr_t *__attr, - size_t __stacksize)); -extern int __pthread_attr_getstacksize __P ((__const pthread_attr_t *__attr, - size_t *__stacksize)); -extern int __pthread_getconcurrency __P ((void)); -extern int __pthread_setconcurrency __P ((int __level)); -extern void __pthread_kill_other_threads_np __P ((void)); - -extern void __pthread_restart_old(pthread_descr th); -extern void __pthread_suspend_old(pthread_descr self); -extern int __pthread_timedsuspend_old(pthread_descr self, const struct timespec *abstime); - -extern void __pthread_restart_new(pthread_descr th); -extern void __pthread_suspend_new(pthread_descr self); -extern int __pthread_timedsuspend_new(pthread_descr self, const struct timespec *abstime); - -extern void __pthread_wait_for_restart_signal(pthread_descr self); +extern int __pthread_attr_setguardsize(pthread_attr_t *__attr, + size_t __guardsize) attribute_hidden; +extern int __pthread_attr_getguardsize(const pthread_attr_t *__attr, + size_t *__guardsize) attribute_hidden; +extern int __pthread_attr_setstackaddr(pthread_attr_t *__attr, + void *__stackaddr) attribute_hidden; +extern int __pthread_attr_getstackaddr(const pthread_attr_t *__attr, + void **__stackaddr) attribute_hidden; +extern int __pthread_attr_setstacksize(pthread_attr_t *__attr, + size_t __stacksize) attribute_hidden; +extern int __pthread_attr_getstacksize(const pthread_attr_t *__attr, + size_t *__stacksize) attribute_hidden; +extern int __pthread_getconcurrency(void) attribute_hidden; +extern int __pthread_setconcurrency(int __level) attribute_hidden; +extern void __pthread_kill_other_threads_np(void) attribute_hidden; + +extern void __pthread_restart_old(pthread_descr th) attribute_hidden; +extern void __pthread_suspend_old(pthread_descr self) attribute_hidden; +extern int __pthread_timedsuspend_old(pthread_descr self, const struct timespec *abstime) attribute_hidden; + +extern void __pthread_restart_new(pthread_descr th) attribute_hidden; +extern void __pthread_suspend_new(pthread_descr self) attribute_hidden; +extern int __pthread_timedsuspend_new(pthread_descr self, const struct timespec *abstime) attribute_hidden; + +extern void __pthread_wait_for_restart_signal(pthread_descr self) attribute_hidden; /* Global pointers to old or new suspend functions */ -extern void (*__pthread_restart)(pthread_descr); -extern void (*__pthread_suspend)(pthread_descr); - -/* Prototypes for the function without cancelation support when the - normal version has it. */ -extern __typeof(close) __libc_close; -extern __typeof(nanosleep) __libc_nanosleep; -extern __typeof(read) __libc_read; -extern __typeof(waitpid) __libc_waitpid; -extern __typeof(write) __libc_write; +extern void (*__pthread_restart)(pthread_descr) attribute_hidden; +extern void (*__pthread_suspend)(pthread_descr) attribute_hidden; +#if defined NOT_IN_libc && defined IS_IN_libpthread extern __typeof(pthread_mutex_init) __pthread_mutex_init attribute_hidden; extern __typeof(pthread_mutex_destroy) __pthread_mutex_destroy attribute_hidden; extern __typeof(pthread_mutex_lock) __pthread_mutex_lock attribute_hidden; extern __typeof(pthread_mutex_trylock) __pthread_mutex_trylock attribute_hidden; -extern __typeof(pthread_mutex_unlock) __pthread_mutex_attribute_hidden; +extern __typeof(pthread_mutex_unlock) __pthread_mutex_unlock attribute_hidden; +#endif /* Prototypes for some of the new semaphore functions. */ -extern int __new_sem_post (sem_t * sem); +/*extern int __new_sem_post (sem_t * sem);*/ /* TSD. */ extern int __pthread_internal_tsd_set (int key, const void * pointer); @@ -523,12 +520,10 @@ extern void ** __attribute__ ((__const__)) __pthread_internal_tsd_address (int key); /* The functions called the signal events. */ -extern void __linuxthreads_create_event (void); -extern void __linuxthreads_death_event (void); -extern void __linuxthreads_reap_event (void); +extern void __linuxthreads_create_event (void) attribute_hidden; +extern void __linuxthreads_death_event (void) attribute_hidden; +extern void __linuxthreads_reap_event (void) attribute_hidden; #include <pthread-functions.h> -extern int * __libc_pthread_init (const struct pthread_functions *functions); - #endif /* internals.h */ diff --git a/libpthread/linuxthreads.old/join.c b/libpthread/linuxthreads.old/join.c index a46d0b68d..c7e547951 100644 --- a/libpthread/linuxthreads.old/join.c +++ b/libpthread/linuxthreads.old/join.c @@ -25,7 +25,7 @@ #include "restart.h" #include "debug.h" /* PDEBUG, added by StS */ -libpthread_hidden_proto (pthread_exit) +libpthread_hidden_proto(pthread_exit) void pthread_exit(void * retval) { __pthread_do_exit (retval, CURRENT_STACK_FRAME); @@ -77,7 +77,7 @@ void __pthread_do_exit(void *retval, char *currentframe) THREAD_SETMEM(self, p_terminated, 1); /* See if someone is joining on us */ joining = THREAD_GETMEM(self, p_joining); - PDEBUG("joining = %p, pid=%d\n", joining, joining->p_pid); + PDEBUG("joining = %p, pid=%d\n", joining, joining ? joining->p_pid : 0); __pthread_unlock(THREAD_GETMEM(self, p_lock)); /* Restart joining thread if any */ if (joining != NULL) restart(joining); @@ -87,7 +87,7 @@ void __pthread_do_exit(void *retval, char *currentframe) if (self == __pthread_main_thread && __pthread_manager_request >= 0) { request.req_thread = self; request.req_kind = REQ_MAIN_THREAD_EXIT; - TEMP_FAILURE_RETRY(__libc_write(__pthread_manager_request, + TEMP_FAILURE_RETRY(write(__pthread_manager_request, (char *)&request, sizeof(request))); suspend(self); /* Main thread flushes stdio streams and runs atexit functions. @@ -186,10 +186,148 @@ int pthread_join(pthread_t thread_id, void ** thread_return) request.req_thread = self; request.req_kind = REQ_FREE; request.req_args.free.thread_id = thread_id; + TEMP_FAILURE_RETRY(write(__pthread_manager_request, + (char *) &request, sizeof(request))); + } + return 0; +} + +int pthread_tryjoin_np(pthread_t thread_id, void ** thread_return) +{ + volatile pthread_descr self = thread_self(); + struct pthread_request request; + pthread_handle handle = thread_handle(thread_id); + pthread_descr th; + int result = 0; + + /* Make sure the descriptor is valid. */ + __pthread_lock(&handle->h_lock, self); + if (invalid_handle(handle, thread_id)) { + result = ESRCH; + goto err; + } + th = handle->h_descr; + /* Is the thread joinable?. */ + if (th->p_detached || th->p_joining != NULL) { + result = EINVAL; + goto err; + } + if (th == self) { + result = EDEADLK; + goto err; + } + /* Return right away if the thread hasn't terminated yet. */ + if (! th->p_terminated) { + result = EBUSY; + goto err; + } + + /* Get return value */ + if (thread_return != NULL) *thread_return = th->p_retval; + __pthread_unlock(&handle->h_lock); + /* Send notification to thread manager */ + if (__pthread_manager_request >= 0) { + request.req_thread = self; + request.req_kind = REQ_FREE; + request.req_args.free.thread_id = thread_id; TEMP_FAILURE_RETRY(__libc_write(__pthread_manager_request, (char *) &request, sizeof(request))); } return 0; + +err: + __pthread_unlock(&handle->h_lock); + return result; +} + +int pthread_timedjoin_np(pthread_t thread_id, void ** thread_return, + const struct timespec *abstime) +{ + volatile pthread_descr self = thread_self(); + struct pthread_request request; + pthread_handle handle = thread_handle(thread_id); + pthread_descr th; + pthread_extricate_if extr; + int already_canceled = 0; + int result = 0; + PDEBUG("\n"); + + /* Set up extrication interface */ + extr.pu_object = handle; + extr.pu_extricate_func = join_extricate_func; + + __pthread_lock(&handle->h_lock, self); + if (invalid_handle(handle, thread_id)) { + result = ESRCH; + goto err; + } + th = handle->h_descr; + if (th == self) { + result = EDEADLK; + goto err; + } + /* If detached or already joined, error */ + if (th->p_detached || th->p_joining != NULL) { + result = EINVAL; + goto err; + } + /* If not terminated yet, suspend ourselves. */ + if (! th->p_terminated) { + /* Register extrication interface */ + __pthread_set_own_extricate_if(self, &extr); + if (!(THREAD_GETMEM(self, p_canceled) + && THREAD_GETMEM(self, p_cancelstate) == PTHREAD_CANCEL_ENABLE)) + th->p_joining = self; + else + already_canceled = 1; + __pthread_unlock(&handle->h_lock); + + if (already_canceled) { + __pthread_set_own_extricate_if(self, 0); + __pthread_do_exit(PTHREAD_CANCELED, CURRENT_STACK_FRAME); + } + + PDEBUG("before suspend\n"); + result = (timedsuspend(self, abstime) == 0) ? ETIMEDOUT : 0; + PDEBUG("after suspend\n"); + /* Deregister extrication interface */ + __pthread_set_own_extricate_if(self, 0); + + /* This is a cancellation point */ + if (result == 0 + && THREAD_GETMEM(self, p_woken_by_cancel) + && THREAD_GETMEM(self, p_cancelstate) == PTHREAD_CANCEL_ENABLE) { + THREAD_SETMEM(self, p_woken_by_cancel, 0); + __pthread_do_exit(PTHREAD_CANCELED, CURRENT_STACK_FRAME); + } + __pthread_lock(&handle->h_lock, self); + } + + /* We might have timed out. */ + if (result == 0) { + /* Get return value */ + if (thread_return != NULL) *thread_return = th->p_retval; + } + else + th->p_joining = NULL; + + __pthread_unlock(&handle->h_lock); + + if (result == 0) { + /* Send notification to thread manager */ + if (__pthread_manager_request >= 0) { + request.req_thread = self; + request.req_kind = REQ_FREE; + request.req_args.free.thread_id = thread_id; + TEMP_FAILURE_RETRY(__libc_write(__pthread_manager_request, + (char *) &request, sizeof(request))); + } + } + return result; + +err: + __pthread_unlock(&handle->h_lock); + return result; } int pthread_detach(pthread_t thread_id) @@ -224,7 +362,7 @@ int pthread_detach(pthread_t thread_id) request.req_thread = thread_self(); request.req_kind = REQ_FREE; request.req_args.free.thread_id = thread_id; - TEMP_FAILURE_RETRY(__libc_write(__pthread_manager_request, + TEMP_FAILURE_RETRY(write(__pthread_manager_request, (char *) &request, sizeof(request))); } return 0; diff --git a/libpthread/linuxthreads.old/libc_pthread_init.c b/libpthread/linuxthreads.old/libc_pthread_init.c index 09606effb..dfdcbcccc 100644 --- a/libpthread/linuxthreads.old/libc_pthread_init.c +++ b/libpthread/linuxthreads.old/libc_pthread_init.c @@ -13,22 +13,13 @@ Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ -#include <features.h> #include <locale.h> -#include <stdlib.h> #include <string.h> -#include "internals.h" -#include "sysdeps/pthread/pthread-functions.h" +#include <linuxthreads.old/sysdeps/pthread/pthread-functions.h> -/* Experimentally off - libc_hidden_proto(memcpy) */ - -#if !(USE_TLS && HAVE___THREAD) && defined __UCLIBC_HAS_XLOCALE__ -libc_hidden_proto(uselocale) -#endif int __libc_multiple_threads attribute_hidden __attribute__((nocommon)); @@ -42,7 +33,7 @@ int * __libc_pthread_init (const struct pthread_functions *functions) sizeof (__libc_pthread_functions)); #endif -#if !(USE_TLS && HAVE___THREAD) && defined __UCLIBC_HAS_XLOCALE__ +#if !defined __UCLIBC_HAS_TLS__ && defined __UCLIBC_HAS_XLOCALE__ /* Initialize thread-locale current locale to point to the global one. With __thread support, the variable's initializer takes care of this. */ uselocale (LC_GLOBAL_LOCALE); diff --git a/libpthread/linuxthreads.old/locale.c b/libpthread/linuxthreads.old/locale.c index c0879d0ce..12497182d 100644 --- a/libpthread/linuxthreads.old/locale.c +++ b/libpthread/linuxthreads.old/locale.c @@ -11,8 +11,8 @@ * 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. + * License along with this library; if not, see + * <http://www.gnu.org/licenses/>. */ #include <features.h> diff --git a/libpthread/linuxthreads.old/lockfile.c b/libpthread/linuxthreads.old/lockfile.c index d054b62cb..de834c476 100644 --- a/libpthread/linuxthreads.old/lockfile.c +++ b/libpthread/linuxthreads.old/lockfile.c @@ -13,9 +13,8 @@ Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ + License along with the GNU C Library; see the file COPYING.LIB. If + not, see <http://www.gnu.org/licenses/>. */ #include <stdio.h> #include <pthread.h> diff --git a/libpthread/linuxthreads.old/manager.c b/libpthread/linuxthreads.old/manager.c index 69fdd1cb5..e4022f8ea 100644 --- a/libpthread/linuxthreads.old/manager.c +++ b/libpthread/linuxthreads.old/manager.c @@ -35,6 +35,9 @@ #include "semaphore.h" #include "debug.h" /* PDEBUG, added by StS */ +#ifndef THREAD_STACK_OFFSET +#define THREAD_STACK_OFFSET 0 +#endif /* poll() is not supported in kernel <= 2.0, therefore is __NR_poll is * not available, we assume an old Linux kernel is in use and we will @@ -137,7 +140,7 @@ int attribute_noreturn __pthread_manager(void *arg) #endif /* __UCLIBC_HAS_XLOCALE__ */ /* Block all signals except __pthread_sig_cancel and SIGTRAP */ - sigfillset(&manager_mask); + __sigfillset(&manager_mask); sigdelset(&manager_mask, __pthread_sig_cancel); /* for thread termination */ sigdelset(&manager_mask, SIGTRAP); /* for debugging purposes */ if (__pthread_threads_debug && __pthread_sig_debug > 0) @@ -146,7 +149,7 @@ int attribute_noreturn __pthread_manager(void *arg) /* Raise our priority to match that of main thread */ __pthread_manager_adjust_prio(__pthread_main_thread->p_priority); /* Synchronize debugging of the thread manager */ - n = TEMP_FAILURE_RETRY(__libc_read(reqfd, (char *)&request, + n = TEMP_FAILURE_RETRY(read(reqfd, (char *)&request, sizeof(request))); #ifndef USE_SELECT ufd.fd = reqfd; @@ -183,9 +186,9 @@ int attribute_noreturn __pthread_manager(void *arg) #endif { - PDEBUG("before __libc_read\n"); - n = __libc_read(reqfd, (char *)&request, sizeof(request)); - PDEBUG("after __libc_read, n=%d\n", n); + PDEBUG("before read\n"); + n = read(reqfd, (char *)&request, sizeof(request)); + PDEBUG("after read, n=%d\n", n); switch(request.req_kind) { case REQ_CREATE: PDEBUG("got REQ_CREATE\n"); @@ -198,7 +201,7 @@ int attribute_noreturn __pthread_manager(void *arg) request.req_thread->p_pid, request.req_thread->p_report_events, &request.req_thread->p_eventbuf.eventmask); - PDEBUG("restarting %d\n", request.req_thread); + PDEBUG("restarting %p\n", request.req_thread); restart(request.req_thread); break; case REQ_FREE: @@ -206,7 +209,7 @@ int attribute_noreturn __pthread_manager(void *arg) pthread_handle_free(request.req_args.free.thread_id); break; case REQ_PROCESS_EXIT: - PDEBUG("got REQ_PROCESS_EXIT from %d, exit code = %d\n", + PDEBUG("got REQ_PROCESS_EXIT from %p, exit code = %d\n", request.req_thread, request.req_args.exit.code); pthread_handle_exit(request.req_thread, request.req_args.exit.code); @@ -229,14 +232,14 @@ int attribute_noreturn __pthread_manager(void *arg) break; case REQ_POST: PDEBUG("got REQ_POST\n"); - __new_sem_post(request.req_args.post); + sem_post(request.req_args.post); break; case REQ_DEBUG: PDEBUG("got REQ_DEBUG\n"); /* Make gdb aware of new thread and gdb will restart the new thread when it is ready to handle the new thread. */ if (__pthread_threads_debug && __pthread_sig_debug > 0) { - PDEBUG("about to call raise(__pthread_sig_debug)\n"); + PDEBUG("about to call raise(__pthread_sig_debug)\n"); raise(__pthread_sig_debug); } case REQ_KICK: @@ -248,7 +251,7 @@ int attribute_noreturn __pthread_manager(void *arg) } } -int __pthread_manager_event(void *arg) +int attribute_noreturn __pthread_manager_event(void *arg) { /* If we have special thread_self processing, initialize it. */ #ifdef INIT_THREAD_SELF @@ -260,7 +263,7 @@ int __pthread_manager_event(void *arg) /* Free it immediately. */ __pthread_unlock (THREAD_GETMEM((&__pthread_manager_thread), p_lock)); - return __pthread_manager(arg); + __pthread_manager(arg); } /* Process creation */ @@ -301,7 +304,7 @@ pthread_start_thread(void *arg) if (__pthread_threads_debug && __pthread_sig_debug > 0) { request.req_thread = self; request.req_kind = REQ_DEBUG; - TEMP_FAILURE_RETRY(__libc_write(__pthread_manager_request, + TEMP_FAILURE_RETRY(write(__pthread_manager_request, (char *) &request, sizeof(request))); suspend(self); } @@ -349,8 +352,7 @@ static int pthread_allocate_stack(const pthread_attr_t *attr, if (attr != NULL && attr->__stackaddr_set) { /* The user provided a stack. */ - new_thread = - (pthread_descr) ((long)(attr->__stackaddr) & -sizeof(void *)) - 1; + new_thread = (pthread_descr) ((long)(attr->__stackaddr) & -sizeof(void *)) - 1; new_thread_bottom = (char *) attr->__stackaddr - attr->__stacksize; guardaddr = NULL; guardsize = 0; @@ -368,7 +370,7 @@ static int pthread_allocate_stack(const pthread_attr_t *attr, #ifdef __ARCH_USE_MMU__ stacksize = STACK_SIZE - pagesize; if (attr != NULL) - stacksize = MIN (stacksize, roundup(attr->__stacksize, pagesize)); + stacksize = MIN(stacksize, roundup(attr->__stacksize, pagesize)); /* Allocate space for stack and thread descriptor at default address */ new_thread = default_new_thread; new_thread_bottom = (char *) (new_thread + 1) - stacksize; @@ -394,7 +396,7 @@ static int pthread_allocate_stack(const pthread_attr_t *attr, /* Put a bad page at the bottom of the stack */ guardsize = attr->__guardsize; guardaddr = (void *)new_thread_bottom - guardsize; - if (mmap ((caddr_t) guardaddr, guardsize, 0, MAP_FIXED, -1, 0) + if (mmap((caddr_t) guardaddr, guardsize, 0, MAP_FIXED, -1, 0) == MAP_FAILED) { /* We don't make this an error. */ @@ -477,6 +479,7 @@ static int pthread_handle_create(pthread_t *thread, const pthread_attr_t *attr, int pid; pthread_descr new_thread; char * new_thread_bottom; + char * new_thread_top; pthread_t new_thread_id; char *guardaddr = NULL; size_t guardsize = 0; @@ -562,7 +565,7 @@ static int pthread_handle_create(pthread_t *thread, const pthread_attr_t *attr, /* Do the cloning. We have to use two different functions depending on whether we are debugging or not. */ pid = 0; /* Note that the thread never can have PID zero. */ - + new_thread_top = ((char *)new_thread - THREAD_STACK_OFFSET); /* ******************************************************** */ /* This code was moved from below to cope with running threads @@ -579,9 +582,9 @@ static int pthread_handle_create(pthread_t *thread, const pthread_attr_t *attr, /* See whether the TD_CREATE event bit is set in any of the masks. */ int idx = __td_eventword (TD_CREATE); - uint32_t mask = __td_eventmask (TD_CREATE); + uint32_t m = __td_eventmask (TD_CREATE); - if ((mask & (__pthread_threads_events.event_bits[idx] + if ((m & (__pthread_threads_events.event_bits[idx] | event_maskp->event_bits[idx])) != 0) { /* Lock the mutex the child will use now so that it will stop. */ @@ -589,12 +592,12 @@ static int pthread_handle_create(pthread_t *thread, const pthread_attr_t *attr, /* We have to report this event. */ #ifdef __ia64__ - pid = __clone2(pthread_start_thread_event, (void **) new_thread, - (char *)new_thread - new_thread_bottom, + pid = __clone2(pthread_start_thread_event, new_thread_top, + new_thread_top - new_thread_bottom, CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | __pthread_sig_cancel, new_thread); #else - pid = clone(pthread_start_thread_event, (void **) new_thread, + pid = clone(pthread_start_thread_event, new_thread_top, CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | __pthread_sig_cancel, new_thread); #endif @@ -627,12 +630,12 @@ static int pthread_handle_create(pthread_t *thread, const pthread_attr_t *attr, { PDEBUG("cloning new_thread = %p\n", new_thread); #ifdef __ia64__ - pid = __clone2(pthread_start_thread, (void **) new_thread, - (char *)new_thread - new_thread_bottom, + pid = __clone2(pthread_start_thread, new_thread_top, + new_thread_top - new_thread_bottom, CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | __pthread_sig_cancel, new_thread); #else - pid = clone(pthread_start_thread, (void **) new_thread, + pid = clone(pthread_start_thread, new_thread_top, CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | __pthread_sig_cancel, new_thread); #endif @@ -663,7 +666,7 @@ static int pthread_handle_create(pthread_t *thread, const pthread_attr_t *attr, __pthread_handles[sseg].h_descr = NULL; __pthread_handles[sseg].h_bottom = NULL; __pthread_handles_num--; - return errno; + return saved_errno; } PDEBUG("new thread pid = %d\n", pid); @@ -701,12 +704,16 @@ static void pthread_free(pthread_descr th) { pthread_handle handle; pthread_readlock_info *iter, *next; +#ifndef __ARCH_USE_MMU__ char *h_bottom_save; +#endif /* Make the handle invalid */ handle = thread_handle(th->p_tid); __pthread_lock(&handle->h_lock, NULL); +#ifndef __ARCH_USE_MMU__ h_bottom_save = handle->h_bottom; +#endif handle->h_descr = NULL; handle->h_bottom = (char *)(-1L); __pthread_unlock(&handle->h_lock); @@ -734,20 +741,18 @@ static void pthread_free(pthread_descr th) /* If initial thread, nothing to free */ if (th == &__pthread_initial_thread) return; -#ifdef __ARCH_USE_MMU__ if (!th->p_userstack) { +#ifdef __ARCH_USE_MMU__ /* Free the stack and thread descriptor area */ if (th->p_guardsize != 0) munmap(th->p_guardaddr, th->p_guardsize); munmap((caddr_t) ((char *)(th+1) - STACK_SIZE), STACK_SIZE); - } #else - /* For non-MMU systems we always malloc the stack, so free it here. -StS */ - if (!th->p_userstack) { + /* For non-MMU systems we always malloc the stack, so free it here. -StS */ free(h_bottom_save); - } #endif /* __ARCH_USE_MMU__ */ + } } /* Handle threads that have exited */ @@ -808,7 +813,7 @@ static void pthread_reap_children(void) int status; PDEBUG("\n"); - while ((pid = __libc_waitpid(-1, &status, WNOHANG | __WCLONE)) > 0) { + while ((pid = waitpid(-1, &status, WNOHANG | __WCLONE)) > 0) { pthread_exited(pid); if (WIFSIGNALED(status)) { /* If a thread died due to a signal, send the same signal to @@ -907,7 +912,7 @@ void __pthread_manager_sighandler(int sig attribute_unused) struct pthread_request request; request.req_thread = 0; request.req_kind = REQ_KICK; - TEMP_FAILURE_RETRY(__libc_write(__pthread_manager_request, + TEMP_FAILURE_RETRY(write(__pthread_manager_request, (char *) &request, sizeof(request))); } } diff --git a/libpthread/linuxthreads.old/oldsemaphore.c b/libpthread/linuxthreads.old/oldsemaphore.c deleted file mode 100644 index 2a7b40acc..000000000 --- a/libpthread/linuxthreads.old/oldsemaphore.c +++ /dev/null @@ -1,241 +0,0 @@ -/* - * This file contains the old semaphore code that we need to - * preserve for glibc-2.0 backwards compatibility. Port to glibc 2.1 - * done by Cristian Gafton. - */ - -/* Linuxthreads - a simple clone()-based implementation of Posix */ -/* threads for Linux. */ -/* Copyright (C) 1996 Xavier Leroy (Xavier.Leroy@inria.fr) */ -/* */ -/* This program 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 program 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. */ - -/* Semaphores a la POSIX 1003.1b */ - -#include <errno.h> -#include "pthread.h" -#include "internals.h" -#include "spinlock.h" -#include "restart.h" -#include "queue.h" - -typedef struct { - long int sem_status; - int sem_spinlock; -} old_sem_t; - -/* Maximum value the semaphore can have. */ -#define SEM_VALUE_MAX ((int) ((~0u) >> 1)) - -static __inline__ int sem_compare_and_swap(old_sem_t *sem, long oldval, long newval) -{ - return compare_and_swap(&sem->sem_status, oldval, newval, &sem->sem_spinlock); -} - -/* The state of a semaphore is represented by a long int encoding - either the semaphore count if >= 0 and no thread is waiting on it, - or the head of the list of threads waiting for the semaphore. - To distinguish the two cases, we encode the semaphore count N - as 2N+1, so that it has the lowest bit set. - - A sequence of sem_wait operations on a semaphore initialized to N - result in the following successive states: - 2N+1, 2N-1, ..., 3, 1, &first_waiting_thread, &second_waiting_thread, ... -*/ - -static void sem_restart_list(pthread_descr waiting); - -int __old_sem_init(old_sem_t *sem, int pshared, unsigned int value); -int __old_sem_init(old_sem_t *sem, int pshared, unsigned int value) -{ - if (value > SEM_VALUE_MAX) { - errno = EINVAL; - return -1; - } - if (pshared) { - errno = ENOSYS; - return -1; - } - sem->sem_spinlock = 0; - sem->sem_status = ((long)value << 1) + 1; - return 0; -} - -/* Function called by pthread_cancel to remove the thread from - waiting inside __old_sem_wait. Here we simply unconditionally - indicate that the thread is to be woken, by returning 1. */ - -static int old_sem_extricate_func(void *obj attribute_unused, pthread_descr th attribute_unused) -{ - return 1; -} - -int __old_sem_wait(old_sem_t * sem); -int __old_sem_wait(old_sem_t * sem) -{ - long oldstatus, newstatus; - volatile pthread_descr self = thread_self(); - pthread_descr * th; - pthread_extricate_if extr; - - /* Set up extrication interface */ - extr.pu_object = 0; - extr.pu_extricate_func = old_sem_extricate_func; - - while (1) { - /* Register extrication interface */ - __pthread_set_own_extricate_if(self, &extr); - do { - oldstatus = sem->sem_status; - if ((oldstatus & 1) && (oldstatus != 1)) - newstatus = oldstatus - 2; - else { - newstatus = (long) self; - self->p_nextwaiting = (pthread_descr) oldstatus; - } - } - while (! sem_compare_and_swap(sem, oldstatus, newstatus)); - if (newstatus & 1) { - /* We got the semaphore. */ - __pthread_set_own_extricate_if(self, 0); - return 0; - } - /* Wait for sem_post or cancellation */ - suspend(self); - __pthread_set_own_extricate_if(self, 0); - - /* This is a cancellation point */ - if (self->p_canceled && self->p_cancelstate == PTHREAD_CANCEL_ENABLE) { - /* Remove ourselves from the waiting list if we're still on it */ - /* First check if we're at the head of the list. */ - do { - oldstatus = sem->sem_status; - if (oldstatus != (long) self) break; - newstatus = (long) self->p_nextwaiting; - } - while (! sem_compare_and_swap(sem, oldstatus, newstatus)); - /* Now, check if we're somewhere in the list. - There's a race condition with sem_post here, but it does not matter: - the net result is that at the time pthread_exit is called, - self is no longer reachable from sem->sem_status. */ - if (oldstatus != (long) self && (oldstatus & 1) == 0) { - for (th = &(((pthread_descr) oldstatus)->p_nextwaiting); - *th != NULL && *th != (pthread_descr) 1; - th = &((*th)->p_nextwaiting)) { - if (*th == self) { - *th = self->p_nextwaiting; - break; - } - } - } - __pthread_do_exit(PTHREAD_CANCELED, CURRENT_STACK_FRAME); - } - } -} - -int __old_sem_trywait(old_sem_t * sem); -int __old_sem_trywait(old_sem_t * sem) -{ - long oldstatus, newstatus; - - do { - oldstatus = sem->sem_status; - if ((oldstatus & 1) == 0 || (oldstatus == 1)) { - errno = EAGAIN; - return -1; - } - newstatus = oldstatus - 2; - } - while (! sem_compare_and_swap(sem, oldstatus, newstatus)); - return 0; -} - -int __old_sem_post(old_sem_t * sem); -int __old_sem_post(old_sem_t * sem) -{ - long oldstatus, newstatus; - - do { - oldstatus = sem->sem_status; - if ((oldstatus & 1) == 0) - newstatus = 3; - else { - if (oldstatus >= SEM_VALUE_MAX) { - /* Overflow */ - errno = ERANGE; - return -1; - } - newstatus = oldstatus + 2; - } - } - while (! sem_compare_and_swap(sem, oldstatus, newstatus)); - if ((oldstatus & 1) == 0) - sem_restart_list((pthread_descr) oldstatus); - return 0; -} - -int __old_sem_getvalue(old_sem_t * sem, int * sval); -int __old_sem_getvalue(old_sem_t * sem, int * sval) -{ - long status = sem->sem_status; - if (status & 1) - *sval = (int)((unsigned long) status >> 1); - else - *sval = 0; - return 0; -} - -int __old_sem_destroy(old_sem_t * sem); -int __old_sem_destroy(old_sem_t * sem) -{ - if ((sem->sem_status & 1) == 0) { - errno = EBUSY; - return -1; - } - return 0; -} - -/* Auxiliary function for restarting all threads on a waiting list, - in priority order. */ - -static void sem_restart_list(pthread_descr waiting) -{ - pthread_descr th, towake, *p; - - /* Sort list of waiting threads by decreasing priority (insertion sort) */ - towake = NULL; - while (waiting != (pthread_descr) 1) { - th = waiting; - waiting = waiting->p_nextwaiting; - p = &towake; - while (*p != NULL && th->p_priority < (*p)->p_priority) - p = &((*p)->p_nextwaiting); - th->p_nextwaiting = *p; - *p = th; - } - /* Wake up threads in priority order */ - while (towake != NULL) { - th = towake; - towake = towake->p_nextwaiting; - th->p_nextwaiting = NULL; - restart(th); - } -} - -#if defined __PIC__ && defined DO_VERSIONING -symbol_version (__old_sem_init, sem_init, GLIBC_2.0); -symbol_version (__old_sem_wait, sem_wait, GLIBC_2.0); -symbol_version (__old_sem_trywait, sem_trywait, GLIBC_2.0); -symbol_version (__old_sem_post, sem_post, GLIBC_2.0); -symbol_version (__old_sem_getvalue, sem_getvalue, GLIBC_2.0); -symbol_version (__old_sem_destroy, sem_destroy, GLIBC_2.0); -#endif - diff --git a/libpthread/linuxthreads.old/pt-machine.c b/libpthread/linuxthreads.old/pt-machine.c index 438008d5d..6963dfcab 100644 --- a/libpthread/linuxthreads.old/pt-machine.c +++ b/libpthread/linuxthreads.old/pt-machine.c @@ -14,8 +14,7 @@ You should have received a copy of the GNU Library General Public License along with the GNU C Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ + see <http://www.gnu.org/licenses/>. */ #define PT_EI diff --git a/libpthread/linuxthreads.old/ptfork.c b/libpthread/linuxthreads.old/ptfork.c index c34ea8104..6f1e2d3c9 100644 --- a/libpthread/linuxthreads.old/ptfork.c +++ b/libpthread/linuxthreads.old/ptfork.c @@ -20,6 +20,7 @@ #ifdef __ARCH_USE_MMU__ +#include <bits/uClibc_mutex.h> #include <stddef.h> #include <stdlib.h> #include <unistd.h> @@ -36,6 +37,16 @@ static struct handler_list * pthread_atfork_prepare = NULL; static struct handler_list * pthread_atfork_parent = NULL; static struct handler_list * pthread_atfork_child = NULL; +#ifdef __MALLOC__ +__UCLIBC_MUTEX_EXTERN(__malloc_heap_lock); +__UCLIBC_MUTEX_EXTERN(__malloc_sbrk_lock); +#ifdef __UCLIBC_UCLINUX_BROKEN_MUNMAP__ +__UCLIBC_MUTEX_EXTERN(__malloc_mmb_heap_lock); +#endif +#elif defined(__MALLOC_STANDARD__) || defined(__MALLOC_SIMPLE__) +__UCLIBC_MUTEX_EXTERN(__malloc_lock); +#endif + static void pthread_insert_list(struct handler_list ** list, void (*handler)(void), struct handler_list * newlist, @@ -71,17 +82,18 @@ int pthread_atfork(void (*prepare)(void), __pthread_mutex_unlock(&pthread_atfork_lock); return 0; } -//strong_alias (__pthread_atfork, pthread_atfork) +/*strong_alias (__pthread_atfork, pthread_atfork)*/ static __inline__ void pthread_call_handlers(struct handler_list * list) { for (/*nothing*/; list != NULL; list = list->next) (list->handler)(); } -extern __typeof(fork) __libc_fork; +void __pthread_once_fork_prepare(void); +void __pthread_once_fork_child(void); +void __pthread_once_fork_parent(void); -pid_t __fork(void) attribute_hidden; -pid_t __fork(void) +static pid_t __fork(void) { pid_t pid; struct handler_list * prepare, * child, * parent; @@ -90,24 +102,53 @@ pid_t __fork(void) prepare = pthread_atfork_prepare; child = pthread_atfork_child; parent = pthread_atfork_parent; - __pthread_mutex_unlock(&pthread_atfork_lock); pthread_call_handlers(prepare); + + __pthread_once_fork_prepare(); +#ifdef __MALLOC__ + __pthread_mutex_lock(&__malloc_sbrk_lock); + __pthread_mutex_lock(&__malloc_heap_lock); +#ifdef __UCLIBC_UCLINUX_BROKEN_MUNMAP__ + __pthread_mutex_lock(&__malloc_mmb_heap_lock); +#endif +#elif defined(__MALLOC_STANDARD__) || defined(__MALLOC_SIMPLE__) + __pthread_mutex_lock(&__malloc_lock); +#endif + pid = __libc_fork(); if (pid == 0) { +#if defined(__MALLOC_STANDARD__) || defined(__MALLOC_SIMPLE__) + __libc_lock_init_recursive(__malloc_lock); +#elif defined(__MALLOC__) +#ifdef __UCLIBC_UCLINUX_BROKEN_MUNMAP__ + __libc_lock_init_adaptive(__malloc_mmb_heap_lock); +#endif + __libc_lock_init_adaptive(__malloc_heap_lock); + __libc_lock_init(__malloc_sbrk_lock); +#endif + __libc_lock_init_adaptive(pthread_atfork_lock); __pthread_reset_main_thread(); __fresetlockfiles(); + __pthread_once_fork_child(); pthread_call_handlers(child); } else { +#if defined(__MALLOC_STANDARD__) || defined(__MALLOC_SIMPLE__) + __pthread_mutex_unlock(&__malloc_lock); +#elif defined(__MALLOC__) +#ifdef __UCLIBC_UCLINUX_BROKEN_MUNMAP__ + __pthread_mutex_unlock(&__malloc_mmb_heap_lock); +#endif + __pthread_mutex_unlock(&__malloc_heap_lock); + __pthread_mutex_unlock(&__malloc_sbrk_lock); +#endif + __pthread_mutex_unlock(&pthread_atfork_lock); + __pthread_once_fork_parent(); pthread_call_handlers(parent); } return pid; } strong_alias(__fork,fork) - -pid_t vfork(void) -{ - return __fork(); -} +strong_alias(__fork,vfork) #else diff --git a/libpthread/linuxthreads.old/pthread.c b/libpthread/linuxthreads.old/pthread.c index 35de4b731..00197b158 100644 --- a/libpthread/linuxthreads.old/pthread.c +++ b/libpthread/linuxthreads.old/pthread.c @@ -14,8 +14,6 @@ /* Thread creation, initialization, and basic low-level routines */ -#define __FORCE_GLIBC -#include <features.h> #include <errno.h> #include <netdb.h> /* for h_errno */ #include <stddef.h> @@ -38,8 +36,6 @@ #include <sys/types.h> #include <sys/syscall.h> -/* mods for uClibc: __libc_sigaction is not in any standard headers */ -extern __typeof(sigaction) __libc_sigaction; libpthread_hidden_proto(waitpid) libpthread_hidden_proto(raise) @@ -168,12 +164,10 @@ pthread_descr __pthread_main_thread = &__pthread_initial_thread; char *__pthread_initial_thread_bos = NULL; -/* For non-MMU systems also remember to stack top of the initial thread. - * This is adapted when other stacks are malloc'ed since we don't know - * the bounds a-priori. -StS */ - #ifndef __ARCH_USE_MMU__ +/* See nommu notes in internals.h and pthread_initialize() below. */ char *__pthread_initial_thread_tos = NULL; +char *__pthread_initial_thread_mid = NULL; #endif /* __ARCH_USE_MMU__ */ /* File descriptor for sending requests to the thread manager. */ @@ -262,6 +256,7 @@ int __libc_current_sigrtmax (void) return current_rtmax; } +#if 0 /* Allocate real-time signal with highest/lowest available priority. Please note that we don't use a lock since we assume this function to be called at program start. */ @@ -274,6 +269,7 @@ int __libc_allocate_rtsig (int high) return high ? current_rtmin++ : current_rtmax--; } #endif +#endif /* Initialize the pthread library. Initialization is split in two functions: @@ -321,7 +317,7 @@ libpthread_hidden_proto(pthread_condattr_init) struct pthread_functions __pthread_functions = { -#if !(USE_TLS && HAVE___THREAD) +#if !defined __UCLIBC_HAS_TLS__ && defined __UCLIBC_HAS_RPC__ .ptr_pthread_internal_tsd_set = __pthread_internal_tsd_set, .ptr_pthread_internal_tsd_get = __pthread_internal_tsd_get, .ptr_pthread_internal_tsd_address = __pthread_internal_tsd_address, @@ -369,10 +365,10 @@ struct pthread_functions __pthread_functions = .ptr_pthread_sigwait = pthread_sigwait, .ptr_pthread_raise = pthread_raise, .ptr__pthread_cleanup_push = _pthread_cleanup_push, - .ptr__pthread_cleanup_pop = _pthread_cleanup_pop + .ptr__pthread_cleanup_pop = _pthread_cleanup_pop, */ .ptr__pthread_cleanup_push_defer = __pthread_cleanup_push_defer, - .ptr__pthread_cleanup_pop_restore = __pthread_cleanup_pop_restore, + .ptr__pthread_cleanup_pop_restore = __pthread_cleanup_pop_restore }; #ifdef SHARED # define ptr_pthread_functions &__pthread_functions @@ -457,12 +453,19 @@ static void pthread_initialize(void) setrlimit(RLIMIT_STACK, &limit); } #else - /* For non-MMU assume __pthread_initial_thread_tos at upper page boundary, and - * __pthread_initial_thread_bos at address 0. These bounds are refined as we - * malloc other stack frames such that they don't overlap. -StS + /* For non-MMU, the initial thread stack can reside anywhere in memory. + * We don't have a way of knowing where the kernel started things -- top + * or bottom (well, that isn't exactly true, but the solution is fairly + * complex and error prone). All we can determine here is an address + * that lies within that stack. Save that address as a reference so that + * as other thread stacks are created, we can adjust the estimated bounds + * of the initial thread's stack appropriately. + * + * This checking is handled in NOMMU_INITIAL_THREAD_BOUNDS(), so see that + * for a few more details. */ - __pthread_initial_thread_tos = - (char *)(((long)CURRENT_STACK_FRAME + getpagesize()) & ~(getpagesize() - 1)); + __pthread_initial_thread_mid = CURRENT_STACK_FRAME; + __pthread_initial_thread_tos = (char *) -1; __pthread_initial_thread_bos = (char *) 1; /* set it non-zero so we know we have been here */ PDEBUG("initial thread stack bounds: bos=%p, tos=%p\n", __pthread_initial_thread_bos, __pthread_initial_thread_tos); @@ -471,22 +474,19 @@ static void pthread_initialize(void) /* Setup signal handlers for the initial thread. Since signal handlers are shared between threads, these settings will be inherited by all other threads. */ + memset(&sa, 0, sizeof(sa)); sa.sa_handler = pthread_handle_sigrestart; - sigemptyset(&sa.sa_mask); - sa.sa_flags = 0; __libc_sigaction(__pthread_sig_restart, &sa, NULL); sa.sa_handler = pthread_handle_sigcancel; sigaddset(&sa.sa_mask, __pthread_sig_restart); - // sa.sa_flags = 0; __libc_sigaction(__pthread_sig_cancel, &sa, NULL); if (__pthread_sig_debug > 0) { sa.sa_handler = pthread_handle_sigdebug; - sigemptyset(&sa.sa_mask); - // sa.sa_flags = 0; + __sigemptyset(&sa.sa_mask); __libc_sigaction(__pthread_sig_debug, &sa, NULL); } /* Initially, block __pthread_sig_restart. Will be unblocked on demand. */ - sigemptyset(&mask); + __sigemptyset(&mask); sigaddset(&mask, __pthread_sig_restart); sigprocmask(SIG_BLOCK, &mask, NULL); /* And unblock __pthread_sig_cancel if it has been blocked. */ @@ -526,11 +526,11 @@ int __pthread_initialize_manager(void) /* On non-MMU systems we make sure that the initial thread bounds don't overlap * with the manager stack frame */ NOMMU_INITIAL_THREAD_BOUNDS(__pthread_manager_thread_tos,__pthread_manager_thread_bos); - PDEBUG("manager stack: size=%d, bos=%p, tos=%p\n", THREAD_MANAGER_STACK_SIZE, + PDEBUG("manager stack: size=%ld, bos=%p, tos=%p\n", THREAD_MANAGER_STACK_SIZE, __pthread_manager_thread_bos, __pthread_manager_thread_tos); #if 0 PDEBUG("initial stack: estimate bos=%p, tos=%p\n", - __pthread_initial_thread_bos, __pthread_initial_thread_tos); + __pthread_initial_thread_bos, __pthread_initial_thread_tos); #endif /* Setup pipe to communicate with thread manager */ @@ -540,7 +540,7 @@ int __pthread_initialize_manager(void) } /* Start the thread manager */ pid = 0; -#ifdef USE_TLS +#if defined(USE_TLS) && USE_TLS if (__linuxthreads_initial_report_events != 0) THREAD_SETMEM (((pthread_descr) NULL), p_report_events, __linuxthreads_initial_report_events); @@ -613,8 +613,8 @@ int __pthread_initialize_manager(void) } if (pid == -1) { free(__pthread_manager_thread_bos); - __libc_close(manager_pipe[0]); - __libc_close(manager_pipe[1]); + close(manager_pipe[0]); + close(manager_pipe[1]); return -1; } __pthread_manager_request = manager_pipe[1]; /* writing end */ @@ -633,7 +633,7 @@ int __pthread_initialize_manager(void) /* Synchronize debugging of the thread manager */ PDEBUG("send REQ_DEBUG to manager thread\n"); request.req_kind = REQ_DEBUG; - TEMP_FAILURE_RETRY(__libc_write(__pthread_manager_request, + TEMP_FAILURE_RETRY(write(__pthread_manager_request, (char *) &request, sizeof(request))); return 0; } @@ -653,10 +653,9 @@ int pthread_create(pthread_t *thread, const pthread_attr_t *attr, request.req_args.create.attr = attr; request.req_args.create.fn = start_routine; request.req_args.create.arg = arg; - sigprocmask(SIG_SETMASK, (const sigset_t *) NULL, - &request.req_args.create.mask); + sigprocmask(SIG_SETMASK, NULL, &request.req_args.create.mask); PDEBUG("write REQ_CREATE to manager thread\n"); - TEMP_FAILURE_RETRY(__libc_write(__pthread_manager_request, + TEMP_FAILURE_RETRY(write(__pthread_manager_request, (char *) &request, sizeof(request))); PDEBUG("before suspend(self)\n"); suspend(self); @@ -714,7 +713,7 @@ static pthread_descr thread_self_stack(void) if (sp >= __pthread_manager_thread_bos && sp < __pthread_manager_thread_tos) return manager_thread; h = __pthread_handles + 2; -# ifdef USE_TLS +# if defined(USE_TLS) && USE_TLS while (h->h_descr == NULL || ! (sp <= (char *) h->h_descr->p_stackaddr && sp >= h->h_bottom)) h++; @@ -785,7 +784,7 @@ static void pthread_onexit_process(int retcode, void *arg attribute_unused) request.req_thread = self; request.req_kind = REQ_PROCESS_EXIT; request.req_args.exit.code = retcode; - TEMP_FAILURE_RETRY(__libc_write(__pthread_manager_request, + TEMP_FAILURE_RETRY(write(__pthread_manager_request, (char *) &request, sizeof(request))); suspend(self); /* Main thread should accumulate times for thread manager and its @@ -849,7 +848,7 @@ static void pthread_handle_sigcancel(int sig) /* Main thread should accumulate times for thread manager and its children, so that timings for main thread account for all threads. */ if (self == __pthread_main_thread) { -#ifdef USE_TLS +#if defined(USE_TLS) && USE_TLS waitpid(__pthread_manager_thread->p_pid, NULL, __WCLONE); #else waitpid(__pthread_manager_thread.p_pid, NULL, __WCLONE); @@ -899,8 +898,8 @@ void __pthread_reset_main_thread(void) free(__pthread_manager_thread_bos); __pthread_manager_thread_bos = __pthread_manager_thread_tos = NULL; /* Close the two ends of the pipe */ - __libc_close(__pthread_manager_request); - __libc_close(__pthread_manager_reader); + close(__pthread_manager_request); + close(__pthread_manager_reader); __pthread_manager_request = __pthread_manager_reader = -1; } @@ -928,9 +927,9 @@ void __pthread_kill_other_threads_np(void) /* Reset the signal handlers behaviour for the signals the implementation uses since this would be passed to the new process. */ - sigemptyset(&sa.sa_mask); - sa.sa_flags = 0; - sa.sa_handler = SIG_DFL; + memset(&sa, 0, sizeof(sa)); + if (SIG_DFL) /* if it's constant zero, it's already done */ + sa.sa_handler = SIG_DFL; __libc_sigaction(__pthread_sig_restart, &sa, NULL); __libc_sigaction(__pthread_sig_cancel, &sa, NULL); if (__pthread_sig_debug > 0) @@ -1007,7 +1006,7 @@ __pthread_timedsuspend_old(pthread_descr self, const struct timespec *abstime) THREAD_SETMEM(self, p_signal_jmp, &jmpbuf); THREAD_SETMEM(self, p_signal, 0); /* Unblock the restart signal */ - sigemptyset(&unblock); + __sigemptyset(&unblock); sigaddset(&unblock, __pthread_sig_restart); sigprocmask(SIG_UNBLOCK, &unblock, &initial_mask); @@ -1026,7 +1025,7 @@ __pthread_timedsuspend_old(pthread_descr self, const struct timespec *abstime) /* Sleep for the required duration. If woken by a signal, resume waiting as required by Single Unix Specification. */ - if (reltime.tv_sec < 0 || __libc_nanosleep(&reltime, NULL) == 0) + if (reltime.tv_sec < 0 || nanosleep(&reltime, NULL) == 0) break; } @@ -1092,7 +1091,7 @@ int __pthread_timedsuspend_new(pthread_descr self, const struct timespec *abstim THREAD_SETMEM(self, p_signal_jmp, &jmpbuf); THREAD_SETMEM(self, p_signal, 0); /* Unblock the restart signal */ - sigemptyset(&unblock); + __sigemptyset(&unblock); sigaddset(&unblock, __pthread_sig_restart); sigprocmask(SIG_UNBLOCK, &unblock, &initial_mask); @@ -1111,7 +1110,7 @@ int __pthread_timedsuspend_new(pthread_descr self, const struct timespec *abstim /* Sleep for the required duration. If woken by a signal, resume waiting as required by Single Unix Specification. */ - if (reltime.tv_sec < 0 || __libc_nanosleep(&reltime, NULL) == 0) + if (reltime.tv_sec < 0 || nanosleep(&reltime, NULL) == 0) break; } @@ -1151,16 +1150,16 @@ void __pthread_message(char * fmt, ...) va_start(args, fmt); vsnprintf(buffer + 8, sizeof(buffer) - 8, fmt, args); va_end(args); - TEMP_FAILURE_RETRY(__libc_write(2, buffer, strlen(buffer))); + TEMP_FAILURE_RETRY(write(2, buffer, strlen(buffer))); } #endif #ifndef __PIC__ -/* We need a hook to force the cancelation wrappers to be linked in when +/* We need a hook to force the cancellation wrappers to be linked in when static libpthread is used. */ -extern const int __pthread_provide_wrappers; -static const int *const __pthread_require_wrappers = +extern const char __pthread_provide_wrappers; +static const char *const __pthread_require_wrappers = &__pthread_provide_wrappers; #endif diff --git a/libpthread/linuxthreads.old/ptlongjmp.c b/libpthread/linuxthreads.old/ptlongjmp.c index b3ff2746f..5cb708944 100644 --- a/libpthread/linuxthreads.old/ptlongjmp.c +++ b/libpthread/linuxthreads.old/ptlongjmp.c @@ -19,11 +19,7 @@ #include "pthread.h" #include "internals.h" #include <bits/stackinfo.h> - -/* These functions are not declared anywhere since they shouldn't be - used at another place but here. */ -extern __typeof(siglongjmp) __libc_siglongjmp attribute_noreturn; -extern __typeof(longjmp) __libc_longjmp attribute_noreturn; +#include <jmpbuf-unwind.h> static void pthread_cleanup_upto(__jmp_buf target) { @@ -35,13 +31,13 @@ static void pthread_cleanup_upto(__jmp_buf target) c != NULL && _JMPBUF_UNWINDS(target, c); c = c->__prev) { -#if _STACK_GROWS_DOWN +#ifdef _STACK_GROWS_DOWN if ((char *) c <= currentframe) { c = NULL; break; } -#elif _STACK_GROWS_UP +#elif defined _STACK_GROWS_UP if ((char *) c >= currentframe) { c = NULL; @@ -58,13 +54,13 @@ static void pthread_cleanup_upto(__jmp_buf target) THREAD_SETMEM(self, p_in_sighandler, NULL); } -void attribute_noreturn siglongjmp(sigjmp_buf env, int val) +void siglongjmp(sigjmp_buf env, int val) { pthread_cleanup_upto(env->__jmpbuf); __libc_siglongjmp(env, val); } -void attribute_noreturn longjmp(jmp_buf env, int val) +void longjmp(jmp_buf env, int val) { pthread_cleanup_upto(env->__jmpbuf); __libc_longjmp(env, val); diff --git a/libpthread/linuxthreads.old/rwlock.c b/libpthread/linuxthreads.old/rwlock.c index eaf71e77c..3ab940261 100644 --- a/libpthread/linuxthreads.old/rwlock.c +++ b/libpthread/linuxthreads.old/rwlock.c @@ -16,8 +16,7 @@ You should have received a copy of the GNU Library General Public License along with the GNU C Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ + see <http://www.gnu.org/licenses/>. */ #include <errno.h> #include <pthread.h> diff --git a/libpthread/linuxthreads.old/semaphore.c b/libpthread/linuxthreads.old/semaphore.c index 7502b6e78..9025dfee6 100644 --- a/libpthread/linuxthreads.old/semaphore.c +++ b/libpthread/linuxthreads.old/semaphore.c @@ -15,6 +15,7 @@ /* Semaphores a la POSIX 1003.1b */ #include <features.h> +#include <limits.h> #include <errno.h> #include "pthread.h" #include "semaphore.h" @@ -23,8 +24,7 @@ #include "restart.h" #include "queue.h" -int __new_sem_init(sem_t *sem, int pshared, unsigned int value); -int __new_sem_init(sem_t *sem, int pshared, unsigned int value) +int sem_init(sem_t *sem, int pshared, unsigned int value) { if (value > SEM_VALUE_MAX) { errno = EINVAL; @@ -41,7 +41,7 @@ int __new_sem_init(sem_t *sem, int pshared, unsigned int value) } /* Function called by pthread_cancel to remove the thread from - waiting inside __new_sem_wait. */ + waiting inside sem_wait. */ static int new_sem_extricate_func(void *obj, pthread_descr th) { @@ -56,8 +56,7 @@ static int new_sem_extricate_func(void *obj, pthread_descr th) return did_remove; } -int __new_sem_wait(sem_t * sem); -int __new_sem_wait(sem_t * sem) +int sem_wait(sem_t * sem) { volatile pthread_descr self = thread_self(); pthread_extricate_if extr; @@ -119,8 +118,7 @@ int __new_sem_wait(sem_t * sem) return 0; } -int __new_sem_trywait(sem_t * sem); -int __new_sem_trywait(sem_t * sem) +int sem_trywait(sem_t * sem) { int retval; @@ -136,8 +134,7 @@ int __new_sem_trywait(sem_t * sem) return retval; } -int __new_sem_post(sem_t * sem); -int __new_sem_post(sem_t * sem) +int sem_post(sem_t * sem) { pthread_descr self = thread_self(); pthread_descr th; @@ -172,21 +169,19 @@ int __new_sem_post(sem_t * sem) } request.req_kind = REQ_POST; request.req_args.post = sem; - TEMP_FAILURE_RETRY(__libc_write(__pthread_manager_request, + TEMP_FAILURE_RETRY(write(__pthread_manager_request, (char *) &request, sizeof(request))); } return 0; } -int __new_sem_getvalue(sem_t * sem, int * sval); -int __new_sem_getvalue(sem_t * sem, int * sval) +int sem_getvalue(sem_t * sem, int * sval) { *sval = sem->__sem_value; return 0; } -int __new_sem_destroy(sem_t * sem); -int __new_sem_destroy(sem_t * sem) +int sem_destroy(sem_t * sem) { if (sem->__sem_waiting != NULL) { __set_errno (EBUSY); @@ -302,12 +297,3 @@ int sem_timedwait(sem_t *sem, const struct timespec *abstime) /* We got the semaphore */ return 0; } - - -weak_alias (__new_sem_init, sem_init) -weak_alias (__new_sem_wait, sem_wait) -weak_alias (__new_sem_trywait, sem_trywait) -weak_alias (__new_sem_post, sem_post) -weak_alias (__new_sem_getvalue, sem_getvalue) -weak_alias (__new_sem_destroy, sem_destroy) - diff --git a/libpthread/linuxthreads.old/semaphore.h b/libpthread/linuxthreads.old/semaphore.h index fac2e5937..3924a471d 100644 --- a/libpthread/linuxthreads.old/semaphore.h +++ b/libpthread/linuxthreads.old/semaphore.h @@ -17,6 +17,7 @@ #include <features.h> #include <sys/types.h> +#include <limits.h> #ifdef __USE_XOPEN2K # define __need_timespec # include <time.h> @@ -42,7 +43,9 @@ typedef struct #define SEM_FAILED ((sem_t *) 0) /* Maximum value the semaphore can have. */ -#define SEM_VALUE_MAX ((int) ((~0u) >> 1)) +#ifndef SEM_VALUE_MAX +#define SEM_VALUE_MAX ((int) ((~0u) >> 1)) +#endif __BEGIN_DECLS @@ -55,13 +58,13 @@ extern int sem_init (sem_t *__sem, int __pshared, unsigned int __value) __THROW; extern int sem_destroy (sem_t *__sem) __THROW; /* Open a named semaphore NAME with open flags OFLAG. */ -extern sem_t *sem_open (__const char *__name, int __oflag, ...) __THROW; +extern sem_t *sem_open (const char *__name, int __oflag, ...) __THROW; /* Close descriptor for named semaphore SEM. */ extern int sem_close (sem_t *__sem) __THROW; /* Remove named semaphore NAME. */ -extern int sem_unlink (__const char *__name) __THROW; +extern int sem_unlink (const char *__name) __THROW; /* Wait for SEM being posted. @@ -75,14 +78,14 @@ extern int sem_wait (sem_t *__sem); This function is a cancellation point and therefore not marked with __THROW. */ extern int sem_timedwait (sem_t *__restrict __sem, - __const struct timespec *__restrict __abstime); + const struct timespec *__restrict __abstime); #endif /* Test whether SEM is posted. */ -extern int sem_trywait (sem_t *__sem) __THROW; +extern int sem_trywait (sem_t *__sem) __THROWNL; /* Post SEM. */ -extern int sem_post (sem_t *__sem) __THROW; +extern int sem_post (sem_t *__sem) __THROWNL; /* Get current value of SEM and store it in *SVAL. */ extern int sem_getvalue (sem_t *__restrict __sem, int *__restrict __sval) diff --git a/libpthread/linuxthreads.old/signals.c b/libpthread/linuxthreads.old/signals.c index 23ba9778f..d8dbc78bd 100644 --- a/libpthread/linuxthreads.old/signals.c +++ b/libpthread/linuxthreads.old/signals.c @@ -20,12 +20,8 @@ #include "pthread.h" #include "internals.h" #include "spinlock.h" -#include <ucontext.h> #include <bits/sigcontextinfo.h> -/* mods for uClibc: __libc_sigaction is not in any standard headers */ -extern __typeof(sigaction) __libc_sigaction; - int pthread_sigmask(int how, const sigset_t * newmask, sigset_t * oldmask) { sigset_t mask; @@ -196,7 +192,7 @@ int sigwait(const sigset_t * set, int * sig) and if not, install our dummy handler. This is conformant to POSIX: "The effect of sigwait() on the signal actions for the signals in set is unspecified." */ - sigfillset(&mask); + __sigfillset(&mask); sigdelset(&mask, __pthread_sig_cancel); for (s = 1; s <= NSIG; s++) { if (sigismember(set, s) && @@ -207,9 +203,8 @@ int sigwait(const sigset_t * set, int * sig) if (sighandler[s].old == NULL || sighandler[s].old == (arch_sighandler_t) SIG_DFL || sighandler[s].old == (arch_sighandler_t) SIG_IGN) { + memset(&sa, 0, sizeof(sa)); sa.sa_handler = pthread_null_sighandler; - sigemptyset(&sa.sa_mask); - sa.sa_flags = 0; sigaction(s, &sa, NULL); } } diff --git a/libpthread/linuxthreads.old/specific.c b/libpthread/linuxthreads.old/specific.c index dd86148d8..c4bcfbf8c 100644 --- a/libpthread/linuxthreads.old/specific.c +++ b/libpthread/linuxthreads.old/specific.c @@ -167,7 +167,7 @@ void __pthread_destroy_specifics(void) __pthread_unlock(THREAD_GETMEM(self, p_lock)); } -#if !(USE_TLS && HAVE___THREAD) +#if !defined __UCLIBC_HAS_TLS__ && defined __UCLIBC_HAS_RPC__ /* Thread-specific data for libc. */ diff --git a/libpthread/linuxthreads.old/spinlock.c b/libpthread/linuxthreads.old/spinlock.c index 24c81d47e..80aeda529 100644 --- a/libpthread/linuxthreads.old/spinlock.c +++ b/libpthread/linuxthreads.old/spinlock.c @@ -14,8 +14,6 @@ /* Internal locks */ -#define __FORCE_GLIBC -#include <features.h> #include <errno.h> #include <sched.h> #include <time.h> @@ -67,7 +65,6 @@ void internal_function __pthread_lock(struct _pthread_fastlock * lock, #if defined HAS_COMPARE_AND_SWAP long oldstatus, newstatus; int successful_seizure, spurious_wakeup_count; - int spin_count; #endif #if defined TEST_FOR_COMPARE_AND_SWAP @@ -87,11 +84,11 @@ void internal_function __pthread_lock(struct _pthread_fastlock * lock, return; spurious_wakeup_count = 0; - spin_count = 0; /* On SMP, try spinning to get the lock. */ #if 0 if (__pthread_smp_kernel) { + int spin_count; int max_count = lock->__spinlock * 2 + 10; if (max_count > MAX_ADAPTIVE_SPIN_COUNT) diff --git a/libpthread/linuxthreads.old/sysdeps/alpha/pt-machine.h b/libpthread/linuxthreads.old/sysdeps/alpha/pt-machine.h index 97c38394b..b47343ba7 100644 --- a/libpthread/linuxthreads.old/sysdeps/alpha/pt-machine.h +++ b/libpthread/linuxthreads.old/sysdeps/alpha/pt-machine.h @@ -17,8 +17,7 @@ You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ + see <http://www.gnu.org/licenses/>. */ #ifndef _PT_MACHINE_H #define _PT_MACHINE_H 1 diff --git a/libpthread/linuxthreads.old/sysdeps/arc/pt-machine.h b/libpthread/linuxthreads.old/sysdeps/arc/pt-machine.h new file mode 100644 index 000000000..8df1e77e3 --- /dev/null +++ b/libpthread/linuxthreads.old/sysdeps/arc/pt-machine.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2013 Synopsys, Inc. (www.synopsys.com) + * + * Licensed under the LGPL v2.1 or later, see the file COPYING.LIB in this tarball. + */ + +#ifndef _PT_MACHINE_H +#define _PT_MACHINE_H 1 +#include <features.h> + +#ifndef PT_EI +# define PT_EI __extern_always_inline +#endif + +extern long int testandset (int *spinlock); +extern int __compare_and_swap (long int *p, long int oldval, long int newval); + +PT_EI long int +testandset (int *spinlock) +{ + unsigned int old = 1; + + /* Atomically exchange @spinlock with 1 */ + __asm__ __volatile__( + "ex %0, [%1]" + : "+r" (old) + : "r" (spinlock) + : "memory"); + + return old; + +} + +/* Get some notion of the current stack. Need not be exactly the top + of the stack, just something somewhere in the current frame. + I don't trust register variables, so let's do this the safe way. */ +#define CURRENT_STACK_FRAME \ +__extension__ ({ char *__sp; __asm__ ("mov %0,sp" : "=r" (__sp)); __sp; }) + +#else +#error PT_MACHINE already defined +#endif /* pt-machine.h */ diff --git a/libpthread/linuxthreads.old/sysdeps/arm/pt-machine.h b/libpthread/linuxthreads.old/sysdeps/arm/pt-machine.h index 14eb6f6da..2b877f980 100644 --- a/libpthread/linuxthreads.old/sysdeps/arm/pt-machine.h +++ b/libpthread/linuxthreads.old/sysdeps/arm/pt-machine.h @@ -15,22 +15,40 @@ Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ + License along with the GNU C Library; see the file COPYING.LIB. If + not, see <http://www.gnu.org/licenses/>. */ #ifndef _PT_MACHINE_H #define _PT_MACHINE_H 1 -#include <features.h> +#include <sys/syscall.h> +#include <unistd.h> #ifndef PT_EI # define PT_EI __extern_always_inline #endif -/* This will not work on ARM1 or ARM2 because SWP is lacking on those - machines. Unfortunately we have no way to detect this at compile - time; let's hope nobody tries to use one. */ +#if defined(__thumb__) +#if defined(__USE_LDREXSTREX__) +PT_EI long int ldrex(int *spinlock) +{ + long int ret; + __asm__ __volatile__( + "ldrex %0, [%1]\n" + : "=r"(ret) + : "r"(spinlock) : "memory"); + return ret; +} + +PT_EI long int strex(int val, int *spinlock) +{ + long int ret; + __asm__ __volatile__( + "strex %0, %1, [%2]\n" + : "=r"(ret) + : "r" (val), "r"(spinlock) : "memory"); + return ret; +} /* Spinlock implementation; required. */ PT_EI long int @@ -38,7 +56,24 @@ testandset (int *spinlock) { register unsigned int ret; -#if defined(__thumb__) + do { + ret = ldrex(spinlock); + } while (strex(1, spinlock)); + + return ret; +} + +#else /* __USE_LDREXSTREX__ */ + +/* This will not work on ARM1 or ARM2 because SWP is lacking on those + machines. Unfortunately we have no way to detect this at compile + time; let's hope nobody tries to use one. */ + +/* Spinlock implementation; required. */ +PT_EI long int testandset (int *spinlock); +PT_EI long int testandset (int *spinlock) +{ + register unsigned int ret; void *pc; __asm__ __volatile__( ".align 0\n" @@ -51,15 +86,21 @@ testandset (int *spinlock) "\t.force_thumb" : "=r"(ret), "=r"(pc) : "0"(1), "r"(spinlock)); -#else + return ret; +} +#endif +#else /* __thumb__ */ + +PT_EI long int testandset (int *spinlock); +PT_EI long int testandset (int *spinlock) +{ + register unsigned int ret; __asm__ __volatile__("swp %0, %1, [%2]" : "=r"(ret) : "0"(1), "r"(spinlock)); -#endif - return ret; } - +#endif /* Get some notion of the current stack. Need not be exactly the top of the stack, just something somewhere in the current frame. */ diff --git a/libpthread/linuxthreads.old/sysdeps/avr32/pt-machine.h b/libpthread/linuxthreads.old/sysdeps/avr32/pt-machine.h index cd45d5faf..5735d0ea2 100644 --- a/libpthread/linuxthreads.old/sysdeps/avr32/pt-machine.h +++ b/libpthread/linuxthreads.old/sysdeps/avr32/pt-machine.h @@ -15,7 +15,7 @@ # define PT_EI __extern_always_inline #endif -static inline int +static __inline__ int _test_and_set (int *p, int v) { int result; diff --git a/libpthread/linuxthreads.old/sysdeps/bfin/pt-machine.h b/libpthread/linuxthreads.old/sysdeps/bfin/pt-machine.h index e81ecffbe..912d64b2c 100644 --- a/libpthread/linuxthreads.old/sysdeps/bfin/pt-machine.h +++ b/libpthread/linuxthreads.old/sysdeps/bfin/pt-machine.h @@ -15,8 +15,7 @@ You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; see the file COPYING.LIB. If - not, write to the Free Software Foundation, Inc., - 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + not, see <http://www.gnu.org/licenses/>. */ #ifndef _PT_MACHINE_H #define _PT_MACHINE_H 1 diff --git a/libpthread/linuxthreads.old/sysdeps/c6x/pt-machine.h b/libpthread/linuxthreads.old/sysdeps/c6x/pt-machine.h new file mode 100644 index 000000000..5e8bfca56 --- /dev/null +++ b/libpthread/linuxthreads.old/sysdeps/c6x/pt-machine.h @@ -0,0 +1,63 @@ +/* Machine-dependent pthreads configuration and inline functions. + C6x version. + Copyright (C) 2004 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Aurelien Jacquiot <aurelien.jacquiot@jaluna.com>. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; see the file COPYING.LIB. If + not, see <http://www.gnu.org/licenses/>. */ + +#ifndef _PT_MACHINE_H +#define _PT_MACHINE_H 1 + +#ifndef PT_EI +# define PT_EI extern inline +#endif + +extern int __compare_and_swap (long int *p, long int oldval, long int newval); + +/* Spinlock implementation; required. */ +static inline long int +testandset (int *spinlock) +{ + register unsigned int ret = 1; + int dummy; + __asm__ __volatile__ ("mvc .s2 CSR, %0\n\tand .s2 -2, %0, %0\n\tmvc .s2 %0, CSR\n" + : "=b" (dummy)); + + if (*spinlock == 0) { + *spinlock = 1; + ret = 0; + } + __asm__ __volatile__ ("mvc .s2 CSR, %0\n\tor .s2 1, %0, %0\n\tmvc .s2 %0, CSR\n" + : "=b" (dummy)); + return ret; +} + +#define WRITE_MEMORY_BARRIER() +#define READ_MEMORY_BARRIER() + +/* Get some notion of the current stack. Need not be exactly the top + of the stack, just something somewhere in the current frame. */ +#define CURRENT_STACK_FRAME get_stack_pointer() +static inline char * get_stack_pointer(void) +{ + char *sp; + __asm__ __volatile__ ("mv .d2 B15, %0" : "=b" (sp)); + return sp; +} + +#define THREAD_STACK_OFFSET 8 + +#endif /* pt-machine.h */ diff --git a/libpthread/linuxthreads.old/sysdeps/cris/pt-machine.h b/libpthread/linuxthreads.old/sysdeps/cris/pt-machine.h index 6d626fb4b..a89579ee0 100644 --- a/libpthread/linuxthreads.old/sysdeps/cris/pt-machine.h +++ b/libpthread/linuxthreads.old/sysdeps/cris/pt-machine.h @@ -15,8 +15,7 @@ You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ + see <http://www.gnu.org/licenses/>. */ #ifndef _PT_MACHINE_H #define _PT_MACHINE_H 1 diff --git a/libpthread/linuxthreads.old/sysdeps/frv/pt-machine.h b/libpthread/linuxthreads.old/sysdeps/frv/pt-machine.h index 9c9d0d76a..6f867ade7 100644 --- a/libpthread/linuxthreads.old/sysdeps/frv/pt-machine.h +++ b/libpthread/linuxthreads.old/sysdeps/frv/pt-machine.h @@ -16,8 +16,7 @@ You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; see the file COPYING.LIB. If - not, write to the Free Software Foundation, Inc., - 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + not, see <http://www.gnu.org/licenses/>. */ #ifndef _PT_MACHINE_H #define _PT_MACHINE_H 1 diff --git a/libpthread/linuxthreads.old/sysdeps/h8300/pt-machine.h b/libpthread/linuxthreads.old/sysdeps/h8300/pt-machine.h index 121f496d7..a37384de9 100644 --- a/libpthread/linuxthreads.old/sysdeps/h8300/pt-machine.h +++ b/libpthread/linuxthreads.old/sysdeps/h8300/pt-machine.h @@ -16,8 +16,7 @@ You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; see the file COPYING.LIB. If - not, write to the Free Software Foundation, Inc., - 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + not, see <http://www.gnu.org/licenses/>. */ #ifndef _PT_MACHINE_H #define _PT_MACHINE_H 1 diff --git a/libpthread/linuxthreads.old/sysdeps/hppa/pspinlock.c b/libpthread/linuxthreads.old/sysdeps/hppa/pspinlock.c new file mode 100644 index 000000000..1a6aa64a9 --- /dev/null +++ b/libpthread/linuxthreads.old/sysdeps/hppa/pspinlock.c @@ -0,0 +1,80 @@ +/* POSIX spinlock implementation. hppa version. + Copyright (C) 2000 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 + modify it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; see the file COPYING.LIB. If + not, see <http://www.gnu.org/licenses/>. */ + +#include <errno.h> +#include <pthread.h> +#include "internals.h" + +int +__pthread_spin_lock (pthread_spinlock_t *lock) +{ + unsigned int val; + + do + __asm__ __volatile__ ("ldcw %1,%0" + : "=r" (val), "=m" (*lock) + : "m" (*lock)); + while (!val); + + return 0; +} +weak_alias (__pthread_spin_lock, pthread_spin_lock) + + +int +__pthread_spin_trylock (pthread_spinlock_t *lock) +{ + unsigned int val; + + __asm__ __volatile__ ("ldcw %1,%0" + : "=r" (val), "=m" (*lock) + : "m" (*lock)); + + return val ? 0 : EBUSY; +} +weak_alias (__pthread_spin_trylock, pthread_spin_trylock) + + +int +__pthread_spin_unlock (pthread_spinlock_t *lock) +{ + *lock = 1; + return 0; +} +weak_alias (__pthread_spin_unlock, pthread_spin_unlock) + + +int +__pthread_spin_init (pthread_spinlock_t *lock, int pshared) +{ + /* We can ignore the `pshared' parameter. Since we are busy-waiting + all processes which can access the memory location `lock' points + to can use the spinlock. */ + *lock = 1; + return 0; +} +weak_alias (__pthread_spin_init, pthread_spin_init) + + +int +__pthread_spin_destroy (pthread_spinlock_t *lock) +{ + /* Nothing to do. */ + return 0; +} +weak_alias (__pthread_spin_destroy, pthread_spin_destroy) diff --git a/libpthread/linuxthreads.old/sysdeps/hppa/pt-machine.h b/libpthread/linuxthreads.old/sysdeps/hppa/pt-machine.h new file mode 100644 index 000000000..85c453c77 --- /dev/null +++ b/libpthread/linuxthreads.old/sysdeps/hppa/pt-machine.h @@ -0,0 +1,59 @@ +/* Machine-dependent pthreads configuration and inline functions. + hppa version. + Copyright (C) 2000, 2002, 2003 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Richard Henderson <rth@tamu.edu>. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; see the file COPYING.LIB. If + not, see <http://www.gnu.org/licenses/>. */ + +#ifndef _PT_MACHINE_H +#define _PT_MACHINE_H 1 + +#include <features.h> +#include <bits/initspin.h> + +#ifndef PT_EI +# define PT_EI __extern_always_inline +#endif + +/* Get some notion of the current stack. Need not be exactly the top + of the stack, just something somewhere in the current frame. */ +#define CURRENT_STACK_FRAME stack_pointer +register char * stack_pointer __asm__ ("%r30"); + + +/* The hppa only has one atomic read and modify memory operation, + load and clear, so hppa spinlocks must use zero to signify that + someone is holding the lock. */ + +#define xstr(s) str(s) +#define str(s) #s +/* Spinlock implementation; required. */ +PT_EI long int +testandset (int *spinlock) +{ + int ret; + + __asm__ __volatile__( + "ldcw 0(%2),%0" + : "=r"(ret), "=m"(*spinlock) + : "r"(spinlock)); + + return ret == 0; +} +#undef str +#undef xstr + +#endif /* pt-machine.h */ diff --git a/libpthread/linuxthreads.old/sysdeps/i386/pt-machine.h b/libpthread/linuxthreads.old/sysdeps/i386/pt-machine.h index a6256c58f..24c5e6c7c 100644 --- a/libpthread/linuxthreads.old/sysdeps/i386/pt-machine.h +++ b/libpthread/linuxthreads.old/sysdeps/i386/pt-machine.h @@ -15,9 +15,8 @@ Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ + License along with the GNU C Library; see the file COPYING.LIB. If + not, see <http://www.gnu.org/licenses/>. */ #ifndef _PT_MACHINE_H #define _PT_MACHINE_H 1 diff --git a/libpthread/linuxthreads.old/sysdeps/i386/tls.h b/libpthread/linuxthreads.old/sysdeps/i386/tls.h index 8534cab80..4469f0776 100644 --- a/libpthread/linuxthreads.old/sysdeps/i386/tls.h +++ b/libpthread/linuxthreads.old/sysdeps/i386/tls.h @@ -13,9 +13,8 @@ Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ #ifndef _TLS_H #define _TLS_H diff --git a/libpthread/linuxthreads.old/sysdeps/i386/useldt.h b/libpthread/linuxthreads.old/sysdeps/i386/useldt.h index ca5677cc9..02326729a 100644 --- a/libpthread/linuxthreads.old/sysdeps/i386/useldt.h +++ b/libpthread/linuxthreads.old/sysdeps/i386/useldt.h @@ -16,8 +16,7 @@ You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ + see <http://www.gnu.org/licenses/>. */ #ifndef __ASSEMBLER__ #include <stddef.h> /* For offsetof. */ diff --git a/libpthread/linuxthreads.old/sysdeps/ia64/pt-machine.h b/libpthread/linuxthreads.old/sysdeps/ia64/pt-machine.h index 668057a2a..f4c6be989 100644 --- a/libpthread/linuxthreads.old/sysdeps/ia64/pt-machine.h +++ b/libpthread/linuxthreads.old/sysdeps/ia64/pt-machine.h @@ -14,9 +14,8 @@ Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ + License along with the GNU C Library; see the file COPYING.LIB. If + not, see <http://www.gnu.org/licenses/>. */ #ifndef _PT_MACHINE_H #define _PT_MACHINE_H 1 diff --git a/libpthread/linuxthreads.old/sysdeps/ia64/tls.h b/libpthread/linuxthreads.old/sysdeps/ia64/tls.h index 81b41eb73..a78f0ec7a 100644 --- a/libpthread/linuxthreads.old/sysdeps/ia64/tls.h +++ b/libpthread/linuxthreads.old/sysdeps/ia64/tls.h @@ -13,9 +13,8 @@ Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ #ifndef _TLS_H #define _TLS_H diff --git a/libpthread/linuxthreads.old/sysdeps/m68k/pt-machine.h b/libpthread/linuxthreads.old/sysdeps/m68k/pt-machine.h index 295495baf..3be216524 100644 --- a/libpthread/linuxthreads.old/sysdeps/m68k/pt-machine.h +++ b/libpthread/linuxthreads.old/sysdeps/m68k/pt-machine.h @@ -16,8 +16,7 @@ You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; see the file COPYING.LIB. If - not, write to the Free Software Foundation, Inc., - 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + not, see <http://www.gnu.org/licenses/>. */ #ifndef _PT_MACHINE_H #define _PT_MACHINE_H 1 @@ -40,7 +39,7 @@ testandset (int *spinlock) #else "bset #7,%1; sne %0" #endif - : "=dm"(ret), "=m"(*spinlock) + : "=&dm"(ret), "=m"(*spinlock) : "m"(*spinlock) : "cc"); diff --git a/libpthread/linuxthreads.old/sysdeps/microblaze/pt-machine.h b/libpthread/linuxthreads.old/sysdeps/microblaze/pt-machine.h new file mode 100644 index 000000000..e8c03f9e5 --- /dev/null +++ b/libpthread/linuxthreads.old/sysdeps/microblaze/pt-machine.h @@ -0,0 +1,106 @@ +/* + * sysdeps/microblaze/pt-machine.h -- microblaze-specific pthread definitions + * + * Copyright (C) 2003 John Williams <jwilliams@itee.uq.edu.au> + * Copyright (C) 2002 NEC Electronics Corporation + * Copyright (C) 2002 Miles Bader <miles@gnu.org> + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License. See the file COPYING.LIB in the main + * directory of this archive for more details. + * + * Written by Miles Bader <miles@gnu.org> + */ + +#ifndef _PT_MACHINE_H +#define _PT_MACHINE_H 1 + +#include <features.h> + +#ifndef PT_EI +# define PT_EI extern inline +#endif + +extern long int testandset (int *spinlock); +extern int __compare_and_swap (long *ptr, long old, long new); + +/* Get some notion of the current stack. Need not be exactly the top + of the stack, just something somewhere in the current frame. */ +#define CURRENT_STACK_FRAME __stack_pointer +register char *__stack_pointer __asm__ ("r1"); + +#define HAS_COMPARE_AND_SWAP +#define HAS_COMPARE_AND_SWAP_WITH_RELEASE_SEMANTICS +#define IMPLEMENT_TAS_WITH_CAS + +/* Atomically: If *PTR == OLD, set *PTR to NEW and return true, + otherwise do nothing and return false. */ +PT_EI int __compare_and_swap (long *ptr, long old, long new) +{ + unsigned long psw; + + /* disable interrupts */ + /* This is ugly ugly ugly! */ + __asm__ __volatile__ ("mfs %0, rmsr;" + "andi r3, %0, ~2;" + "mts rmsr, r3;" + : "=&r" (psw) + : + : "r3"); + + if (likely (*ptr == old)) + { + *ptr = new; + __asm__ __volatile__ ("mts rmsr, %0;" :: "r" (psw)); /* re-enable */ + return 1; + } + else + { + __asm__ __volatile__ ("mts rmsr, %0;" :: "r" (psw)); /* re-enable */ + return 0; + } +} + +/* like above's __compare_and_swap() but it first syncs the memory + (This is also the difference between both functions in e.g. + ../powerpc/pt-machine.h) + Doing this additional sync fixes a hang of __pthread_alt_unlock() + (Falk Brettschneider <fbrettschneider@baumeroptronic.de>) */ +PT_EI int +__compare_and_swap_with_release_semantics (long *p, + long oldval, long newval) +{ + __asm__ __volatile__ ("" : : : "memory"); /*MEMORY_BARRIER ();*/ + return __compare_and_swap (p, oldval, newval); +} + + +#ifndef IMPLEMENT_TAS_WITH_CAS +/* Spinlock implementation; required. */ +PT_EI long int testandset (int *spinlock) +{ + unsigned psw; + + /* disable interrupts */ + __asm__ __volatile__ ("mfs %0, rmsr;" + "andi r3, %0, ~2;" + "mts rmsr, r3;" + : "=&r" (psw) + : + : "r3"); + + if (*spinlock) + { + /* Enable ints */ + __asm__ __volatile__ ("mts rmsr, %0;" :: "r" (psw)); + return 1; + } else { + *spinlock=1; + /* Enable ints */ + __asm__ __volatile__ ("mts rmsr, %0;" :: "r" (psw)); + return 0; + } +} + +#endif +#endif /* pt-machine.h */ diff --git a/libpthread/linuxthreads.old/sysdeps/microblaze/sigcontextinfo.h b/libpthread/linuxthreads.old/sysdeps/microblaze/sigcontextinfo.h new file mode 100644 index 000000000..f5408ad08 --- /dev/null +++ b/libpthread/linuxthreads.old/sysdeps/microblaze/sigcontextinfo.h @@ -0,0 +1,17 @@ +/* + * sysdeps/microblaze/sigcontextinfo.h -- microblaze-specific pthread signal definitions + * + * Copyright (C) 2002 NEC Electronics Corporation + * Copyright (C) 2002 Miles Bader <miles@gnu.org> + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License. See the file COPYING.LIB in the main + * directory of this archive for more details. + * + * Written by Miles Bader <miles@gnu.org> + */ + +#include <signal.h> + +#define SIGCONTEXT struct sigcontext * +#define SIGCONTEXT_EXTRA_ARGS diff --git a/libpthread/linuxthreads.old/sysdeps/mips/pt-machine.h b/libpthread/linuxthreads.old/sysdeps/mips/pt-machine.h index fb1cc0e6d..caaf9a7c0 100644 --- a/libpthread/linuxthreads.old/sysdeps/mips/pt-machine.h +++ b/libpthread/linuxthreads.old/sysdeps/mips/pt-machine.h @@ -18,8 +18,7 @@ You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; see the file COPYING.LIB. If - not, write to the Free Software Foundation, Inc., - 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + not, see <http://www.gnu.org/licenses/>. */ #ifndef _PT_MACHINE_H #define _PT_MACHINE_H 1 diff --git a/libpthread/linuxthreads.old/sysdeps/nios/pt-machine.h b/libpthread/linuxthreads.old/sysdeps/nios/pt-machine.h deleted file mode 100644 index 140455013..000000000 --- a/libpthread/linuxthreads.old/sysdeps/nios/pt-machine.h +++ /dev/null @@ -1,68 +0,0 @@ -/* Machine-dependent pthreads configuration and inline functions. - ARM version. - Copyright (C) 1997, 1998 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Philip Blundell <philb@gnu.org>. - - The GNU C 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. - - The GNU C 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 the GNU C Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -#ifndef _PT_MACHINE_H -#define _PT_MACHINE_H 1 - -#include <features.h> - -#ifndef PT_EI -# define PT_EI __extern_always_inline -#endif - -/* Spinlock implementation; required. */ -/* it is weird and dangerous to disable interrupt in userspace, but for nios - what else we can do before we have a swap like instruction? This is better - than nothing - */ -PT_EI long int -testandset (int *spinlock) -{ - unsigned int ret; - - __asm__ __volatile__("pfx 8\n\t" - "wrctl %1 ; disable interrupt\n\t" - "nop\n\t" - "nop\n\t" - "ld %0, [%2]\n\t" - "st [%2], %1\n\t" - "pfx 9\n\t" - "wrctl %1 ; enable interrupt\n\t" - "nop\n\t" - "nop\n\t" - : "=&r"(ret) - : "r"(1), "r"(spinlock) - : "memory"); - - return ret; -} - - -/* Get some notion of the current stack. Need not be exactly the top - of the stack, just something somewhere in the current frame. */ -#define CURRENT_STACK_FRAME stack_pointer -register char * stack_pointer __asm__ ("%sp"); - -/* nios needs more because of reg windows */ -#define THREAD_MANAGER_STACK_SIZE (32*1024) -#define STACK_SIZE (32*1024) - -#endif /* pt-machine.h */ diff --git a/libpthread/linuxthreads.old/sysdeps/nios2/pt-machine.h b/libpthread/linuxthreads.old/sysdeps/nios2/pt-machine.h index 061fa735e..e3260811b 100644 --- a/libpthread/linuxthreads.old/sysdeps/nios2/pt-machine.h +++ b/libpthread/linuxthreads.old/sysdeps/nios2/pt-machine.h @@ -15,8 +15,7 @@ You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; see the file COPYING.LIB. If - not, write to the Free Software Foundation, Inc., - 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + not, see <http://www.gnu.org/licenses/>. */ #ifndef _PT_MACHINE_H #define _PT_MACHINE_H 1 diff --git a/libpthread/linuxthreads.old/sysdeps/sh64/pt-machine.h b/libpthread/linuxthreads.old/sysdeps/or1k/pt-machine.h index b87448a75..c6c8ee470 100644 --- a/libpthread/linuxthreads.old/sysdeps/sh64/pt-machine.h +++ b/libpthread/linuxthreads.old/sysdeps/or1k/pt-machine.h @@ -1,23 +1,19 @@ -/* Cloned for uClibc by Paul Mundt, December 2003 */ -/* Modified by SuperH, Inc. September 2003 */ - /* Machine-dependent pthreads configuration and inline functions. - SuperH version. - Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc. + OpenRISC version. + Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. This file is part of the GNU C Library. - Contributed by Niibe Yutaka <gniibe@m17n.org>. The GNU C 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 + modify it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. The GNU C 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. + Lesser General Public License for more details. - You should have received a copy of the GNU Library General Public + You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ @@ -26,14 +22,34 @@ #define _PT_MACHINE_H 1 #include <features.h> +#include <sys/syscall.h> #ifndef PT_EI # define PT_EI __extern_always_inline #endif +PT_EI long int testandset(int*); + +#define OR1K_ATOMIC_XCHG 1 + +PT_EI long int +testandset (int *spinlock) +{ + int err; + int oldvalue = 1; + + err = INLINE_SYSCALL(or1k_atomic, 3, OR1K_ATOMIC_XCHG, spinlock, &oldvalue); + + return (oldvalue); +} + /* Get some notion of the current stack. Need not be exactly the top of the stack, just something somewhere in the current frame. */ -#define CURRENT_STACK_FRAME stack_pointer -register char * stack_pointer __asm__ ("r15"); - +#define CURRENT_STACK_FRAME stack_pointer() +static inline char *stack_pointer(void) +{ + unsigned long ret; + __asm__ __volatile__ ("l.ori %0, r1, 0" : "=r" (ret)); + return (char *)ret; +} #endif /* pt-machine.h */ diff --git a/libpthread/linuxthreads.old/sysdeps/powerpc/pt-machine.h b/libpthread/linuxthreads.old/sysdeps/powerpc/pt-machine.h index 561f8958e..aa2d206b0 100644 --- a/libpthread/linuxthreads.old/sysdeps/powerpc/pt-machine.h +++ b/libpthread/linuxthreads.old/sysdeps/powerpc/pt-machine.h @@ -15,8 +15,7 @@ You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; see the file COPYING.LIB. If - not, write to the Free Software Foundation, Inc., - 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + not, see <http://www.gnu.org/licenses/>. */ /* These routines are from Appendix G of the 'PowerPC 601 RISC Microprocessor User's Manual', by IBM and Motorola. */ diff --git a/libpthread/linuxthreads.old/sysdeps/pthread/bits/libc-lock.h b/libpthread/linuxthreads.old/sysdeps/pthread/bits/libc-lock.h index 740e793be..8833e343d 100644 --- a/libpthread/linuxthreads.old/sysdeps/pthread/bits/libc-lock.h +++ b/libpthread/linuxthreads.old/sysdeps/pthread/bits/libc-lock.h @@ -14,9 +14,8 @@ Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ + License along with the GNU C Library; see the file COPYING.LIB. If + not, see <http://www.gnu.org/licenses/>. */ #ifndef _BITS_LIBC_LOCK_H #define _BITS_LIBC_LOCK_H 1 @@ -30,7 +29,7 @@ /* Mutex type. */ #if defined(_LIBC) || defined(_IO_MTSAFE_IO) typedef pthread_mutex_t __libc_lock_t; -typedef struct { pthread_mutex_t mutex; } __libc_lock_recursive_t; +typedef pthread_mutex_t __libc_lock_recursive_t; # ifdef __USE_UNIX98 typedef pthread_rwlock_t __libc_rwlock_t; # else @@ -132,15 +131,39 @@ typedef pthread_key_t __libc_key_t; #define __libc_rwlock_init(NAME) \ (__libc_maybe_call (__pthread_rwlock_init, (&(NAME), NULL), 0)); +/* Same as last but this time we initialize an adaptive mutex. */ +#if defined _LIBC && !defined NOT_IN_libc && defined SHARED +#define __libc_lock_init_adaptive(NAME) \ + ({ \ + (NAME).__m_count = 0; \ + (NAME).__m_owner = NULL; \ + (NAME).__m_kind = PTHREAD_MUTEX_ADAPTIVE_NP; \ + (NAME).__m_lock.__status = 0; \ + (NAME).__m_lock.__spinlock = __LT_SPINLOCK_INIT; \ + 0; }) +#else +#define __libc_lock_init_adaptive(NAME) \ + do { \ + if (__pthread_mutex_init != NULL) \ + { \ + pthread_mutexattr_t __attr; \ + __pthread_mutexattr_init (&__attr); \ + __pthread_mutexattr_settype (&__attr, PTHREAD_MUTEX_ADAPTIVE_NP); \ + __pthread_mutex_init (&(NAME), &__attr); \ + __pthread_mutexattr_destroy (&__attr); \ + } \ + } while (0); +#endif + /* Same as last but this time we initialize a recursive mutex. */ #if defined _LIBC && !defined NOT_IN_libc && defined SHARED #define __libc_lock_init_recursive(NAME) \ ({ \ - (NAME).mutex.__m_count = 0; \ - (NAME).mutex.__m_owner = NULL; \ - (NAME).mutex.__m_kind = PTHREAD_MUTEX_RECURSIVE_NP; \ - (NAME).mutex.__m_lock.__status = 0; \ - (NAME).mutex.__m_lock.__spinlock = __LT_SPINLOCK_INIT; \ + (NAME).__m_count = 0; \ + (NAME).__m_owner = NULL; \ + (NAME).__m_kind = PTHREAD_MUTEX_RECURSIVE_NP; \ + (NAME).__m_lock.__status = 0; \ + (NAME).__m_lock.__spinlock = __LT_SPINLOCK_INIT; \ 0; }) #else #define __libc_lock_init_recursive(NAME) \ @@ -150,7 +173,7 @@ typedef pthread_key_t __libc_key_t; pthread_mutexattr_t __attr; \ __pthread_mutexattr_init (&__attr); \ __pthread_mutexattr_settype (&__attr, PTHREAD_MUTEX_RECURSIVE_NP); \ - __pthread_mutex_init (&(NAME).mutex, &__attr); \ + __pthread_mutex_init (&(NAME), &__attr); \ __pthread_mutexattr_destroy (&__attr); \ } \ } while (0); @@ -247,6 +270,7 @@ typedef pthread_key_t __libc_key_t; _pthread_cleanup_pop_restore (&_buffer, (DOIT)); \ } +#if 0 #define __libc_cleanup_push(fct, arg) \ { struct _pthread_cleanup_buffer _buffer; \ __libc_maybe_call (_pthread_cleanup_push, (&_buffer, (fct), (arg)), 0) @@ -254,6 +278,7 @@ typedef pthread_key_t __libc_key_t; #define __libc_cleanup_pop(execute) \ __libc_maybe_call (_pthread_cleanup_pop, (&_buffer, execute), 0); \ } +#endif /* Create thread-specific key. */ #define __libc_key_create(KEY, DESTRUCTOR) \ @@ -276,7 +301,7 @@ typedef pthread_key_t __libc_key_t; library. */ extern int __pthread_mutex_init (pthread_mutex_t *__mutex, - __const pthread_mutexattr_t *__mutex_attr); + const pthread_mutexattr_t *__mutex_attr); extern int __pthread_mutex_destroy (pthread_mutex_t *__mutex); @@ -295,7 +320,7 @@ extern int __pthread_mutexattr_settype (pthread_mutexattr_t *__attr, #ifdef __USE_UNIX98 extern int __pthread_rwlock_init (pthread_rwlock_t *__rwlock, - __const pthread_rwlockattr_t *__attr); + const pthread_rwlockattr_t *__attr); extern int __pthread_rwlock_destroy (pthread_rwlock_t *__rwlock); @@ -314,7 +339,7 @@ extern int __pthread_key_create (pthread_key_t *__key, void (*__destr_function) (void *)); extern int __pthread_setspecific (pthread_key_t __key, - __const void *__pointer); + const void *__pointer); extern void *__pthread_getspecific (pthread_key_t __key); @@ -351,7 +376,6 @@ weak_extern (BP_SYM (__pthread_key_create)) weak_extern (BP_SYM (__pthread_setspecific)) weak_extern (BP_SYM (__pthread_getspecific)) weak_extern (BP_SYM (__pthread_once)) -weak_extern (__pthread_initialize) weak_extern (__pthread_atfork) weak_extern (BP_SYM (_pthread_cleanup_push)) weak_extern (BP_SYM (_pthread_cleanup_pop)) @@ -376,7 +400,6 @@ weak_extern (BP_SYM (_pthread_cleanup_pop_restore)) # pragma weak __pthread_setspecific # pragma weak __pthread_getspecific # pragma weak __pthread_once -# pragma weak __pthread_initialize # pragma weak __pthread_atfork # pragma weak _pthread_cleanup_push_defer # pragma weak _pthread_cleanup_pop_restore diff --git a/libpthread/linuxthreads.old/sysdeps/pthread/bits/libc-tsd.h b/libpthread/linuxthreads.old/sysdeps/pthread/bits/libc-tsd.h index 2b889e621..97af75ebf 100644 --- a/libpthread/linuxthreads.old/sysdeps/pthread/bits/libc-tsd.h +++ b/libpthread/linuxthreads.old/sysdeps/pthread/bits/libc-tsd.h @@ -13,15 +13,12 @@ Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ + License along with the GNU C Library; see the file COPYING.LIB. If + not, see <http://www.gnu.org/licenses/>. */ #ifndef _BITS_LIBC_TSD_H #define _BITS_LIBC_TSD_H 1 -#include <libc-internal.h> - /* Fast thread-specific data internal to libc. */ enum __libc_tsd_key_t { _LIBC_TSD_KEY_MALLOC = 0, _LIBC_TSD_KEY_DL_ERROR, @@ -32,12 +29,11 @@ enum __libc_tsd_key_t { _LIBC_TSD_KEY_MALLOC = 0, _LIBC_TSD_KEY_CTYPE_TOUPPER, _LIBC_TSD_KEY_N }; -#include <sys/cdefs.h> -#include <tls.h> - +#include <features.h> #include <linuxthreads.old/internals.h> -#if defined(USE_TLS) && USE_TLS && HAVE___THREAD +#ifdef __UCLIBC_HAS_TLS__ +#include <tls.h> /* When __thread works, the generic definition is what we want. */ # include <sysdeps/generic/bits/libc-tsd.h> diff --git a/libpthread/linuxthreads.old/sysdeps/pthread/bits/pthreadtypes.h b/libpthread/linuxthreads.old/sysdeps/pthread/bits/pthreadtypes.h index faec63b06..3eb592919 100644 --- a/libpthread/linuxthreads.old/sysdeps/pthread/bits/pthreadtypes.h +++ b/libpthread/linuxthreads.old/sysdeps/pthread/bits/pthreadtypes.h @@ -19,6 +19,9 @@ #ifndef _BITS_PTHREADTYPES_H #define _BITS_PTHREADTYPES_H 1 +#define __need_size_t +#include <stddef.h> + #define __need_schedparam #include <bits/sched.h> diff --git a/libpthread/linuxthreads.old/sysdeps/pthread/not-cancel.h b/libpthread/linuxthreads.old/sysdeps/pthread/not-cancel.h new file mode 100644 index 000000000..bbdb0739c --- /dev/null +++ b/libpthread/linuxthreads.old/sysdeps/pthread/not-cancel.h @@ -0,0 +1,113 @@ +/* Uncancelable versions of cancelable interfaces. Linux version. + Copyright (C) 2003, 2006 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@redhat.com>, 2003. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <sys/types.h> +#include <sysdep.h> + +/* Uncancelable open. */ +#if defined __NR_openat && !defined __NR_open +#define open_not_cancel(name, flags, mode) \ + INLINE_SYSCALL (openat, 4, AT_FDCWD, (const char *) (name), \ + (flags), (mode)) +#define open_not_cancel_2(name, flags) \ + INLINE_SYSCALL (openat, 3, AT_FDCWD, (const char *) (name), \ + (flags)) +#else +#define open_not_cancel(name, flags, mode) \ + INLINE_SYSCALL (open, 3, (const char *) (name), (flags), (mode)) +#define open_not_cancel_2(name, flags) \ + INLINE_SYSCALL (open, 2, (const char *) (name), (flags)) +#endif + +/* Uncancelable openat. */ +#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt +extern int __openat_nocancel (int fd, const char *fname, int oflag, + mode_t mode) attribute_hidden; +extern int __openat64_nocancel (int fd, const char *fname, int oflag, + mode_t mode) attribute_hidden; +#else +# define __openat_nocancel(fd, fname, oflag, mode) \ + openat (fd, fname, oflag, mode) +# define __openat64_nocancel(fd, fname, oflag, mode) \ + openat64 (fd, fname, oflag, mode) +#endif + +#define openat_not_cancel(fd, fname, oflag, mode) \ + __openat_nocancel (fd, fname, oflag, mode) +#define openat_not_cancel_3(fd, fname, oflag) \ + __openat_nocancel (fd, fname, oflag, 0) +#define openat64_not_cancel(fd, fname, oflag, mode) \ + __openat64_nocancel (fd, fname, oflag, mode) +#define openat64_not_cancel_3(fd, fname, oflag) \ + __openat64_nocancel (fd, fname, oflag, 0) + +/* Uncancelable close. */ +#define close_not_cancel(fd) \ + INLINE_SYSCALL (close, 1, fd) +#define close_not_cancel_no_status(fd) \ + (void) ({ INTERNAL_SYSCALL_DECL (err); \ + INTERNAL_SYSCALL (close, err, 1, (fd)); }) + +/* Uncancelable read. */ +#define read_not_cancel(fd, buf, n) \ + INLINE_SYSCALL (read, 3, (fd), (buf), (n)) + +/* Uncancelable write. */ +#define write_not_cancel(fd, buf, n) \ + INLINE_SYSCALL (write, 3, (fd), (buf), (n)) + +/* Uncancelable writev. */ +#define writev_not_cancel_no_status(fd, iov, n) \ + (void) ({ INTERNAL_SYSCALL_DECL (err); \ + INTERNAL_SYSCALL (writev, err, 3, (fd), (iov), (n)); }) + +/* Uncancelable fcntl. */ +#define fcntl_not_cancel(fd, cmd, val) \ + __fcntl_nocancel (fd, cmd, val) + +/* Uncancelable waitpid. */ +#ifdef __NR_waitpid +# define waitpid_not_cancel(pid, stat_loc, options) \ + INLINE_SYSCALL (waitpid, 3, pid, stat_loc, options) +#else +# define waitpid_not_cancel(pid, stat_loc, options) \ + INLINE_SYSCALL (wait4, 4, pid, stat_loc, options, NULL) +#endif + +/* Uncancelable pause. */ +#ifdef __NR_pause +# define pause_not_cancel() \ + INLINE_SYSCALL (pause, 0) +#else +# define pause_not_cancel() \ + __pause_nocancel () +#endif + +/* Uncancelable nanosleep. */ +#ifdef __NR_nanosleep +# define nanosleep_not_cancel(requested_time, remaining) \ + INLINE_SYSCALL (nanosleep, 2, requested_time, remaining) +#else +# define nanosleep_not_cancel(requested_time, remaining) \ + __nanosleep_nocancel (requested_time, remaining) +#endif + +/* Uncancelable sigsuspend. */ +#define sigsuspend_not_cancel(set) \ + __sigsuspend_nocancel (set) diff --git a/libpthread/linuxthreads.old/sysdeps/pthread/pthread-functions.h b/libpthread/linuxthreads.old/sysdeps/pthread/pthread-functions.h index ce6d10fba..2afaa52e8 100644 --- a/libpthread/linuxthreads.old/sysdeps/pthread/pthread-functions.h +++ b/libpthread/linuxthreads.old/sysdeps/pthread/pthread-functions.h @@ -13,25 +13,28 @@ Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ #ifndef _PTHREAD_FUNCTIONS_H #define _PTHREAD_FUNCTIONS_H 1 #include <pthread.h> +#if 0 #include <setjmp.h> #include <linuxthreads.old/internals.h> struct fork_block; +#endif /* Data type shared with libc. The libc uses it to pass on calls to the thread functions. Wine pokes directly into this structure, so if possible avoid breaking it and append new hooks to the end. */ struct pthread_functions { +#if 0 pid_t (*ptr_pthread_fork) (struct fork_block *); +#endif int (*ptr_pthread_attr_destroy) (pthread_attr_t *); int (*ptr_pthread_attr_init) (pthread_attr_t *); int (*ptr_pthread_attr_getdetachstate) (const pthread_attr_t *, int *); @@ -68,26 +71,36 @@ struct pthread_functions pthread_t (*ptr_pthread_self) (void); int (*ptr_pthread_setcancelstate) (int, int *); int (*ptr_pthread_setcanceltype) (int, int *); +#if 0 void (*ptr_pthread_do_exit) (void *retval, char *currentframe); void (*ptr_pthread_cleanup_upto) (__jmp_buf target, char *targetframe); pthread_descr (*ptr_pthread_thread_self) (void); +#endif +#if !defined __UCLIBC_HAS_TLS__ && defined __UCLIBC_HAS_RPC__ int (*ptr_pthread_internal_tsd_set) (int key, const void *pointer); void * (*ptr_pthread_internal_tsd_get) (int key); void ** __attribute__ ((__const__)) (*ptr_pthread_internal_tsd_address) (int key); +#endif +#if 0 int (*ptr_pthread_sigaction) (int sig, const struct sigaction * act, struct sigaction *oact); int (*ptr_pthread_sigwait) (const sigset_t *set, int *sig); int (*ptr_pthread_raise) (int sig); +#endif int (*ptr_pthread_cond_timedwait) (pthread_cond_t *, pthread_mutex_t *, const struct timespec *); +#if 0 void (*ptr__pthread_cleanup_push) (struct _pthread_cleanup_buffer * buffer, void (*routine)(void *), void * arg); +#endif void (*ptr__pthread_cleanup_push_defer) (struct _pthread_cleanup_buffer * buffer, void (*routine)(void *), void * arg); +#if 0 void (*ptr__pthread_cleanup_pop) (struct _pthread_cleanup_buffer * buffer, int execute); +#endif void (*ptr__pthread_cleanup_pop_restore) (struct _pthread_cleanup_buffer * buffer, int execute); }; @@ -95,4 +108,6 @@ struct pthread_functions /* Variable in libc.so. */ extern struct pthread_functions __libc_pthread_functions attribute_hidden; +extern int * __libc_pthread_init (const struct pthread_functions *functions); + #endif /* pthread-functions.h */ diff --git a/libpthread/linuxthreads.old/sysdeps/pthread/pthread.h b/libpthread/linuxthreads.old/sysdeps/pthread/pthread.h index 870e37fa5..3c7044d8b 100644 --- a/libpthread/linuxthreads.old/sysdeps/pthread/pthread.h +++ b/libpthread/linuxthreads.old/sysdeps/pthread/pthread.h @@ -161,9 +161,9 @@ enum if ATTR is NULL), and call function START_ROUTINE with given arguments ARG. */ extern int pthread_create (pthread_t *__restrict __threadp, - __const pthread_attr_t *__restrict __attr, + const pthread_attr_t *__restrict __attr, void *(*__start_routine) (void *), - void *__restrict __arg) __THROW; + void *__restrict __arg) __THROWNL; /* Obtain the identifier of the current thread. */ extern pthread_t pthread_self (void) __THROW; @@ -179,6 +179,21 @@ extern void pthread_exit (void *__retval) __attribute__ ((__noreturn__)); is not NULL. */ extern int pthread_join (pthread_t __th, void **__thread_return); +#ifdef __USE_GNU +/* Check whether thread TH has terminated. If yes return the status of + the thread in *THREAD_RETURN, if THREAD_RETURN is not NULL. */ +extern int pthread_tryjoin_np (pthread_t __th, void **__thread_return) __THROW; + +/* Make calling thread wait for termination of the thread TH, but only + until TIMEOUT. The exit status of the thread is stored in + *THREAD_RETURN, if THREAD_RETURN is not NULL. + + This function is a cancellation point and therefore not marked with + __THROW. */ +extern int pthread_timedjoin_np (pthread_t __th, void **__thread_return, + __const struct timespec *__abstime); +#endif + /* Indicate that the thread TH is never to be joined with PTHREAD_JOIN. The resources of TH will therefore be freed immediately when it terminates, instead of waiting for another thread to perform PTHREAD_JOIN @@ -201,16 +216,16 @@ extern int pthread_attr_setdetachstate (pthread_attr_t *__attr, int __detachstate) __THROW; /* Return in *DETACHSTATE the `detachstate' attribute in *ATTR. */ -extern int pthread_attr_getdetachstate (__const pthread_attr_t *__attr, +extern int pthread_attr_getdetachstate (const pthread_attr_t *__attr, int *__detachstate) __THROW; /* Set scheduling parameters (priority, etc) in *ATTR according to PARAM. */ extern int pthread_attr_setschedparam (pthread_attr_t *__restrict __attr, - __const struct sched_param *__restrict + const struct sched_param *__restrict __param) __THROW; /* Return in *PARAM the scheduling parameters of *ATTR. */ -extern int pthread_attr_getschedparam (__const pthread_attr_t *__restrict +extern int pthread_attr_getschedparam (const pthread_attr_t *__restrict __attr, struct sched_param *__restrict __param) __THROW; @@ -220,7 +235,7 @@ extern int pthread_attr_setschedpolicy (pthread_attr_t *__attr, int __policy) __THROW; /* Return in *POLICY the scheduling policy of *ATTR. */ -extern int pthread_attr_getschedpolicy (__const pthread_attr_t *__restrict +extern int pthread_attr_getschedpolicy (const pthread_attr_t *__restrict __attr, int *__restrict __policy) __THROW; @@ -229,7 +244,7 @@ extern int pthread_attr_setinheritsched (pthread_attr_t *__attr, int __inherit) __THROW; /* Return in *INHERIT the scheduling inheritance mode of *ATTR. */ -extern int pthread_attr_getinheritsched (__const pthread_attr_t *__restrict +extern int pthread_attr_getinheritsched (const pthread_attr_t *__restrict __attr, int *__restrict __inherit) __THROW; @@ -238,7 +253,7 @@ extern int pthread_attr_setscope (pthread_attr_t *__attr, int __scope) __THROW; /* Return in *SCOPE the scheduling contention scope of *ATTR. */ -extern int pthread_attr_getscope (__const pthread_attr_t *__restrict __attr, +extern int pthread_attr_getscope (const pthread_attr_t *__restrict __attr, int *__restrict __scope) __THROW; #ifdef __USE_UNIX98 @@ -247,11 +262,12 @@ extern int pthread_attr_setguardsize (pthread_attr_t *__attr, size_t __guardsize) __THROW; /* Get the size of the guard area at the bottom of the thread. */ -extern int pthread_attr_getguardsize (__const pthread_attr_t *__restrict +extern int pthread_attr_getguardsize (const pthread_attr_t *__restrict __attr, size_t *__restrict __guardsize) __THROW; #endif +#if 0 /* uClibc: deprecated stuff disabled. def __UCLIBC_SUSV3_LEGACY__ */ /* Set the starting address of the stack of the thread to be created. Depending on whether the stack grows up or down the value must either be higher or lower than all the address in the memory block. The @@ -260,9 +276,10 @@ extern int pthread_attr_setstackaddr (pthread_attr_t *__attr, void *__stackaddr) __THROW; /* Return the previously set address for the stack. */ -extern int pthread_attr_getstackaddr (__const pthread_attr_t *__restrict +extern int pthread_attr_getstackaddr (const pthread_attr_t *__restrict __attr, void **__restrict __stackaddr) __THROW; +#endif #ifdef __USE_XOPEN2K /* The following two interfaces are intended to replace the last two. They @@ -272,7 +289,7 @@ extern int pthread_attr_setstack (pthread_attr_t *__attr, void *__stackaddr, size_t __stacksize) __THROW; /* Return the previously set address for the stack. */ -extern int pthread_attr_getstack (__const pthread_attr_t *__restrict __attr, +extern int pthread_attr_getstack (const pthread_attr_t *__restrict __attr, void **__restrict __stackaddr, size_t *__restrict __stacksize) __THROW; #endif @@ -284,7 +301,7 @@ extern int pthread_attr_setstacksize (pthread_attr_t *__attr, size_t __stacksize) __THROW; /* Return the currently used minimal stack size. */ -extern int pthread_attr_getstacksize (__const pthread_attr_t *__restrict +extern int pthread_attr_getstacksize (const pthread_attr_t *__restrict __attr, size_t *__restrict __stacksize) __THROW; @@ -293,7 +310,7 @@ extern int pthread_attr_getstacksize (__const pthread_attr_t *__restrict #ifdef __USE_GNU /* Initialize thread attribute *ATTR with attributes corresponding to the - already running thread TH. It shall be called on unitialized ATTR + already running thread TH. It shall be called on uninitialized ATTR and destroyed with pthread_attr_destroy when no longer needed. */ extern int pthread_getattr_np (pthread_t __th, pthread_attr_t *__attr) __THROW; #endif @@ -304,7 +321,7 @@ extern int pthread_getattr_np (pthread_t __th, pthread_attr_t *__attr) __THROW; /* Set the scheduling parameters for TARGET_THREAD according to POLICY and *PARAM. */ extern int pthread_setschedparam (pthread_t __target_thread, int __policy, - __const struct sched_param *__param) + const struct sched_param *__param) __THROW; /* Return in *POLICY and *PARAM the scheduling parameters for TARGET_THREAD. */ @@ -321,32 +338,37 @@ extern int pthread_getconcurrency (void) __THROW; extern int pthread_setconcurrency (int __level) __THROW; #endif +#ifdef __USE_GNU +/* Same thing, different name */ +#define pthread_yield() sched_yield() +#endif + /* Functions for mutex handling. */ /* Initialize MUTEX using attributes in *MUTEX_ATTR, or use the default values if later is NULL. */ extern int pthread_mutex_init (pthread_mutex_t *__restrict __mutex, - __const pthread_mutexattr_t *__restrict + const pthread_mutexattr_t *__restrict __mutex_attr) __THROW; /* Destroy MUTEX. */ extern int pthread_mutex_destroy (pthread_mutex_t *__mutex) __THROW; /* Try to lock MUTEX. */ -extern int pthread_mutex_trylock (pthread_mutex_t *__mutex) __THROW; +extern int pthread_mutex_trylock (pthread_mutex_t *__mutex) __THROWNL; /* Wait until lock for MUTEX becomes available and lock it. */ -extern int pthread_mutex_lock (pthread_mutex_t *__mutex) __THROW; +extern int pthread_mutex_lock (pthread_mutex_t *__mutex) __THROWNL; #ifdef __USE_XOPEN2K /* Wait until lock becomes available, or specified time passes. */ extern int pthread_mutex_timedlock (pthread_mutex_t *__restrict __mutex, - __const struct timespec *__restrict - __abstime) __THROW; + const struct timespec *__restrict + __abstime) __THROWNL; #endif /* Unlock MUTEX. */ -extern int pthread_mutex_unlock (pthread_mutex_t *__mutex) __THROW; +extern int pthread_mutex_unlock (pthread_mutex_t *__mutex) __THROWNL; /* Functions for handling mutex attributes. */ @@ -359,7 +381,7 @@ extern int pthread_mutexattr_init (pthread_mutexattr_t *__attr) __THROW; extern int pthread_mutexattr_destroy (pthread_mutexattr_t *__attr) __THROW; /* Get the process-shared flag of the mutex attribute ATTR. */ -extern int pthread_mutexattr_getpshared (__const pthread_mutexattr_t * +extern int pthread_mutexattr_getpshared (const pthread_mutexattr_t * __restrict __attr, int *__restrict __pshared) __THROW; @@ -375,7 +397,7 @@ extern int pthread_mutexattr_settype (pthread_mutexattr_t *__attr, int __kind) __THROW; /* Return in *KIND the mutex kind attribute in *ATTR. */ -extern int pthread_mutexattr_gettype (__const pthread_mutexattr_t *__restrict +extern int pthread_mutexattr_gettype (const pthread_mutexattr_t *__restrict __attr, int *__restrict __kind) __THROW; #endif @@ -385,22 +407,27 @@ extern int pthread_mutexattr_gettype (__const pthread_mutexattr_t *__restrict /* Initialize condition variable COND using attributes ATTR, or use the default values if later is NULL. */ extern int pthread_cond_init (pthread_cond_t *__restrict __cond, - __const pthread_condattr_t *__restrict + const pthread_condattr_t *__restrict __cond_attr) __THROW; +libpthread_hidden_proto(pthread_cond_init) /* Destroy condition variable COND. */ extern int pthread_cond_destroy (pthread_cond_t *__cond) __THROW; +libpthread_hidden_proto(pthread_cond_destroy) /* Wake up one thread waiting for condition variable COND. */ -extern int pthread_cond_signal (pthread_cond_t *__cond) __THROW; +extern int pthread_cond_signal (pthread_cond_t *__cond) __THROWNL; +libpthread_hidden_proto(pthread_cond_signal) /* Wake up all threads waiting for condition variables COND. */ -extern int pthread_cond_broadcast (pthread_cond_t *__cond) __THROW; +extern int pthread_cond_broadcast (pthread_cond_t *__cond) __THROWNL; +libpthread_hidden_proto(pthread_cond_broadcast) /* Wait for condition variable COND to be signaled or broadcast. MUTEX is assumed to be locked before. */ extern int pthread_cond_wait (pthread_cond_t *__restrict __cond, pthread_mutex_t *__restrict __mutex); +libpthread_hidden_proto(pthread_cond_wait) /* Wait for condition variable COND to be signaled or broadcast until ABSTIME. MUTEX is assumed to be locked before. ABSTIME is an @@ -408,19 +435,22 @@ extern int pthread_cond_wait (pthread_cond_t *__restrict __cond, (00:00:00 GMT, January 1, 1970). */ extern int pthread_cond_timedwait (pthread_cond_t *__restrict __cond, pthread_mutex_t *__restrict __mutex, - __const struct timespec *__restrict + const struct timespec *__restrict __abstime); +libpthread_hidden_proto(pthread_cond_timedwait) /* Functions for handling condition variable attributes. */ /* Initialize condition variable attribute ATTR. */ extern int pthread_condattr_init (pthread_condattr_t *__attr) __THROW; +libpthread_hidden_proto(pthread_condattr_init) /* Destroy condition variable attribute ATTR. */ extern int pthread_condattr_destroy (pthread_condattr_t *__attr) __THROW; +libpthread_hidden_proto(pthread_condattr_destroy) /* Get the process-shared flag of the condition variable attribute ATTR. */ -extern int pthread_condattr_getpshared (__const pthread_condattr_t * +extern int pthread_condattr_getpshared (const pthread_condattr_t * __restrict __attr, int *__restrict __pshared) __THROW; @@ -435,40 +465,40 @@ extern int pthread_condattr_setpshared (pthread_condattr_t *__attr, /* Initialize read-write lock RWLOCK using attributes ATTR, or use the default values if later is NULL. */ extern int pthread_rwlock_init (pthread_rwlock_t *__restrict __rwlock, - __const pthread_rwlockattr_t *__restrict + const pthread_rwlockattr_t *__restrict __attr) __THROW; /* Destroy read-write lock RWLOCK. */ extern int pthread_rwlock_destroy (pthread_rwlock_t *__rwlock) __THROW; /* Acquire read lock for RWLOCK. */ -extern int pthread_rwlock_rdlock (pthread_rwlock_t *__rwlock) __THROW; +extern int pthread_rwlock_rdlock (pthread_rwlock_t *__rwlock) __THROWNL; /* Try to acquire read lock for RWLOCK. */ -extern int pthread_rwlock_tryrdlock (pthread_rwlock_t *__rwlock) __THROW; +extern int pthread_rwlock_tryrdlock (pthread_rwlock_t *__rwlock) __THROWNL; # ifdef __USE_XOPEN2K /* Try to acquire read lock for RWLOCK or return after specfied time. */ extern int pthread_rwlock_timedrdlock (pthread_rwlock_t *__restrict __rwlock, - __const struct timespec *__restrict - __abstime) __THROW; + const struct timespec *__restrict + __abstime) __THROWNL; # endif /* Acquire write lock for RWLOCK. */ -extern int pthread_rwlock_wrlock (pthread_rwlock_t *__rwlock) __THROW; +extern int pthread_rwlock_wrlock (pthread_rwlock_t *__rwlock) __THROWNL; /* Try to acquire write lock for RWLOCK. */ -extern int pthread_rwlock_trywrlock (pthread_rwlock_t *__rwlock) __THROW; +extern int pthread_rwlock_trywrlock (pthread_rwlock_t *__rwlock) __THROWNL; # ifdef __USE_XOPEN2K /* Try to acquire write lock for RWLOCK or return after specfied time. */ extern int pthread_rwlock_timedwrlock (pthread_rwlock_t *__restrict __rwlock, - __const struct timespec *__restrict - __abstime) __THROW; + const struct timespec *__restrict + __abstime) __THROWNL; # endif /* Unlock RWLOCK. */ -extern int pthread_rwlock_unlock (pthread_rwlock_t *__rwlock) __THROW; +extern int pthread_rwlock_unlock (pthread_rwlock_t *__rwlock) __THROWNL; /* Functions for handling read-write lock attributes. */ @@ -480,7 +510,7 @@ extern int pthread_rwlockattr_init (pthread_rwlockattr_t *__attr) __THROW; extern int pthread_rwlockattr_destroy (pthread_rwlockattr_t *__attr) __THROW; /* Return current setting of process-shared attribute of ATTR in PSHARED. */ -extern int pthread_rwlockattr_getpshared (__const pthread_rwlockattr_t * +extern int pthread_rwlockattr_getpshared (const pthread_rwlockattr_t * __restrict __attr, int *__restrict __pshared) __THROW; @@ -489,7 +519,7 @@ extern int pthread_rwlockattr_setpshared (pthread_rwlockattr_t *__attr, int __pshared) __THROW; /* Return current setting of reader/writer preference. */ -extern int pthread_rwlockattr_getkind_np (__const pthread_rwlockattr_t *__attr, +extern int pthread_rwlockattr_getkind_np (const pthread_rwlockattr_t *__attr, int *__pref) __THROW; /* Set reader/write preference. */ @@ -513,19 +543,19 @@ extern int pthread_spin_init (pthread_spinlock_t *__lock, int __pshared) extern int pthread_spin_destroy (pthread_spinlock_t *__lock) __THROW; /* Wait until spinlock LOCK is retrieved. */ -extern int pthread_spin_lock (pthread_spinlock_t *__lock) __THROW; +extern int pthread_spin_lock (pthread_spinlock_t *__lock) __THROWNL; /* Try to lock spinlock LOCK. */ -extern int pthread_spin_trylock (pthread_spinlock_t *__lock) __THROW; +extern int pthread_spin_trylock (pthread_spinlock_t *__lock) __THROWNL; /* Release spinlock LOCK. */ -extern int pthread_spin_unlock (pthread_spinlock_t *__lock) __THROW; +extern int pthread_spin_unlock (pthread_spinlock_t *__lock) __THROWNL; /* Barriers are a also a new feature in 1003.1j-2000. */ extern int pthread_barrier_init (pthread_barrier_t *__restrict __barrier, - __const pthread_barrierattr_t *__restrict + const pthread_barrierattr_t *__restrict __attr, unsigned int __count) __THROW; extern int pthread_barrier_destroy (pthread_barrier_t *__barrier) __THROW; @@ -534,14 +564,14 @@ extern int pthread_barrierattr_init (pthread_barrierattr_t *__attr) __THROW; extern int pthread_barrierattr_destroy (pthread_barrierattr_t *__attr) __THROW; -extern int pthread_barrierattr_getpshared (__const pthread_barrierattr_t * +extern int pthread_barrierattr_getpshared (const pthread_barrierattr_t * __restrict __attr, int *__restrict __pshared) __THROW; extern int pthread_barrierattr_setpshared (pthread_barrierattr_t *__attr, int __pshared) __THROW; -extern int pthread_barrier_wait (pthread_barrier_t *__barrier) __THROW; +extern int pthread_barrier_wait (pthread_barrier_t *__barrier) __THROWNL; #endif #endif @@ -562,7 +592,7 @@ extern int pthread_key_delete (pthread_key_t __key) __THROW; /* Store POINTER in the thread-specific data slot identified by KEY. */ extern int pthread_setspecific (pthread_key_t __key, - __const void *__pointer) __THROW; + const void *__pointer) __THROW; /* Return current value of the thread-specific data slot identified by KEY. */ extern void *pthread_getspecific (pthread_key_t __key) __THROW; diff --git a/libpthread/linuxthreads.old/sysdeps/pthread/tls.h b/libpthread/linuxthreads.old/sysdeps/pthread/tls.h index 6a23ec05e..2068f1e77 100644 --- a/libpthread/linuxthreads.old/sysdeps/pthread/tls.h +++ b/libpthread/linuxthreads.old/sysdeps/pthread/tls.h @@ -13,9 +13,8 @@ Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ /* By default no TLS support is available. This is signaled by the absence of the symbol USE_TLS. */ diff --git a/libpthread/linuxthreads.old/sysdeps/sh/pt-machine.h b/libpthread/linuxthreads.old/sysdeps/sh/pt-machine.h index 793f80b2d..7d1484e71 100644 --- a/libpthread/linuxthreads.old/sysdeps/sh/pt-machine.h +++ b/libpthread/linuxthreads.old/sysdeps/sh/pt-machine.h @@ -15,9 +15,8 @@ Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ + License along with the GNU C Library; see the file COPYING.LIB. If + not, see <http://www.gnu.org/licenses/>. */ #ifndef _PT_MACHINE_H #define _PT_MACHINE_H 1 diff --git a/libpthread/linuxthreads.old/sysdeps/sh/tls.h b/libpthread/linuxthreads.old/sysdeps/sh/tls.h index 7bc29800a..25bef830f 100644 --- a/libpthread/linuxthreads.old/sysdeps/sh/tls.h +++ b/libpthread/linuxthreads.old/sysdeps/sh/tls.h @@ -13,9 +13,8 @@ Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ #ifndef _TLS_H #define _TLS_H diff --git a/libpthread/linuxthreads.old/sysdeps/sh64/Makefile.arch b/libpthread/linuxthreads.old/sysdeps/sh64/Makefile.arch deleted file mode 100644 index e4cb95b76..000000000 --- a/libpthread/linuxthreads.old/sysdeps/sh64/Makefile.arch +++ /dev/null @@ -1,30 +0,0 @@ -# Makefile for uClibc -# -# Copyright (C) 2003 Paul Mundt <lethal@linux-sh.org> -# Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org> -# -# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. -# - -libpthread_ARCH_DIR:=$(top_srcdir)libpthread/linuxthreads.old/sysdeps/sh64 -libpthread_ARCH_OUT:=$(top_builddir)libpthread/linuxthreads.old/sysdeps/sh64 - -libpthread_ARCH_SRC:=$(wildcard $(libpthread_ARCH_DIR)/*.c) -libpthread_ARCH_OBJ:=$(patsubst $(libpthread_ARCH_DIR)/%.c,$(libpthread_ARCH_OUT)/%.o,$(libpthread_ARCH_SRC)) - -libpthread-a-y+=$(libpthread_ARCH_OBJ) -libpthread-so-y+=$(libpthread_ARCH_OBJ:.o=.os) - -libpthread-multi-y+=$(libpthread_ARCH_SRC) - -objclean-y+=libpthread_arch_objclean - -# We need to build as SHcompact for tas.. -$(libpthread_ARCH_OBJ): %.o : %.c - $(compile.c:32media=compact) - -$(libpthread_ARCH_OBJ:.o=.os): %.os : %.c - $(compile.c:32media=compact) - -libpthread_arch_objclean: - $(RM) $(libpthread_ARCH_OUT)/*.{o,os} diff --git a/libpthread/linuxthreads.old/sysdeps/sh64/pt-machine.c b/libpthread/linuxthreads.old/sysdeps/sh64/pt-machine.c deleted file mode 100644 index bd2c401fc..000000000 --- a/libpthread/linuxthreads.old/sysdeps/sh64/pt-machine.c +++ /dev/null @@ -1,47 +0,0 @@ -/* Cloned for uClibc by Paul Mundt, December 2003 */ -/* Modified by SuperH, Inc. September 2003 */ - -/* Machine-dependent pthreads configuration and inline functions. - SH5 version. - Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Niibe Yutaka <gniibe@m17n.org>. - - The GNU C 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. - - The GNU C 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 the GNU C Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -#include "pt-machine.h" - -/* Spinlock implementation; required. */ - -/* The SH5 does not have a suitable test-and-set instruction (SWAP only - operates on an aligned quad word). So we use the SH4 version instead. - This must be seperately compiled in SHcompact mode, so it cannot be - inline. */ - -long int testandset (int *spinlock) -{ - int ret; - - __asm__ __volatile__( - "tas.b @%1\n\t" - "movt %0" - : "=r" (ret) - : "r" (spinlock) - : "memory", "cc"); - - return (ret == 0); -} - diff --git a/libpthread/linuxthreads.old/sysdeps/sparc/pt-machine.h b/libpthread/linuxthreads.old/sysdeps/sparc/pt-machine.h index ab90810f1..d502c759a 100644 --- a/libpthread/linuxthreads.old/sysdeps/sparc/pt-machine.h +++ b/libpthread/linuxthreads.old/sysdeps/sparc/pt-machine.h @@ -1,8 +1,82 @@ -#include <features.h> -#include <bits/wordsize.h> +/* Machine-dependent pthreads configuration and inline functions. + sparc version. + Copyright (C) 1996-1998, 2000-2003 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Richard Henderson <rth@tamu.edu>. -#if __WORDSIZE == 32 -# include "sparc32/pt-machine.h" -#else -# include "sparc64/pt-machine.h" + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; see the file COPYING.LIB. If + not, see <http://www.gnu.org/licenses/>. */ + +#ifndef _PT_MACHINE_H +#define _PT_MACHINE_H 1 + +#ifndef PT_EI +# define PT_EI __extern_always_inline #endif + +extern long int testandset (int *spinlock); +extern int __compare_and_swap (long int *p, long int oldval, long int newval); + +/* Spinlock implementation; required. */ +PT_EI long int +testandset (int *spinlock) +{ + int ret; + + __asm__ __volatile__("ldstub %1,%0" + : "=r"(ret), "=m"(*spinlock) + : "m"(*spinlock)); + + return ret; +} + + +/* Memory barrier; default is to do nothing */ +#define MEMORY_BARRIER() __asm__ __volatile__("stbar" : : : "memory") + + +/* Get some notion of the current stack. Need not be exactly the top + of the stack, just something somewhere in the current frame. */ +#define CURRENT_STACK_FRAME (stack_pointer + (2 * 64)) +register char *stack_pointer __asm__("%sp"); + + +/* Registers %g6 and %g7 are reserved by the ABI for "system use". + %g7 is specified in the TLS ABI as thread pointer -- we do the same. */ +struct _pthread_descr_struct; +register struct _pthread_descr_struct *__thread_self __asm__("%g7"); + +/* Return the thread descriptor for the current thread. */ +#define THREAD_SELF __thread_self + +/* Initialize the thread-unique value. */ +#define INIT_THREAD_SELF(descr, nr) (__thread_self = (descr)) + +/* Access to data in the thread descriptor is easy. */ +#define THREAD_GETMEM(descr, member) \ + ((void) sizeof (descr), THREAD_SELF->member) +#define THREAD_GETMEM_NC(descr, member) \ + ((void) sizeof (descr), THREAD_SELF->member) +#define THREAD_SETMEM(descr, member, value) \ + ((void) sizeof (descr), THREAD_SELF->member = (value)) +#define THREAD_SETMEM_NC(descr, member, value) \ + ((void) sizeof (descr), THREAD_SELF->member = (value)) + +/* We want the OS to assign stack addresses. */ +#define FLOATING_STACKS 1 + +/* Maximum size of the stack if the rlimit is unlimited. */ +#define ARCH_STACK_MAX_SIZE 8*1024*1024 + +#endif /* pt-machine.h */ diff --git a/libpthread/linuxthreads.old/sysdeps/sparc/sparc32/pt-machine.h b/libpthread/linuxthreads.old/sysdeps/sparc/sparc32/pt-machine.h deleted file mode 100644 index 43c05f2a6..000000000 --- a/libpthread/linuxthreads.old/sysdeps/sparc/sparc32/pt-machine.h +++ /dev/null @@ -1,83 +0,0 @@ -/* Machine-dependent pthreads configuration and inline functions. - sparc version. - Copyright (C) 1996-1998, 2000-2003 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Richard Henderson <rth@tamu.edu>. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1 of the - License, or (at your option) any later version. - - The GNU C 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -#ifndef _PT_MACHINE_H -#define _PT_MACHINE_H 1 - -#ifndef PT_EI -# define PT_EI __extern_always_inline -#endif - -extern long int testandset (int *spinlock); -extern int __compare_and_swap (long int *p, long int oldval, long int newval); - -/* Spinlock implementation; required. */ -PT_EI long int -testandset (int *spinlock) -{ - int ret; - - __asm__ __volatile__("ldstub %1,%0" - : "=r"(ret), "=m"(*spinlock) - : "m"(*spinlock)); - - return ret; -} - - -/* Memory barrier; default is to do nothing */ -#define MEMORY_BARRIER() __asm__ __volatile__("stbar" : : : "memory") - - -/* Get some notion of the current stack. Need not be exactly the top - of the stack, just something somewhere in the current frame. */ -#define CURRENT_STACK_FRAME (stack_pointer + (2 * 64)) -register char *stack_pointer __asm__("%sp"); - - -/* Registers %g6 and %g7 are reserved by the ABI for "system use". - %g7 is specified in the TLS ABI as thread pointer -- we do the same. */ -struct _pthread_descr_struct; -register struct _pthread_descr_struct *__thread_self __asm__("%g7"); - -/* Return the thread descriptor for the current thread. */ -#define THREAD_SELF __thread_self - -/* Initialize the thread-unique value. */ -#define INIT_THREAD_SELF(descr, nr) (__thread_self = (descr)) - -/* Access to data in the thread descriptor is easy. */ -#define THREAD_GETMEM(descr, member) \ - ((void) sizeof (descr), THREAD_SELF->member) -#define THREAD_GETMEM_NC(descr, member) \ - ((void) sizeof (descr), THREAD_SELF->member) -#define THREAD_SETMEM(descr, member, value) \ - ((void) sizeof (descr), THREAD_SELF->member = (value)) -#define THREAD_SETMEM_NC(descr, member, value) \ - ((void) sizeof (descr), THREAD_SELF->member = (value)) - -/* We want the OS to assign stack addresses. */ -#define FLOATING_STACKS 1 - -/* Maximum size of the stack if the rlimit is unlimited. */ -#define ARCH_STACK_MAX_SIZE 8*1024*1024 - -#endif /* pt-machine.h */ diff --git a/libpthread/linuxthreads.old/sysdeps/sparc/sparc64/pt-machine.h b/libpthread/linuxthreads.old/sysdeps/sparc/sparc64/pt-machine.h deleted file mode 100644 index 815d70e8d..000000000 --- a/libpthread/linuxthreads.old/sysdeps/sparc/sparc64/pt-machine.h +++ /dev/null @@ -1,105 +0,0 @@ -/* Machine-dependent pthreads configuration and inline functions. - Sparc v9 version. - Copyright (C) 1997-2002, 2003 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Richard Henderson <rth@tamu.edu>. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1 of the - License, or (at your option) any later version. - - The GNU C 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; see the file COPYING.LIB. If - not, write to the Free Software Foundation, Inc., - 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#ifndef _PT_MACHINE_H -#define _PT_MACHINE_H 1 - -#ifndef PT_EI -# define PT_EI __extern_always_inline -#endif - -extern long int testandset (int *spinlock); -extern int __compare_and_swap (long int *p, long int oldval, long int newval); - -/* Spinlock implementation; required. */ -PT_EI long int -testandset (int *spinlock) -{ - int ret; - - __asm__ __volatile__("ldstub %1,%0" - : "=r" (ret), "=m" (*spinlock) : "m" (*spinlock)); - - return ret; -} - - -/* Memory barrier; default is to do nothing */ -#define MEMORY_BARRIER() \ - __asm__ __volatile__("membar #LoadLoad | #LoadStore | #StoreLoad | #StoreStore" : : : "memory") -/* Read barrier. */ -#define READ_MEMORY_BARRIER() \ - __asm__ __volatile__("membar #LoadLoad | #LoadStore" : : : "memory") -/* Write barrier. */ -#define WRITE_MEMORY_BARRIER() \ - __asm__ __volatile__("membar #StoreLoad | #StoreStore" : : : "memory") - - -/* Get some notion of the current stack. Need not be exactly the top - of the stack, just something somewhere in the current frame. */ -#define CURRENT_STACK_FRAME (stack_pointer + (2 * 128)) -register char *stack_pointer __asm__ ("%sp"); - - -/* Registers %g6 and %g7 are reserved by the ABI for "system use". The - TLS ABI specifies %g7 as the thread pointer. */ -struct _pthread_descr_struct; -register struct _pthread_descr_struct *__thread_self __asm__ ("%g7"); - -/* Return the thread descriptor for the current thread. */ -#define THREAD_SELF __thread_self - -/* Initialize the thread-unique value. */ -#define INIT_THREAD_SELF(descr, nr) (__thread_self = (descr)) - - -/* Compare-and-swap for semaphores. */ - -#define HAS_COMPARE_AND_SWAP -PT_EI int -__compare_and_swap (long int *p, long int oldval, long int newval) -{ - long int readval; - - __asm__ __volatile__ ("casx [%4], %2, %0" - : "=r"(readval), "=m"(*p) - : "r"(oldval), "m"(*p), "r"(p), "0"(newval)); - MEMORY_BARRIER(); - return readval == oldval; -} - -/* Access to data in the thread descriptor is easy. */ -#define THREAD_GETMEM(descr, member) \ - ((void) sizeof (descr), THREAD_SELF->member) -#define THREAD_GETMEM_NC(descr, member) \ - ((void) sizeof (descr), THREAD_SELF->member) -#define THREAD_SETMEM(descr, member, value) \ - ((void) sizeof (descr), THREAD_SELF->member = (value)) -#define THREAD_SETMEM_NC(descr, member, value) \ - ((void) sizeof (descr), THREAD_SELF->member = (value)) - -/* We want the OS to assign stack addresses. */ -#define FLOATING_STACKS 1 - -/* Maximum size of the stack if the rlimit is unlimited. */ -#define ARCH_STACK_MAX_SIZE 32*1024*1024 - -#endif /* pt-machine.h */ diff --git a/libpthread/linuxthreads.old/sysdeps/sparc/tcb-offsets.h b/libpthread/linuxthreads.old/sysdeps/sparc/tcb-offsets.h new file mode 100644 index 000000000..6d6f111f4 --- /dev/null +++ b/libpthread/linuxthreads.old/sysdeps/sparc/tcb-offsets.h @@ -0,0 +1 @@ +#include "../../../linuxthreads/sysdeps/pthread/tcb-offsets.h" diff --git a/libpthread/linuxthreads.old/sysdeps/v850/pt-machine.h b/libpthread/linuxthreads.old/sysdeps/v850/pt-machine.h deleted file mode 100644 index 34de63b9f..000000000 --- a/libpthread/linuxthreads.old/sysdeps/v850/pt-machine.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * sysdeps/v850/pt-machine.h -- v850-specific pthread definitions - * - * Copyright (C) 2002 NEC Electronics Corporation - * Copyright (C) 2002 Miles Bader <miles@gnu.org> - * - * This file is subject to the terms and conditions of the GNU Lesser - * General Public License. See the file COPYING.LIB in the main - * directory of this archive for more details. - * - * Written by Miles Bader <miles@gnu.org> - */ - -#ifndef _PT_MACHINE_H -#define _PT_MACHINE_H 1 - -#include <features.h> - -#ifndef PT_EI -# define PT_EI __extern_always_inline -#endif - -/* Get some notion of the current stack. Need not be exactly the top - of the stack, just something somewhere in the current frame. */ -#define CURRENT_STACK_FRAME __stack_pointer -register char *__stack_pointer __asm__ ("sp"); - -#define HAS_COMPARE_AND_SWAP - -/* Atomically: If *PTR == OLD, set *PTR to NEW and return true, - otherwise do nothing and return false. */ -PT_EI int -__compare_and_swap (long *ptr, long old, long new) -{ - unsigned long psw; - - /* disable interrupts */ - __asm__ __volatile__ ("stsr psw, %0; di" : "=&r" (psw)); - - if (likely (*ptr == old)) - { - *ptr = new; - __asm__ __volatile__ ("ldsr %0, psw" :: "r" (psw)); /* re-enable */ - return 1; - } - else - { - __asm__ __volatile__ ("ldsr %0, psw" :: "r" (psw)); /* re-enable */ - return 0; - } -} -#endif /* pt-machine.h */ diff --git a/libpthread/linuxthreads.old/sysdeps/x86_64/pt-machine.h b/libpthread/linuxthreads.old/sysdeps/x86_64/pt-machine.h index ce07bbb03..ed1fa30b1 100644 --- a/libpthread/linuxthreads.old/sysdeps/x86_64/pt-machine.h +++ b/libpthread/linuxthreads.old/sysdeps/x86_64/pt-machine.h @@ -14,9 +14,8 @@ Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ #ifndef _PT_MACHINE_H #define _PT_MACHINE_H 1 @@ -33,6 +32,9 @@ # define PT_EI __extern_always_inline # endif +extern long int testandset (int *); +extern int __compare_and_swap (long int *, long int, long int); + /* Get some notion of the current stack. Need not be exactly the top of the stack, just something somewhere in the current frame. */ # define CURRENT_STACK_FRAME stack_pointer diff --git a/libpthread/linuxthreads.old/sysdeps/x86_64/tls.h b/libpthread/linuxthreads.old/sysdeps/x86_64/tls.h index 5e7239d17..24ed3fca9 100644 --- a/libpthread/linuxthreads.old/sysdeps/x86_64/tls.h +++ b/libpthread/linuxthreads.old/sysdeps/x86_64/tls.h @@ -13,9 +13,8 @@ Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ #ifndef _TLS_H #define _TLS_H diff --git a/libpthread/linuxthreads.old/sysdeps/xtensa/pt-machine.h b/libpthread/linuxthreads.old/sysdeps/xtensa/pt-machine.h index acd4d109f..2c68ddfb5 100644 --- a/libpthread/linuxthreads.old/sysdeps/xtensa/pt-machine.h +++ b/libpthread/linuxthreads.old/sysdeps/xtensa/pt-machine.h @@ -15,9 +15,8 @@ Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 51 Franklin Street - Fifth Floor, - Boston, MA 02110-1301, USA. */ + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ #ifndef _PT_MACHINE_H #define _PT_MACHINE_H 1 @@ -26,19 +25,51 @@ #include <asm/unistd.h> #ifndef PT_EI -# define PT_EI __extern_always_inline +# define PT_EI extern inline __attribute__ ((gnu_inline)) #endif -/* Memory barrier. */ #define MEMORY_BARRIER() __asm__ ("memw" : : : "memory") +#define HAS_COMPARE_AND_SWAP + +extern long int testandset (int *spinlock); +extern int __compare_and_swap (long int *p, long int oldval, long int newval); /* Spinlock implementation; required. */ PT_EI long int testandset (int *spinlock) { - int unused = 0; - return INTERNAL_SYSCALL (xtensa, , 4, SYS_XTENSA_ATOMIC_SET, - spinlock, 1, unused); + unsigned long tmp; + __asm__ volatile ( +" movi %0, 0 \n" +" wsr %0, SCOMPARE1 \n" +" movi %0, 1 \n" +" s32c1i %0, %1, 0 \n" + : "=&a" (tmp) + : "a" (spinlock) + : "memory" + ); + return tmp; +} + +PT_EI int +__compare_and_swap (long int *p, long int oldval, long int newval) +{ + unsigned long tmp; + unsigned long value; + __asm__ volatile ( +"1: l32i %0, %2, 0 \n" +" bne %0, %4, 2f \n" +" wsr %0, SCOMPARE1 \n" +" mov %1, %0 \n" +" mov %0, %3 \n" +" s32c1i %0, %2, 0 \n" +" bne %1, %0, 1b \n" +"2: \n" + : "=&a" (tmp), "=&a" (value) + : "a" (p), "a" (newval), "a" (oldval) + : "memory" ); + + return tmp == oldval; } /* Get some notion of the current stack. Need not be exactly the top diff --git a/libpthread/linuxthreads.old/wrapsyscall.c b/libpthread/linuxthreads.old/wrapsyscall.c index 466589ef9..668b3911c 100644 --- a/libpthread/linuxthreads.old/wrapsyscall.c +++ b/libpthread/linuxthreads.old/wrapsyscall.c @@ -1,4 +1,4 @@ -/* Wrapper arpund system calls to provide cancelation points. +/* Wrapper around system calls to provide cancellation points. Copyright (C) 1996,1997,1998,1999,2000,2001 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996. @@ -15,11 +15,8 @@ You should have received a copy of the GNU Library General Public License along with the GNU C Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ + see <http://www.gnu.org/licenses/>. */ -#define __FORCE_GLIBC -#include <features.h> #include <fcntl.h> #include <sys/mman.h> #include <pthread.h> @@ -28,6 +25,7 @@ #include <stddef.h> #include <stdlib.h> #include <termios.h> +#include <sys/epoll.h> #include <sys/resource.h> #include <sys/wait.h> #include <sys/socket.h> @@ -37,39 +35,40 @@ #ifndef __PIC__ /* We need a hook to force this file to be linked in when static libpthread is used. */ -const int __pthread_provide_wrappers = 0; +const char __pthread_provide_wrappers = 0; #endif - -#define CANCELABLE_SYSCALL(res_type, name, param_list, params) \ -res_type __libc_##name param_list; \ -res_type \ -__attribute__ ((weak)) \ -name param_list \ -{ \ - res_type result; \ - int oldtype; \ - pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype); \ - result = __libc_##name params; \ - pthread_setcanceltype (oldtype, NULL); \ - return result; \ +/* Using private interface to libc (__libc_foo) to implement + * cancellable versions of some libc functions */ +#define CANCELABLE_SYSCALL(res_type, name, param_list, params) \ +res_type __libc_##name param_list; \ +res_type \ +__attribute__ ((weak)) \ +name param_list \ +{ \ + res_type result; \ + int oldtype; \ + pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype); \ + result = __libc_##name params; \ + pthread_setcanceltype (oldtype, NULL); \ + return result; \ } -#define CANCELABLE_SYSCALL_VA(res_type, name, param_list, params, last_arg) \ -res_type __libc_##name param_list; \ -res_type \ -__attribute__ ((weak)) \ -name param_list \ -{ \ - res_type result; \ - int oldtype; \ - va_list ap; \ - pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype); \ - va_start (ap, last_arg); \ - result = __libc_##name params; \ - va_end (ap); \ - pthread_setcanceltype (oldtype, NULL); \ - return result; \ +#define CANCELABLE_SYSCALL_VA(res_type, name, param_list, params, last_arg) \ +res_type __libc_##name param_list; \ +res_type \ +__attribute__ ((weak)) \ +name param_list \ +{ \ + res_type result; \ + int oldtype; \ + va_list ap; \ + pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype); \ + va_start (ap, last_arg); \ + result = __libc_##name params; \ + va_end (ap); \ + pthread_setcanceltype (oldtype, NULL); \ + return result; \ } @@ -81,6 +80,12 @@ CANCELABLE_SYSCALL (int, close, (int fd), (fd)) CANCELABLE_SYSCALL_VA (int, fcntl, (int fd, int cmd, ...), (fd, cmd, va_arg (ap, long int)), cmd) +#if defined __UCLIBC_HAS_LFS__ && __WORDSIZE == 32 +/* fcntl64(2). */ +CANCELABLE_SYSCALL_VA (int, fcntl64, (int fd, int cmd, ...), + (fd, cmd, va_arg (ap, long int)), cmd) +#endif + /* fsync(2). */ CANCELABLE_SYSCALL (int, fsync, (int fd), (fd)) @@ -183,7 +188,7 @@ libpthread_hidden_def(waitpid) CANCELABLE_SYSCALL (ssize_t, write, (int fd, const void *buf, size_t n), (fd, buf, n)) - +#if defined __UCLIBC_HAS_SOCKET__ /* The following system calls are thread cancellation points specified in XNS. */ @@ -225,3 +230,17 @@ CANCELABLE_SYSCALL (ssize_t, sendto, (int fd, const __ptr_t buf, size_t n, int flags, __CONST_SOCKADDR_ARG addr, socklen_t addr_len), (fd, buf, n, flags, addr, addr_len)) +#endif /* __UCLIBC_HAS_SOCKET__ */ + +#ifdef __UCLIBC_HAS_EPOLL__ +# include <sys/epoll.h> +# ifdef __NR_epoll_wait +CANCELABLE_SYSCALL (int, epoll_wait, (int epfd, struct epoll_event *events, int maxevents, int timeout), + (epfd, events, maxevents, timeout)) +# endif +# ifdef __NR_epoll_pwait +CANCELABLE_SYSCALL (int, epoll_pwait, (int epfd, struct epoll_event *events, int maxevents, int timeout, + const sigset_t *set), + (epfd, events, maxevents, timeout, set)) +# endif +#endif |
