svn commit: trunk/uClibc/libpthread/linuxthreads.old
vapier at uclibc.org
vapier at uclibc.org
Thu Nov 9 08:11:34 UTC 2006
Author: vapier
Date: 2006-11-09 00:11:33 -0800 (Thu, 09 Nov 2006)
New Revision: 16524
Log:
backport from upstream:
2001-04-10 Ulrich Drepper <drepper at redhat.com>
* join.c (pthread_exit): Move code to new function __pthread_do_exit
which takes an extra parameter with the current frame pointer.
Call new function with CURRENT_STACK_FRAME.
(__pthread_do_exit): New function. Call __pthread_perform_cleanup
with the new parameter.
(pthread_join): Call __pthread_do_exit instead of pthread_exit.
* cancel.c (__pthread_perform_cleanup): Takes extra parameter. Use
this parameter as the initial value the cleanup handler records are
compared against. No active cleanup handler record must have an
address lower than the previous one and the initial record must be
above (below on PA) the frame address passed in.
(pthread_setcancelstate): Call __pthread_do_exit instead of
pthread_exit.
(pthread_setcanceltype): Likewise.
(pthread_testcancel): Likewise.
(_pthread_cleanup_pop_restore): Likewise.
* condvar.c (pthread_cond_wait): Likewise.
(pthread_cond_timedwait_relative): Likewise.
* manager.c (pthread_start_thread): Likewise.
* oldsemaphore.c (__old_sem_wait): Likewise.
* pthread.c (pthread_handle_sigcancel): Likewise.
* semaphore.c (__new_sem_wait): Likewise.
(sem_timedwait): Likewise.
* ptlongjmp.c (pthread_cleanup_upto): Also use current stack frame
to limit the cleanup handlers which get run.
* internals.h: Add prototype for __pthread_do_exit. Adjust prototype
for __pthread_perform_cleanup.
Modified:
trunk/uClibc/libpthread/linuxthreads.old/cancel.c
trunk/uClibc/libpthread/linuxthreads.old/condvar.c
trunk/uClibc/libpthread/linuxthreads.old/internals.h
trunk/uClibc/libpthread/linuxthreads.old/join.c
trunk/uClibc/libpthread/linuxthreads.old/manager.c
trunk/uClibc/libpthread/linuxthreads.old/oldsemaphore.c
trunk/uClibc/libpthread/linuxthreads.old/pthread.c
trunk/uClibc/libpthread/linuxthreads.old/ptlongjmp.c
trunk/uClibc/libpthread/linuxthreads.old/semaphore.c
Changeset:
Modified: trunk/uClibc/libpthread/linuxthreads.old/cancel.c
===================================================================
--- trunk/uClibc/libpthread/linuxthreads.old/cancel.c 2006-11-09 08:07:43 UTC (rev 16523)
+++ trunk/uClibc/libpthread/linuxthreads.old/cancel.c 2006-11-09 08:11:33 UTC (rev 16524)
@@ -25,7 +25,10 @@
#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
@@ -45,7 +48,7 @@
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 @@
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 @@
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 @@
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. */
Modified: trunk/uClibc/libpthread/linuxthreads.old/condvar.c
===================================================================
--- trunk/uClibc/libpthread/linuxthreads.old/condvar.c 2006-11-09 08:07:43 UTC (rev 16523)
+++ trunk/uClibc/libpthread/linuxthreads.old/condvar.c 2006-11-09 08:11:33 UTC (rev 16524)
@@ -93,7 +93,7 @@
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 @@
&& 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 @@
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 @@
&& 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. */
Modified: trunk/uClibc/libpthread/linuxthreads.old/internals.h
===================================================================
--- trunk/uClibc/libpthread/linuxthreads.old/internals.h 2006-11-09 08:07:43 UTC (rev 16523)
+++ trunk/uClibc/libpthread/linuxthreads.old/internals.h 2006-11-09 08:11:33 UTC (rev 16524)
@@ -448,8 +448,10 @@
/* 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);
Modified: trunk/uClibc/libpthread/linuxthreads.old/join.c
===================================================================
--- trunk/uClibc/libpthread/linuxthreads.old/join.c 2006-11-09 08:07:43 UTC (rev 16523)
+++ trunk/uClibc/libpthread/linuxthreads.old/join.c 2006-11-09 08:11:33 UTC (rev 16524)
@@ -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 @@
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 @@
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 @@
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);
}
Modified: trunk/uClibc/libpthread/linuxthreads.old/manager.c
===================================================================
--- trunk/uClibc/libpthread/linuxthreads.old/manager.c 2006-11-09 08:07:43 UTC (rev 16523)
+++ trunk/uClibc/libpthread/linuxthreads.old/manager.c 2006-11-09 08:11:33 UTC (rev 16524)
@@ -309,7 +309,7 @@
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
Modified: trunk/uClibc/libpthread/linuxthreads.old/oldsemaphore.c
===================================================================
--- trunk/uClibc/libpthread/linuxthreads.old/oldsemaphore.c 2006-11-09 08:07:43 UTC (rev 16523)
+++ trunk/uClibc/libpthread/linuxthreads.old/oldsemaphore.c 2006-11-09 08:11:33 UTC (rev 16524)
@@ -136,7 +136,7 @@
}
}
}
- pthread_exit(PTHREAD_CANCELED);
+ __pthread_do_exit(PTHREAD_CANCELED, CURRENT_STACK_FRAME);
}
}
}
Modified: trunk/uClibc/libpthread/linuxthreads.old/pthread.c
===================================================================
--- trunk/uClibc/libpthread/linuxthreads.old/pthread.c 2006-11-09 08:07:43 UTC (rev 16523)
+++ trunk/uClibc/libpthread/linuxthreads.old/pthread.c 2006-11-09 08:11:33 UTC (rev 16524)
@@ -819,7 +819,7 @@
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);
Modified: trunk/uClibc/libpthread/linuxthreads.old/ptlongjmp.c
===================================================================
--- trunk/uClibc/libpthread/linuxthreads.old/ptlongjmp.c 2006-11-09 08:07:43 UTC (rev 16523)
+++ trunk/uClibc/libpthread/linuxthreads.old/ptlongjmp.c 2006-11-09 08:11:33 UTC (rev 16524)
@@ -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 @@
{
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)))
Modified: trunk/uClibc/libpthread/linuxthreads.old/semaphore.c
===================================================================
--- trunk/uClibc/libpthread/linuxthreads.old/semaphore.c 2006-11-09 08:07:43 UTC (rev 16523)
+++ trunk/uClibc/libpthread/linuxthreads.old/semaphore.c 2006-11-09 08:11:33 UTC (rev 16524)
@@ -87,7 +87,7 @@
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 @@
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 @@
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 @@
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;
More information about the uClibc-cvs
mailing list