Back to index

glibc  2.9
sysdep-cancel.h
Go to the documentation of this file.
00001 /* Cancellable system call stubs.  Linux/PowerPC64 version.
00002    Copyright (C) 2003, 2004, 2006 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 # ifdef HAVE_ASM_GLOBAL_DOT_NAME
00030 #  define DASHDASHPFX(str) .__##str
00031 # else
00032 #  define DASHDASHPFX(str) __##str
00033 # endif
00034 
00035 # undef PSEUDO
00036 # define PSEUDO(name, syscall_name, args)                      \
00037   .section ".text";                                            \
00038   ENTRY (name)                                                        \
00039     SINGLE_THREAD_P;                                           \
00040     bne- .Lpseudo_cancel;                                      \
00041   .type DASHDASHPFX(syscall_name##_nocancel),@function;               \
00042   .globl DASHDASHPFX(syscall_name##_nocancel);                        \
00043   DASHDASHPFX(syscall_name##_nocancel):                               \
00044     DO_CALL (SYS_ify (syscall_name));                                 \
00045     PSEUDO_RET;                                                       \
00046   .size DASHDASHPFX(syscall_name##_nocancel),.-DASHDASHPFX(syscall_name##_nocancel);       \
00047   .Lpseudo_cancel:                                             \
00048     stdu 1,-128(1);                                            \
00049     cfi_adjust_cfa_offset (128);                               \
00050     mflr 9;                                                    \
00051     std  9,128+16(1);                                                 \
00052     cfi_offset (lr, 16);                                       \
00053     DOCARGS_##args;  /* save syscall args around CENABLE.  */  \
00054     CENABLE;                                                   \
00055     std  3,72(1);    /* store CENABLE return value (MASK).  */ \
00056     UNDOCARGS_##args;       /* restore syscall args.  */                     \
00057     DO_CALL (SYS_ify (syscall_name));                                 \
00058     mfcr 0;          /* save CR/R3 around CDISABLE.  */        \
00059     std  3,64(1);                                              \
00060     std  0,8(1);                                               \
00061     ld   3,72(1);    /* pass MASK to CDISABLE.  */                    \
00062     CDISABLE;                                                  \
00063     ld   9,128+16(1);                                                 \
00064     ld   0,8(1);     /* restore CR/R3. */                      \
00065     ld   3,64(1);                                              \
00066     mtlr 9;                                                    \
00067     mtcr 0;                                                    \
00068     addi 1,1,128;
00069 
00070 # define DOCARGS_0
00071 # define UNDOCARGS_0
00072 
00073 # define DOCARGS_1   std 3,80(1); DOCARGS_0
00074 # define UNDOCARGS_1 ld 3,80(1); UNDOCARGS_0
00075 
00076 # define DOCARGS_2   std 4,88(1); DOCARGS_1
00077 # define UNDOCARGS_2 ld 4,88(1); UNDOCARGS_1
00078 
00079 # define DOCARGS_3   std 5,96(1); DOCARGS_2
00080 # define UNDOCARGS_3 ld 5,96(1); UNDOCARGS_2
00081 
00082 # define DOCARGS_4   std 6,104(1); DOCARGS_3
00083 # define UNDOCARGS_4 ld 6,104(1); UNDOCARGS_3
00084 
00085 # define DOCARGS_5   std 7,112(1); DOCARGS_4
00086 # define UNDOCARGS_5 ld 7,112(1); UNDOCARGS_4
00087 
00088 # define DOCARGS_6   std 8,120(1); DOCARGS_5
00089 # define UNDOCARGS_6 ld 8,120(1); UNDOCARGS_5
00090 
00091 # ifdef IS_IN_libpthread
00092 #  define CENABLE    bl JUMPTARGET(__pthread_enable_asynccancel)
00093 #  define CDISABLE   bl JUMPTARGET(__pthread_disable_asynccancel)
00094 # elif !defined NOT_IN_libc
00095 #  define CENABLE    bl JUMPTARGET(__libc_enable_asynccancel)
00096 #  define CDISABLE   bl JUMPTARGET(__libc_disable_asynccancel)
00097 # elif defined IS_IN_librt
00098 #  define CENABLE    bl JUMPTARGET(__librt_enable_asynccancel)
00099 #  define CDISABLE   bl JUMPTARGET(__librt_disable_asynccancel)
00100 # else
00101 #  error Unsupported library
00102 # endif
00103 
00104 # ifndef __ASSEMBLER__
00105 #  define SINGLE_THREAD_P                                      \
00106   __builtin_expect (THREAD_GETMEM (THREAD_SELF,                       \
00107                                header.multiple_threads) == 0, 1)
00108 # else
00109 #   define SINGLE_THREAD_P                                     \
00110   lwz   10,MULTIPLE_THREADS_OFFSET(13);                        \
00111   cmpwi 10,0
00112 # endif
00113 
00114 #elif !defined __ASSEMBLER__
00115 
00116 # define SINGLE_THREAD_P (1)
00117 # define NO_CANCELLATION 1
00118 
00119 #endif
00120 
00121 #ifndef __ASSEMBLER__
00122 # define RTLD_SINGLE_THREAD_P \
00123   __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
00124                                header.multiple_threads) == 0, 1)
00125 #endif