]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/uclibc/lib/libpthread/src/ptcleanup.c
Inital import
[l4.git] / l4 / pkg / uclibc / lib / libpthread / src / ptcleanup.c
1 /* Linuxthreads - a simple clone()-based implementation of Posix        */
2 /* threads for Linux.                                                   */
3 /* Copyright (C) 1998 Xavier Leroy (Xavier.Leroy@inria.fr)              */
4 /*                                                                      */
5 /* This program is free software; you can redistribute it and/or        */
6 /* modify it under the terms of the GNU Library General Public License  */
7 /* as published by the Free Software Foundation; either version 2       */
8 /* of the License, or (at your option) any later version.               */
9 /*                                                                      */
10 /* This program is distributed in the hope that it will be useful,      */
11 /* but WITHOUT ANY WARRANTY; without even the implied warranty of       */
12 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the        */
13 /* GNU Library General Public License for more details.                 */
14
15 /* Redefine siglongjmp and longjmp so that they interact correctly
16    with cleanup handlers */
17
18 #define NO_PTR_DEMANGLE
19
20 #include <setjmp.h>
21 #include "pthread.h"
22 #include "internals.h"
23 #ifndef NO_PTR_DEMANGLE
24 #include <jmpbuf-unwind.h>
25 #define __JMPBUF_UNWINDS(a,b,c) _JMPBUF_UNWINDS(a,b,c)
26 #else
27 #define __JMPBUF_UNWINDS(a,b,c) _JMPBUF_UNWINDS(a,b)
28 #endif
29
30 #ifndef NO_PTR_DEMANGLE
31 static __inline__ uintptr_t
32 demangle_ptr (uintptr_t x)
33 {
34 #ifdef PTR_DEMANGLE
35   PTR_DEMANGLE (x);
36 #endif
37   return x;
38 }
39 #else
40 #define demangle_ptr(x) x
41 #endif
42
43 void __pthread_cleanup_upto (__jmp_buf target, char *targetframe)
44 {
45   pthread_descr self = thread_self();
46   struct _pthread_cleanup_buffer * c;
47
48   for (c = THREAD_GETMEM(self, p_cleanup);
49        c != NULL && __JMPBUF_UNWINDS(target, c, demangle_ptr);
50        c = c->__prev)
51     {
52 #if _STACK_GROWS_DOWN
53       if ((char *) c <= targetframe)
54         {
55           c = NULL;
56           break;
57         }
58 #elif _STACK_GROWS_UP
59       if ((char *) c >= targetframe)
60         {
61           c = NULL;
62           break;
63         }
64 #else
65 # error "Define either _STACK_GROWS_DOWN or _STACK_GROWS_UP"
66 #endif
67       c->__routine(c->__arg);
68     }
69   THREAD_SETMEM(self, p_cleanup, c);
70 #ifdef NOT_FOR_L4
71   if (THREAD_GETMEM(self, p_in_sighandler)
72       && __JMPBUF_UNWINDS(target, THREAD_GETMEM(self, p_in_sighandler),
73                          demangle_ptr))
74     THREAD_SETMEM(self, p_in_sighandler, NULL);
75 #endif
76 }