diff options
author | Waldemar Brodkorb <wbx@uclibc-ng.org> | 2016-05-18 18:41:24 +0200 |
---|---|---|
committer | Waldemar Brodkorb <wbx@uclibc-ng.org> | 2016-05-18 18:41:24 +0200 |
commit | 6a8ccc95528f5e86a8770ed15ce89609b5b3dee9 (patch) | |
tree | bbd4df35b4d4a6a8b00d7a5e61fb2668b850ad62 /libpthread/linuxthreads/ptlongjmp.c | |
parent | 398a27a5b323956344b4f831d892fed3bd9813c7 (diff) |
remove linuxthreads.new, rename linuxthreads.old
Linuxthreads.new isn't really useful with the existence
of NPTL/TLS for well supported architectures. There is no
reason to use LT.new for ARM/MIPS or other architectures
supporting NPTL/TLS. It is not available for noMMU architectures
like Blackfin or FR-V. To simplify the live of the few uClibc-ng
developers, LT.new is removed and LT.old is renamed to LT.
LINUXTHREADS_OLD -> UCLIBC_HAS_LINUXTHREADS
Diffstat (limited to 'libpthread/linuxthreads/ptlongjmp.c')
-rw-r--r-- | libpthread/linuxthreads/ptlongjmp.c | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/libpthread/linuxthreads/ptlongjmp.c b/libpthread/linuxthreads/ptlongjmp.c new file mode 100644 index 000000000..5cb708944 --- /dev/null +++ b/libpthread/linuxthreads/ptlongjmp.c @@ -0,0 +1,67 @@ +/* Linuxthreads - a simple clone()-based implementation of Posix */ +/* threads for Linux. */ +/* Copyright (C) 1998 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. */ + +/* Redefine siglongjmp and longjmp so that they interact correctly + with cleanup handlers */ + +#include <setjmp.h> +#include "pthread.h" +#include "internals.h" +#include <bits/stackinfo.h> +#include <jmpbuf-unwind.h> + +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) + { +#ifdef _STACK_GROWS_DOWN + if ((char *) c <= currentframe) + { + c = NULL; + break; + } +#elif defined _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))) + THREAD_SETMEM(self, p_in_sighandler, NULL); +} + +void siglongjmp(sigjmp_buf env, int val) +{ + pthread_cleanup_upto(env->__jmpbuf); + __libc_siglongjmp(env, val); +} + +void longjmp(jmp_buf env, int val) +{ + pthread_cleanup_upto(env->__jmpbuf); + __libc_longjmp(env, val); +} |