Back to index

glibc  2.9
sysdep-cancel.h
Go to the documentation of this file.
00001 /* Copyright (C) 2003, 2005 Free Software Foundation, Inc.
00002    This file is part of the GNU C Library.
00003    Contributed by Franz Sirl <Franz.Sirl-kernel@lauterbach.com>, 2003.
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 <sysdep.h>
00021 #include <tls.h>
00022 #ifndef __ASSEMBLER__
00023 # include <linuxthreads/internals.h>
00024 #endif
00025 
00026 #if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt
00027 
00028 # undef PSEUDO
00029 # define PSEUDO(name, syscall_name, args)                      \
00030   .section ".text";                                            \
00031   ENTRY (name)                                                        \
00032     SINGLE_THREAD_P;                                           \
00033     bne- .Lpseudo_cancel;                                      \
00034     DO_CALL (SYS_ify (syscall_name));                                 \
00035     PSEUDO_RET;                                                       \
00036   .Lpseudo_cancel:                                             \
00037     stwu 1,-48(1);                                             \
00038     mflr 9;                                                    \
00039     stw 9,52(1);                                               \
00040     CGOTSETUP;                                                        \
00041     DOCARGS_##args;  /* save syscall args around CENABLE.  */  \
00042     CENABLE;                                                   \
00043     stw 3,16(1);     /* store CENABLE return value (MASK).  */ \
00044     UNDOCARGS_##args;       /* restore syscall args.  */                     \
00045     DO_CALL (SYS_ify (syscall_name));                                 \
00046     mfcr 0;          /* save CR/R3 around CDISABLE.  */        \
00047     stw 3,8(1);                                                       \
00048     stw 0,12(1);                                               \
00049     lwz 3,16(1);     /* pass MASK to CDISABLE.  */                    \
00050     CDISABLE;                                                  \
00051     lwz 4,52(1);                                               \
00052     lwz 0,12(1);     /* restore CR/R3. */                      \
00053     lwz 3,8(1);                                                       \
00054     CGOTRESTORE;                                               \
00055     mtlr 4;                                                    \
00056     mtcr 0;                                                    \
00057     addi 1,1,48;
00058 
00059 # define DOCARGS_0
00060 # define UNDOCARGS_0
00061 
00062 # define DOCARGS_1   stw 3,20(1); DOCARGS_0
00063 # define UNDOCARGS_1 lwz 3,20(1); UNDOCARGS_0
00064 
00065 # define DOCARGS_2   stw 4,24(1); DOCARGS_1
00066 # define UNDOCARGS_2 lwz 4,24(1); UNDOCARGS_1
00067 
00068 # define DOCARGS_3   stw 5,28(1); DOCARGS_2
00069 # define UNDOCARGS_3 lwz 5,28(1); UNDOCARGS_2
00070 
00071 # define DOCARGS_4   stw 6,32(1); DOCARGS_3
00072 # define UNDOCARGS_4 lwz 6,32(1); UNDOCARGS_3
00073 
00074 # define DOCARGS_5   stw 7,36(1); DOCARGS_4
00075 # define UNDOCARGS_5 lwz 7,36(1); UNDOCARGS_4
00076 
00077 # define DOCARGS_6   stw 8,40(1); DOCARGS_5
00078 # define UNDOCARGS_6 lwz 8,40(1); UNDOCARGS_5
00079 
00080 # define CGOTSETUP
00081 # define CGOTRESTORE
00082 
00083 # ifdef IS_IN_libpthread
00084 #  define CENABLE    bl __pthread_enable_asynccancel@local
00085 #  define CDISABLE   bl __pthread_disable_asynccancel@local
00086 # elif !defined NOT_IN_libc
00087 #  define CENABLE    bl __libc_enable_asynccancel@local
00088 #  define CDISABLE   bl __libc_disable_asynccancel@local
00089 # else
00090 #  define CENABLE    bl JUMPTARGET(__librt_enable_asynccancel)
00091 #  define CDISABLE   bl JUMPTARGET(__librt_disable_asynccancel)
00092 #  if defined HAVE_AS_REL16 && defined PIC
00093 #   undef CGOTSETUP
00094 #   define CGOTSETUP                                           \
00095     bcl 20,31,1f;                                              \
00096  1: stw 30,44(1);                                              \
00097     mflr 30;                                                   \
00098     addis 30,30,_GLOBAL_OFFSET_TABLE-1b@ha;                           \
00099     addi 30,30,_GLOBAL_OFFSET_TABLE-1b@l
00100 #   undef CGOTRESTORE
00101 #   define CGOTRESTORE                                                \
00102     lwz 30,44(1)
00103 #  endif
00104 # endif
00105 
00106 # ifdef HAVE_TLS_SUPPORT
00107 #  ifndef __ASSEMBLER__
00108 #   define SINGLE_THREAD_P                                     \
00109   __builtin_expect (THREAD_GETMEM (THREAD_SELF, p_multiple_threads) == 0, 1)
00110 #  else
00111 #   define SINGLE_THREAD_P                                     \
00112   lwz 10,MULTIPLE_THREADS_OFFSET(2);                                  \
00113   cmpwi 10,0
00114 #  endif
00115 # else
00116 #  if !defined NOT_IN_libc
00117 #   define __local_multiple_threads __libc_multiple_threads
00118 #  else
00119 #   define __local_multiple_threads __librt_multiple_threads
00120 #  endif
00121 #  ifndef __ASSEMBLER__
00122 extern int __local_multiple_threads attribute_hidden;
00123 #   define SINGLE_THREAD_P __builtin_expect (__local_multiple_threads == 0, 1)
00124 #  else
00125 #   if !defined PIC
00126 #    define SINGLE_THREAD_P                                    \
00127   lis 10,__local_multiple_threads@ha;                                 \
00128   lwz 10,__local_multiple_threads@l(10);                       \
00129   cmpwi 10,0
00130 #   else
00131 #    ifdef HAVE_ASM_PPC_REL16
00132 #     define SINGLE_THREAD_P                                          \
00133   mflr 9;                                                      \
00134   bcl 20,31,1f;                                                       \
00135 1:mflr 10;                                                     \
00136   addis 10,10,__local_multiple_threads-1b@ha;                         \
00137   lwz 10,__local_multiple_threads-1b@l(10);                           \
00138   mtlr 9;                                                      \
00139   cmpwi 10,0
00140 #    else
00141 #     define SINGLE_THREAD_P                                          \
00142   mflr 9;                                                      \
00143   bl _GLOBAL_OFFSET_TABLE_@local-4;                                   \
00144   mflr 10;                                                     \
00145   mtlr 9;                                                      \
00146   lwz 10,__local_multiple_threads@got(10);                            \
00147   lwz 10,0(10);                                                       \
00148   cmpwi 10,0
00149 #    endif
00150 #   endif
00151 #  endif
00152 # endif
00153 
00154 #elif !defined __ASSEMBLER__
00155 
00156 /* This code should never be used but we define it anyhow.  */
00157 # define SINGLE_THREAD_P (1)
00158 
00159 #endif