Back to index

glibc  2.9
pt-cleanup.c
Go to the documentation of this file.
00001 /* Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc.
00002    This file is part of the GNU C Library.
00003    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
00004 
00005    The GNU C Library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Lesser General Public
00007    License as published by the Free Software Foundation; either
00008    version 2.1 of the License, or (at your option) any later version.
00009 
00010    The GNU C Library is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Lesser General Public License for more details.
00014 
00015    You should have received a copy of the GNU Lesser General Public
00016    License along with the GNU C Library; if not, write to the Free
00017    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00018    02111-1307 USA.  */
00019 
00020 #include <setjmp.h>
00021 #include <stdlib.h>
00022 #include "pthreadP.h"
00023 #include <jmpbuf-unwind.h>
00024 
00025 void
00026 __pthread_cleanup_upto (__jmp_buf target, char *targetframe)
00027 {
00028   struct pthread *self = THREAD_SELF;
00029   struct _pthread_cleanup_buffer *cbuf;
00030 
00031   /* Adjust all pointers used in comparisons, so that top of thread's
00032      stack is at the top of address space.  Without that, things break
00033      if stack is allocated above the main stack.  */
00034   uintptr_t adj = (uintptr_t) self->stackblock + self->stackblock_size;
00035   uintptr_t targetframe_adj = (uintptr_t) targetframe - adj;
00036 
00037   for (cbuf = THREAD_GETMEM (self, cleanup);
00038        cbuf != NULL && _JMPBUF_UNWINDS_ADJ (target, cbuf, adj);
00039        cbuf = cbuf->__prev)
00040     {
00041 #if _STACK_GROWS_DOWN
00042       if ((uintptr_t) cbuf - adj <= targetframe_adj)
00043         {
00044           cbuf = NULL;
00045           break;
00046         }
00047 #elif _STACK_GROWS_UP
00048       if ((uintptr_t) cbuf - adj >= targetframe_adj)
00049         {
00050           cbuf = NULL;
00051           break;
00052         }
00053 #else
00054 # error "Define either _STACK_GROWS_DOWN or _STACK_GROWS_UP"
00055 #endif
00056 
00057       /* Call the cleanup code.  */
00058       cbuf->__routine (cbuf->__arg);
00059     }
00060 
00061   THREAD_SETMEM (self, cleanup, cbuf);
00062 }
00063 hidden_def (__pthread_cleanup_upto)