summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libpthread/linuxthreads.old/cancel.c27
-rw-r--r--libpthread/linuxthreads.old/condvar.c8
-rw-r--r--libpthread/linuxthreads.old/internals.h4
-rw-r--r--libpthread/linuxthreads.old/join.c11
-rw-r--r--libpthread/linuxthreads.old/manager.c2
-rw-r--r--libpthread/linuxthreads.old/oldsemaphore.c2
-rw-r--r--libpthread/linuxthreads.old/pthread.c2
-rw-r--r--libpthread/linuxthreads.old/ptlongjmp.c21
-rw-r--r--libpthread/linuxthreads.old/semaphore.c8
9 files changed, 63 insertions, 22 deletions
diff --git a/libpthread/linuxthreads.old/cancel.c b/libpthread/linuxthreads.old/cancel.c
index 25b098dd5..ac66c5855 100644
--- a/libpthread/linuxthreads.old/cancel.c
+++ b/libpthread/linuxthreads.old/cancel.c
@@ -25,6 +25,9 @@
#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)
@@ -45,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;
}
@@ -59,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;
}
@@ -126,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,
@@ -173,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/internals.h b/libpthread/linuxthreads.old/internals.h
index bd4d8ae13..ab227d6cc 100644
--- a/libpthread/linuxthreads.old/internals.h
+++ b/libpthread/linuxthreads.old/internals.h
@@ -448,8 +448,10 @@ 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(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..f249a8114 100644
--- a/libpthread/linuxthreads.old/join.c
+++ b/libpthread/linuxthreads.old/join.c
@@ -27,6 +27,11 @@
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;
@@ -36,7 +41,7 @@ void pthread_exit(void * retval)
contain cancellation points */
THREAD_SETMEM(self, p_canceled, 0);
/* 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 +155,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 +168,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 dbbee3f6f..cad2aacdf 100644
--- a/libpthread/linuxthreads.old/manager.c
+++ b/libpthread/linuxthreads.old/manager.c
@@ -309,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
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/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;