Back to index

glibc  2.9
sysdep-cancel.h
Go to the documentation of this file.
00001 /* Cancellable system call stubs.  Linux/PowerPC version.
00002    Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
00003    This file is part of the GNU C Library.
00004    Contributed by Franz Sirl <Franz.Sirl-kernel@lauterbach.com>, 2003.
00005 
00006    The GNU C Library is free software; you can redistribute it and/or
00007    modify it under the terms of the GNU Lesser General Public
00008    License as published by the Free Software Foundation; either
00009    version 2.1 of the License, or (at your option) any later version.
00010 
00011    The GNU C Library is distributed in the hope that it will be useful,
00012    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014    Lesser General Public License for more details.
00015 
00016    You should have received a copy of the GNU Lesser General Public
00017    License along with the GNU C Library; if not, write to the Free
00018    Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA
00019    02110-1301 USA.  */
00020 
00021 #include <sysdep.h>
00022 #include <tls.h>
00023 #ifndef __ASSEMBLER__
00024 # include <nptl/pthreadP.h>
00025 #endif
00026 
00027 #if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt
00028 
00029 # undef PSEUDO
00030 # define PSEUDO(name, syscall_name, args)                      \
00031   .section ".text";                                            \
00032   ENTRY (name)                                                        \
00033     SINGLE_THREAD_P;                                           \
00034     bne- .Lpseudo_cancel;                                      \
00035   .type __##syscall_name##_nocancel,@function;                        \
00036   .globl __##syscall_name##_nocancel;                                 \
00037   __##syscall_name##_nocancel:                                        \
00038     DO_CALL (SYS_ify (syscall_name));                                 \
00039     PSEUDO_RET;                                                       \
00040   .size __##syscall_name##_nocancel,.-__##syscall_name##_nocancel;    \
00041   .Lpseudo_cancel:                                             \
00042     stwu 1,-48(1);                                             \
00043     cfi_adjust_cfa_offset (48);                                       \
00044     mflr 9;                                                    \
00045     stw 9,52(1);                                               \
00046     cfi_offset (lr, 4);                                               \
00047     DOCARGS_##args;  /* save syscall args around CENABLE.  */  \
00048     CENABLE;                                                   \
00049     stw 3,16(1);     /* store CENABLE return value (MASK).  */ \
00050     UNDOCARGS_##args;       /* restore syscall args.  */                     \
00051     DO_CALL (SYS_ify (syscall_name));                                 \
00052     mfcr 0;          /* save CR/R3 around CDISABLE.  */        \
00053     stw 3,8(1);                                                       \
00054     stw 0,12(1);                                               \
00055     lwz 3,16(1);     /* pass MASK to CDISABLE.  */                    \
00056     CDISABLE;                                                  \
00057     lwz 4,52(1);                                               \
00058     lwz 0,12(1);     /* restore CR/R3. */                      \
00059     lwz 3,8(1);                                                       \
00060     mtlr 4;                                                    \
00061     mtcr 0;                                                    \
00062     addi 1,1,48;
00063 
00064 # define DOCARGS_0
00065 # define UNDOCARGS_0
00066 
00067 # define DOCARGS_1   stw 3,20(1); DOCARGS_0
00068 # define UNDOCARGS_1 lwz 3,20(1); UNDOCARGS_0
00069 
00070 # define DOCARGS_2   stw 4,24(1); DOCARGS_1
00071 # define UNDOCARGS_2 lwz 4,24(1); UNDOCARGS_1
00072 
00073 # define DOCARGS_3   stw 5,28(1); DOCARGS_2
00074 # define UNDOCARGS_3 lwz 5,28(1); UNDOCARGS_2
00075 
00076 # define DOCARGS_4   stw 6,32(1); DOCARGS_3
00077 # define UNDOCARGS_4 lwz 6,32(1); UNDOCARGS_3
00078 
00079 # define DOCARGS_5   stw 7,36(1); DOCARGS_4
00080 # define UNDOCARGS_5 lwz 7,36(1); UNDOCARGS_4
00081 
00082 # define DOCARGS_6   stw 8,40(1); DOCARGS_5
00083 # define UNDOCARGS_6 lwz 8,40(1); UNDOCARGS_5
00084 
00085 # ifdef IS_IN_libpthread
00086 #  define CENABLE    bl __pthread_enable_asynccancel@local
00087 #  define CDISABLE   bl __pthread_disable_asynccancel@local
00088 # elif !defined NOT_IN_libc
00089 #  define CENABLE    bl __libc_enable_asynccancel@local
00090 #  define CDISABLE   bl __libc_disable_asynccancel@local
00091 # elif defined IS_IN_librt
00092 #  define CENABLE    bl __librt_enable_asynccancel@local
00093 #  define CDISABLE   bl __librt_disable_asynccancel@local
00094 # else
00095 #  error Unsupported library
00096 # endif
00097 
00098 # ifndef __ASSEMBLER__
00099 #  define SINGLE_THREAD_P                                      \
00100   __builtin_expect (THREAD_GETMEM (THREAD_SELF,                       \
00101                                header.multiple_threads) == 0, 1)
00102 # else
00103 #  define SINGLE_THREAD_P                                      \
00104   lwz 10,MULTIPLE_THREADS_OFFSET(2);                                  \
00105   cmpwi 10,0
00106 # endif
00107 
00108 #elif !defined __ASSEMBLER__
00109 
00110 # define SINGLE_THREAD_P (1)
00111 # define NO_CANCELLATION 1
00112 
00113 #endif
00114 
00115 #ifndef __ASSEMBLER__
00116 # define RTLD_SINGLE_THREAD_P \
00117   __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
00118                                header.multiple_threads) == 0, 1)
00119 #endif