diff options
Diffstat (limited to 'libpthread/linuxthreads.old')
-rw-r--r-- | libpthread/linuxthreads.old/Makefile.in | 5 | ||||
-rw-r--r-- | libpthread/linuxthreads.old/cancel.c | 46 | ||||
-rw-r--r-- | libpthread/linuxthreads.old/condvar.c | 8 | ||||
-rw-r--r-- | libpthread/linuxthreads.old/debug.h | 16 | ||||
-rw-r--r-- | libpthread/linuxthreads.old/internals.h | 16 | ||||
-rw-r--r-- | libpthread/linuxthreads.old/join.c | 21 | ||||
-rw-r--r-- | libpthread/linuxthreads.old/manager.c | 5 | ||||
-rw-r--r-- | libpthread/linuxthreads.old/oldsemaphore.c | 2 | ||||
-rw-r--r-- | libpthread/linuxthreads.old/pthread.c | 2 | ||||
-rw-r--r-- | libpthread/linuxthreads.old/ptlongjmp.c | 21 | ||||
-rw-r--r-- | libpthread/linuxthreads.old/queue.h | 1 | ||||
-rw-r--r-- | libpthread/linuxthreads.old/semaphore.c | 8 | ||||
-rw-r--r-- | libpthread/linuxthreads.old/spinlock.c | 2 | ||||
-rw-r--r-- | libpthread/linuxthreads.old/sysdeps/pthread/pthread.h | 3 | ||||
-rw-r--r-- | libpthread/linuxthreads.old/wrapsyscall.c | 2 |
15 files changed, 90 insertions, 68 deletions
diff --git a/libpthread/linuxthreads.old/Makefile.in b/libpthread/linuxthreads.old/Makefile.in index 6ebaa144b..9c152764f 100644 --- a/libpthread/linuxthreads.old/Makefile.in +++ b/libpthread/linuxthreads.old/Makefile.in @@ -11,11 +11,6 @@ CFLAGS-linuxthreads.old := $(CFLAGS-dir_linuxthreads.old) $(SSP_ALL_CFLAGS) CFLAGS-libpthread/linuxthreads.old/sysdeps/$(TARGET_ARCH)/ := $(CFLAGS-linuxthreads.old) -# This stuff will not compile without at least -O1 -# psm: can't handle this here, could maybe search for -O0 in CFLAGS -# and append -O1 if found -#CFLAGS:=$(CFLAGS:-O0=-O1) - ifeq ($(PTHREADS_DEBUG_SUPPORT),y) LDFLAGS-libpthread.so := $(LDFLAGS_NOSTRIP) -z defs else diff --git a/libpthread/linuxthreads.old/cancel.c b/libpthread/linuxthreads.old/cancel.c index 1356348a7..ac66c5855 100644 --- a/libpthread/linuxthreads.old/cancel.c +++ b/libpthread/linuxthreads.old/cancel.c @@ -25,6 +25,17 @@ #include <rpc/rpc.h> extern void __rpc_thread_destroy(void); #endif +#include <bits/stackinfo.h> + +#include <stdio.h> + +#ifdef _STACK_GROWS_DOWN +# define FRAME_LEFT(frame, other) ((char *) frame >= (char *) other) +#elif _STACK_GROWS_UP +# define FRAME_LEFT(frame, other) ((char *) frame <= (char *) other) +#else +# error "Define either _STACK_GROWS_DOWN or _STACK_GROWS_UP" +#endif int pthread_setcancelstate(int state, int * oldstate) @@ -37,7 +48,7 @@ int pthread_setcancelstate(int state, int * oldstate) if (THREAD_GETMEM(self, p_canceled) && THREAD_GETMEM(self, p_cancelstate) == PTHREAD_CANCEL_ENABLE && THREAD_GETMEM(self, p_canceltype) == PTHREAD_CANCEL_ASYNCHRONOUS) - pthread_exit(PTHREAD_CANCELED); + __pthread_do_exit(PTHREAD_CANCELED, CURRENT_STACK_FRAME); return 0; } @@ -51,7 +62,7 @@ int pthread_setcanceltype(int type, int * oldtype) if (THREAD_GETMEM(self, p_canceled) && THREAD_GETMEM(self, p_cancelstate) == PTHREAD_CANCEL_ENABLE && THREAD_GETMEM(self, p_canceltype) == PTHREAD_CANCEL_ASYNCHRONOUS) - pthread_exit(PTHREAD_CANCELED); + __pthread_do_exit(PTHREAD_CANCELED, CURRENT_STACK_FRAME); return 0; } @@ -62,6 +73,7 @@ int pthread_cancel(pthread_t thread) int dorestart = 0; pthread_descr th; pthread_extricate_if *pextricate; + int already_canceled; __pthread_lock(&handle->h_lock, NULL); if (invalid_handle(handle, thread)) { @@ -71,13 +83,15 @@ int pthread_cancel(pthread_t thread) th = handle->h_descr; - if (th->p_canceled) { + already_canceled = th->p_canceled; + th->p_canceled = 1; + + if (th->p_cancelstate == PTHREAD_CANCEL_DISABLE || already_canceled) { __pthread_unlock(&handle->h_lock); return 0; } pextricate = th->p_extricate; - th->p_canceled = 1; pid = th->p_pid; /* If the thread has registered an extrication interface, then @@ -115,7 +129,7 @@ void pthread_testcancel(void) pthread_descr self = thread_self(); if (THREAD_GETMEM(self, p_canceled) && THREAD_GETMEM(self, p_cancelstate) == PTHREAD_CANCEL_ENABLE) - pthread_exit(PTHREAD_CANCELED); + __pthread_do_exit(PTHREAD_CANCELED, CURRENT_STACK_FRAME); } void _pthread_cleanup_push(struct _pthread_cleanup_buffer * buffer, @@ -125,6 +139,8 @@ void _pthread_cleanup_push(struct _pthread_cleanup_buffer * buffer, buffer->__routine = routine; buffer->__arg = arg; buffer->__prev = THREAD_GETMEM(self, p_cleanup); + if (buffer->__prev != NULL && FRAME_LEFT (buffer, buffer->__prev)) + buffer->__prev = NULL; THREAD_SETMEM(self, p_cleanup, buffer); } @@ -144,6 +160,8 @@ void _pthread_cleanup_push_defer(struct _pthread_cleanup_buffer * buffer, buffer->__arg = arg; buffer->__canceltype = THREAD_GETMEM(self, p_canceltype); buffer->__prev = THREAD_GETMEM(self, p_cleanup); + if (buffer->__prev != NULL && FRAME_LEFT (buffer, buffer->__prev)) + buffer->__prev = NULL; THREAD_SETMEM(self, p_canceltype, PTHREAD_CANCEL_DEFERRED); THREAD_SETMEM(self, p_cleanup, buffer); } @@ -158,15 +176,27 @@ void _pthread_cleanup_pop_restore(struct _pthread_cleanup_buffer * buffer, if (THREAD_GETMEM(self, p_canceled) && THREAD_GETMEM(self, p_cancelstate) == PTHREAD_CANCEL_ENABLE && THREAD_GETMEM(self, p_canceltype) == PTHREAD_CANCEL_ASYNCHRONOUS) - pthread_exit(PTHREAD_CANCELED); + __pthread_do_exit(PTHREAD_CANCELED, CURRENT_STACK_FRAME); } -void __pthread_perform_cleanup(void) +void __pthread_perform_cleanup(char *currentframe) { pthread_descr self = thread_self(); struct _pthread_cleanup_buffer * c; + for (c = THREAD_GETMEM(self, p_cleanup); c != NULL; c = c->__prev) - c->__routine(c->__arg); + { +#if _STACK_GROWS_DOWN + if ((char *) c <= currentframe) + break; +#elif _STACK_GROWS_UP + if ((char *) c >= currentframe) + break; +#else +# error "Define either _STACK_GROWS_DOWN or _STACK_GROWS_UP" +#endif + c->__routine(c->__arg); + } #ifdef __UCLIBC_HAS_RPC__ /* And the TSD which needs special help. */ diff --git a/libpthread/linuxthreads.old/condvar.c b/libpthread/linuxthreads.old/condvar.c index 62df907c1..3d77f781a 100644 --- a/libpthread/linuxthreads.old/condvar.c +++ b/libpthread/linuxthreads.old/condvar.c @@ -93,7 +93,7 @@ int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex) if (already_canceled) { __pthread_set_own_extricate_if(self, 0); - pthread_exit(PTHREAD_CANCELED); + __pthread_do_exit(PTHREAD_CANCELED, CURRENT_STACK_FRAME); } __pthread_mutex_unlock(mutex); @@ -122,7 +122,7 @@ int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex) && THREAD_GETMEM(self, p_cancelstate) == PTHREAD_CANCEL_ENABLE) { THREAD_SETMEM(self, p_woken_by_cancel, 0); __pthread_mutex_lock(mutex); - pthread_exit(PTHREAD_CANCELED); + __pthread_do_exit(PTHREAD_CANCELED, CURRENT_STACK_FRAME); } /* Put back any resumes we caught that don't belong to us. */ @@ -168,7 +168,7 @@ pthread_cond_timedwait_relative(pthread_cond_t *cond, if (already_canceled) { __pthread_set_own_extricate_if(self, 0); - pthread_exit(PTHREAD_CANCELED); + __pthread_do_exit(PTHREAD_CANCELED, CURRENT_STACK_FRAME); } __pthread_mutex_unlock(mutex); @@ -216,7 +216,7 @@ pthread_cond_timedwait_relative(pthread_cond_t *cond, && THREAD_GETMEM(self, p_cancelstate) == PTHREAD_CANCEL_ENABLE) { THREAD_SETMEM(self, p_woken_by_cancel, 0); __pthread_mutex_lock(mutex); - pthread_exit(PTHREAD_CANCELED); + __pthread_do_exit(PTHREAD_CANCELED, CURRENT_STACK_FRAME); } /* Put back any resumes we caught that don't belong to us. */ diff --git a/libpthread/linuxthreads.old/debug.h b/libpthread/linuxthreads.old/debug.h index a2ac5113a..94b7c084b 100644 --- a/libpthread/linuxthreads.old/debug.h +++ b/libpthread/linuxthreads.old/debug.h @@ -29,9 +29,6 @@ # define DEBUG_PT #endif -/* include asserts for now */ -#define DO_ASSERT - /* define the PDEBUG macro here */ #undef PDEBUG #ifdef DEBUG_PT @@ -40,17 +37,4 @@ # define PDEBUG(fmt, args...) /* debug switched off */ #endif -/* nothing; placeholder to disable a PDEBUG message but don't delete it */ -#undef PDEBUGG -#define PDEBUGG(fmt, args...) - -/* Define ASSERT to stop/warn. Should be void in production code */ -#undef ASSERT -#ifdef DO_ASSERT -# define ASSERT(x) if (!(x)) fprintf(stderr, "pt: assertion failed in %s:%i.\n",\ - __FILE__, __LINE__) -#else -# define ASSERT(x) -#endif - #endif /* _PT_DEBUG_H */ diff --git a/libpthread/linuxthreads.old/internals.h b/libpthread/linuxthreads.old/internals.h index 17b724e64..ab227d6cc 100644 --- a/libpthread/linuxthreads.old/internals.h +++ b/libpthread/linuxthreads.old/internals.h @@ -24,6 +24,7 @@ #include <setjmp.h> #include <signal.h> #include <unistd.h> +#include <bits/stackinfo.h> #include <sys/types.h> #include <sys/wait.h> #include "pt-machine.h" @@ -445,21 +446,12 @@ static inline pthread_descr thread_self (void) extern int __libc_multiple_threads attribute_hidden; extern int __librt_multiple_threads; -/* Debugging */ - -#ifdef DEBUG -#include <assert.h> -#define ASSERT assert -#define MSG __pthread_message -#else -#define ASSERT(x) -#define MSG(msg,arg...) -#endif - /* Internal global functions */ +void __pthread_do_exit (void *retval, char *currentframe) + __attribute__ ((__noreturn__)); void __pthread_destroy_specifics(void); -void __pthread_perform_cleanup(void); +void __pthread_perform_cleanup(char *currentframe); int __pthread_initialize_manager(void); void __pthread_message(char * fmt, ...); int __pthread_manager(void *reqfd); diff --git a/libpthread/linuxthreads.old/join.c b/libpthread/linuxthreads.old/join.c index 6a8a9d982..4bdc77a25 100644 --- a/libpthread/linuxthreads.old/join.c +++ b/libpthread/linuxthreads.old/join.c @@ -27,16 +27,25 @@ void pthread_exit(void * retval) { + __pthread_do_exit (retval, CURRENT_STACK_FRAME); +} + +void __pthread_do_exit(void *retval, char *currentframe) +{ pthread_descr self = thread_self(); pthread_descr joining; struct pthread_request request; PDEBUG("self=%p, pid=%d\n", self, self->p_pid); - /* Reset the cancellation flag to avoid looping if the cleanup handlers - contain cancellation points */ - THREAD_SETMEM(self, p_canceled, 0); + /* obey POSIX behavior and prevent cancellation functions from + * being called more than once. + * http://sourceware.org/ml/libc-ports/2006-10/msg00043.html + */ + THREAD_SETMEM(self, p_cancelstate, PTHREAD_CANCEL_DISABLE); + THREAD_SETMEM(self, p_canceltype, PTHREAD_CANCEL_DEFERRED); + /* Call cleanup functions and destroy the thread-specific data */ - __pthread_perform_cleanup(); + __pthread_perform_cleanup(currentframe); __pthread_destroy_specifics(); /* Store return value */ __pthread_lock(THREAD_GETMEM(self, p_lock), self); @@ -150,7 +159,7 @@ int pthread_join(pthread_t thread_id, void ** thread_return) if (already_canceled) { __pthread_set_own_extricate_if(self, 0); - pthread_exit(PTHREAD_CANCELED); + __pthread_do_exit(PTHREAD_CANCELED, CURRENT_STACK_FRAME); } PDEBUG("before suspend\n"); @@ -163,7 +172,7 @@ int pthread_join(pthread_t thread_id, void ** thread_return) if (THREAD_GETMEM(self, p_woken_by_cancel) && THREAD_GETMEM(self, p_cancelstate) == PTHREAD_CANCEL_ENABLE) { THREAD_SETMEM(self, p_woken_by_cancel, 0); - pthread_exit(PTHREAD_CANCELED); + __pthread_do_exit(PTHREAD_CANCELED, CURRENT_STACK_FRAME); } __pthread_lock(&handle->h_lock, self); } diff --git a/libpthread/linuxthreads.old/manager.c b/libpthread/linuxthreads.old/manager.c index e57080d17..cad2aacdf 100644 --- a/libpthread/linuxthreads.old/manager.c +++ b/libpthread/linuxthreads.old/manager.c @@ -148,7 +148,6 @@ int attribute_noreturn __pthread_manager(void *arg) /* Synchronize debugging of the thread manager */ n = TEMP_FAILURE_RETRY(__libc_read(reqfd, (char *)&request, sizeof(request))); - ASSERT(n == sizeof(request) && request.req_kind == REQ_DEBUG); #ifndef USE_SELECT ufd.fd = reqfd; ufd.events = POLLIN; @@ -187,7 +186,6 @@ int attribute_noreturn __pthread_manager(void *arg) PDEBUG("before __libc_read\n"); n = __libc_read(reqfd, (char *)&request, sizeof(request)); PDEBUG("after __libc_read, n=%d\n", n); - ASSERT(n == sizeof(request)); switch(request.req_kind) { case REQ_CREATE: PDEBUG("got REQ_CREATE\n"); @@ -311,7 +309,7 @@ pthread_start_thread(void *arg) outcome = self->p_start_args.start_routine(THREAD_GETMEM(self, p_start_args.arg)); /* Exit with the given return value */ - pthread_exit(outcome); + __pthread_do_exit(outcome, CURRENT_STACK_FRAME); } static int @@ -698,7 +696,6 @@ static void pthread_free(pthread_descr th) pthread_readlock_info *iter, *next; char *h_bottom_save; - ASSERT(th->p_exited); /* Make the handle invalid */ handle = thread_handle(th->p_tid); __pthread_lock(&handle->h_lock, NULL); diff --git a/libpthread/linuxthreads.old/oldsemaphore.c b/libpthread/linuxthreads.old/oldsemaphore.c index 6e91dc3c7..178affa1b 100644 --- a/libpthread/linuxthreads.old/oldsemaphore.c +++ b/libpthread/linuxthreads.old/oldsemaphore.c @@ -136,7 +136,7 @@ int __old_sem_wait(old_sem_t * sem) } } } - pthread_exit(PTHREAD_CANCELED); + __pthread_do_exit(PTHREAD_CANCELED, CURRENT_STACK_FRAME); } } } diff --git a/libpthread/linuxthreads.old/pthread.c b/libpthread/linuxthreads.old/pthread.c index d9adfa432..2efb4d2d4 100644 --- a/libpthread/linuxthreads.old/pthread.c +++ b/libpthread/linuxthreads.old/pthread.c @@ -819,7 +819,7 @@ static void pthread_handle_sigcancel(int sig) if (__builtin_expect (THREAD_GETMEM(self, p_canceled), 0) && THREAD_GETMEM(self, p_cancelstate) == PTHREAD_CANCEL_ENABLE) { if (THREAD_GETMEM(self, p_canceltype) == PTHREAD_CANCEL_ASYNCHRONOUS) - pthread_exit(PTHREAD_CANCELED); + __pthread_do_exit(PTHREAD_CANCELED, CURRENT_STACK_FRAME); jmpbuf = THREAD_GETMEM(self, p_cancel_jmp); if (jmpbuf != NULL) { THREAD_SETMEM(self, p_cancel_jmp, NULL); diff --git a/libpthread/linuxthreads.old/ptlongjmp.c b/libpthread/linuxthreads.old/ptlongjmp.c index 055a217d3..b3ff2746f 100644 --- a/libpthread/linuxthreads.old/ptlongjmp.c +++ b/libpthread/linuxthreads.old/ptlongjmp.c @@ -18,6 +18,7 @@ #include <setjmp.h> #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. */ @@ -28,11 +29,29 @@ static void pthread_cleanup_upto(__jmp_buf target) { pthread_descr self = thread_self(); struct _pthread_cleanup_buffer * c; + char *currentframe = CURRENT_STACK_FRAME; for (c = THREAD_GETMEM(self, p_cleanup); c != NULL && _JMPBUF_UNWINDS(target, c); c = c->__prev) - c->__routine(c->__arg); + { +#if _STACK_GROWS_DOWN + if ((char *) c <= currentframe) + { + c = NULL; + break; + } +#elif _STACK_GROWS_UP + if ((char *) c >= currentframe) + { + c = NULL; + break; + } +#else +# error "Define either _STACK_GROWS_DOWN or _STACK_GROWS_UP" +#endif + c->__routine(c->__arg); + } THREAD_SETMEM(self, p_cleanup, c); if (THREAD_GETMEM(self, p_in_sighandler) && _JMPBUF_UNWINDS(target, THREAD_GETMEM(self, p_in_sighandler))) diff --git a/libpthread/linuxthreads.old/queue.h b/libpthread/linuxthreads.old/queue.h index 28bd75531..c7f8471b9 100644 --- a/libpthread/linuxthreads.old/queue.h +++ b/libpthread/linuxthreads.old/queue.h @@ -21,7 +21,6 @@ static inline void enqueue(pthread_descr * q, pthread_descr th) { int prio = th->p_priority; - ASSERT(th->p_nextwaiting == NULL); for (; *q != NULL; q = &((*q)->p_nextwaiting)) { if (prio > (*q)->p_priority) { th->p_nextwaiting = *q; diff --git a/libpthread/linuxthreads.old/semaphore.c b/libpthread/linuxthreads.old/semaphore.c index a44f52411..7502b6e78 100644 --- a/libpthread/linuxthreads.old/semaphore.c +++ b/libpthread/linuxthreads.old/semaphore.c @@ -87,7 +87,7 @@ int __new_sem_wait(sem_t * sem) if (already_canceled) { __pthread_set_own_extricate_if(self, 0); - pthread_exit(PTHREAD_CANCELED); + __pthread_do_exit(PTHREAD_CANCELED, CURRENT_STACK_FRAME); } /* Wait for sem_post or cancellation, or fall through if already canceled */ @@ -113,7 +113,7 @@ int __new_sem_wait(sem_t * sem) if (THREAD_GETMEM(self, p_woken_by_cancel) && THREAD_GETMEM(self, p_cancelstate) == PTHREAD_CANCEL_ENABLE) { THREAD_SETMEM(self, p_woken_by_cancel, 0); - pthread_exit(PTHREAD_CANCELED); + __pthread_do_exit(PTHREAD_CANCELED, CURRENT_STACK_FRAME); } /* We got the semaphore */ return 0; @@ -252,7 +252,7 @@ int sem_timedwait(sem_t *sem, const struct timespec *abstime) if (already_canceled) { __pthread_set_own_extricate_if(self, 0); - pthread_exit(PTHREAD_CANCELED); + __pthread_do_exit(PTHREAD_CANCELED, CURRENT_STACK_FRAME); } spurious_wakeup_count = 0; @@ -297,7 +297,7 @@ int sem_timedwait(sem_t *sem, const struct timespec *abstime) if (THREAD_GETMEM(self, p_woken_by_cancel) && THREAD_GETMEM(self, p_cancelstate) == PTHREAD_CANCEL_ENABLE) { THREAD_SETMEM(self, p_woken_by_cancel, 0); - pthread_exit(PTHREAD_CANCELED); + __pthread_do_exit(PTHREAD_CANCELED, CURRENT_STACK_FRAME); } /* We got the semaphore */ return 0; diff --git a/libpthread/linuxthreads.old/spinlock.c b/libpthread/linuxthreads.old/spinlock.c index e00bc3156..f5999e4d2 100644 --- a/libpthread/linuxthreads.old/spinlock.c +++ b/libpthread/linuxthreads.old/spinlock.c @@ -620,8 +620,6 @@ void __pthread_alt_unlock(struct _pthread_fastlock *lock) if (maxprio == INT_MIN) continue; - ASSERT (p_max_prio != (struct wait_node *) 1); - /* Now we want to to remove the max priority thread's wait node from the list. Before we can do this, we must atomically try to change the node's abandon state from zero to nonzero. If we succeed, that means we diff --git a/libpthread/linuxthreads.old/sysdeps/pthread/pthread.h b/libpthread/linuxthreads.old/sysdeps/pthread/pthread.h index 0cee6a84f..448636bd9 100644 --- a/libpthread/linuxthreads.old/sysdeps/pthread/pthread.h +++ b/libpthread/linuxthreads.old/sysdeps/pthread/pthread.h @@ -24,9 +24,6 @@ #include <signal.h> #include <bits/pthreadtypes.h> #include <bits/initspin.h> -#if defined _LIBC && (defined IS_IN_libc || defined NOT_IN_libc) -#include <bits/uClibc_pthread.h> -#endif __BEGIN_DECLS diff --git a/libpthread/linuxthreads.old/wrapsyscall.c b/libpthread/linuxthreads.old/wrapsyscall.c index 369c190d5..684989be0 100644 --- a/libpthread/linuxthreads.old/wrapsyscall.c +++ b/libpthread/linuxthreads.old/wrapsyscall.c @@ -96,9 +96,11 @@ CANCELABLE_SYSCALL (off64_t, lseek64, (int fd, off64_t offset, int whence), (fd, offset, whence)) #endif +#ifdef __NR_msync /* msync(2). */ CANCELABLE_SYSCALL (int, msync, (__ptr_t addr, size_t length, int flags), (addr, length, flags)) +#endif /* nanosleep(2). */ |