* sysdeps/unix/sysv/linux/m68k/semtimedop.S: New file.
[glibc/pb-stable.git] / nptl / unwind.c
blob7529174d5a43ea11bc3522cd29ba542f1b4ab3f9
1 /* Copyright (C) 2003 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3 Contributed by Ulrich Drepper <drepper@redhat.com>
4 and Richard Henderson <rth@redhat.com>, 2003.
6 The GNU C Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
11 The GNU C Library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with the GNU C Library; if not, write to the Free
18 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307 USA. */
21 #include <setjmp.h>
22 #include <stdlib.h>
23 #include "pthreadP.h"
26 #ifdef HAVE_FORCED_UNWIND
28 static _Unwind_Reason_Code
29 unwind_stop (int version, _Unwind_Action actions,
30 _Unwind_Exception_Class exc_class,
31 struct _Unwind_Exception *exc_obj,
32 struct _Unwind_Context *context, void *stop_parameter)
34 struct pthread_unwind_buf *buf = stop_parameter;
36 /* Do longjmp if we're at "end of stack", aka "end of unwind data".
37 We assume there are only C frame without unwind data in between
38 here and the jmp_buf target. Otherwise simply note that the CFA
39 of a function is NOT within it's stack frame; it's the SP of the
40 previous frame. */
41 if ((actions & _UA_END_OF_STACK)
42 || ! _JMPBUF_UNWINDS (buf->cancel_jmp_buf[0].jmp_buf,
43 _Unwind_GetCFA (context)))
44 __libc_longjmp ((struct __jmp_buf_tag *) buf->cancel_jmp_buf, 1);
46 return _URC_NO_REASON;
50 static void
51 unwind_cleanup (_Unwind_Reason_Code reason, struct _Unwind_Exception *exc)
53 /* Nothing to do. */
56 #endif /* have forced unwind */
59 void
60 __cleanup_fct_attribute __attribute ((noreturn))
61 __pthread_unwind (__pthread_unwind_buf_t *buf)
63 struct pthread_unwind_buf *ibuf = (struct pthread_unwind_buf *) buf;
64 struct pthread *self = THREAD_SELF;
66 /* Handle the compatibility stuff first. Execute all handlers
67 registered with the old method. We don't execute them in order,
68 instead, they will run first. */
69 struct _pthread_cleanup_buffer *oldp = ibuf->priv.data.cleanup;
70 struct _pthread_cleanup_buffer *curp = THREAD_GETMEM (self, cleanup);
72 if (curp != oldp)
76 /* Pointer to the next element. */
77 struct _pthread_cleanup_buffer *nextp = curp->__prev;
79 /* Call the handler. */
80 curp->__routine (curp->__arg);
82 /* To the next. */
83 curp = nextp;
85 while (curp != oldp);
87 /* Mark the current element as handled. */
88 THREAD_SETMEM (self, cleanup, curp);
91 #ifdef HAVE_FORCED_UNWIND
92 /* This is not a catchable exception, so don't provide any details about
93 the exception type. We do need to initialize the field though. */
94 THREAD_SETMEM (self, exc.exception_class, 0);
95 THREAD_SETMEM (self, exc.exception_cleanup, unwind_cleanup);
97 _Unwind_ForcedUnwind (&self->exc, unwind_stop, ibuf);
98 #else
99 /* We simply jump to the registered setjmp buffer. */
100 __libc_longjmp ((struct __jmp_buf_tag *) ibuf->cancel_jmp_buf, 1);
101 #endif
102 /* NOTREACHED */
104 /* We better do not get here. */
105 abort ();
109 void
110 __cleanup_fct_attribute __attribute ((noreturn))
111 __pthread_unwind_next (__pthread_unwind_buf_t *buf)
113 struct pthread_unwind_buf *ibuf = (struct pthread_unwind_buf *) buf;
115 __pthread_unwind (ibuf->priv.data.prev);