Back to index

glibc  2.9
sysdep-cancel.h
Go to the documentation of this file.
00001 /* Copyright (C) 2003, 2004, 2006 Free Software Foundation, Inc.
00002    This file is part of the GNU C Library.
00003    Contributed by Jakub Jelinek <jakub@redhat.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 <nptl/pthreadP.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        .text;                                                        \
00031 L(pseudo_cancel):                                                    \
00032        cfi_startproc;                                                       \
00033        STM_##args                                                    \
00034        stmg   %r13,%r15,104(%r15);                                   \
00035        cfi_offset (%r15,-40);                                               \
00036        cfi_offset (%r14,-48);                                               \
00037        cfi_offset (%r13,-56);                                               \
00038        lgr    %r14,%r15;                                             \
00039        aghi   %r15,-160;                                             \
00040        cfi_adjust_cfa_offset (160);                                         \
00041        stg    %r14,0(%r15);                                          \
00042        brasl  %r14,CENABLE;                                          \
00043        lgr    %r0,%r2;                                               \
00044        LM_##args                                                     \
00045        .if SYS_ify (syscall_name) < 256;                             \
00046        svc SYS_ify (syscall_name);                                   \
00047        .else;                                                        \
00048        lghi %r1,SYS_ify (syscall_name);                              \
00049        svc 0;                                                        \
00050        .endif;                                                              \
00051        LR7_##args                                                    \
00052        lgr    %r13,%r2;                                              \
00053        lgr    %r2,%r0;                                               \
00054        brasl  %r14,CDISABLE;                                                \
00055        lgr    %r2,%r13;                                              \
00056        lmg    %r13,%r15,104+160(%r15);                               \
00057        cfi_endproc;                                                  \
00058        j      L(pseudo_check);                                       \
00059 ENTRY(name)                                                          \
00060        SINGLE_THREAD_P                                                      \
00061        jne    L(pseudo_cancel);                                      \
00062 .type  __##syscall_name##_nocancel,@function;                               \
00063 .globl __##syscall_name##_nocancel;                                         \
00064 __##syscall_name##_nocancel:                                                \
00065        DO_CALL(syscall_name, args);                                         \
00066 L(pseudo_check):                                                     \
00067        lghi   %r4,-4095;                                             \
00068        clgr   %r2,%r4;                                               \
00069        jgnl   SYSCALL_ERROR_LABEL;                                   \
00070 .size  __##syscall_name##_nocancel,.-__##syscall_name##_nocancel;           \
00071 L(pseudo_end):
00072 
00073 # ifdef IS_IN_libpthread
00074 #  define CENABLE    __pthread_enable_asynccancel
00075 #  define CDISABLE   __pthread_disable_asynccancel
00076 #  define __local_multiple_threads __pthread_multiple_threads
00077 # elif !defined NOT_IN_libc
00078 #  define CENABLE    __libc_enable_asynccancel
00079 #  define CDISABLE   __libc_disable_asynccancel
00080 #  define __local_multiple_threads __libc_multiple_threads
00081 # elif defined IS_IN_librt
00082 #  define CENABLE    __librt_enable_asynccancel
00083 #  define CDISABLE   __librt_disable_asynccancel
00084 # else
00085 #  error Unsupported library
00086 # endif
00087 
00088 #define STM_0        /* Nothing */
00089 #define STM_1        stg %r2,16(%r15);
00090 #define STM_2        stmg %r2,%r3,16(%r15);
00091 #define STM_3        stmg %r2,%r4,16(%r15);
00092 #define STM_4        stmg %r2,%r5,16(%r15);
00093 #define STM_5        stmg %r2,%r5,16(%r15);
00094 #define STM_6        stmg %r2,%r7,16(%r15);
00095 
00096 #define LM_0         /* Nothing */
00097 #define LM_1         lg %r2,16+160(%r15);
00098 #define LM_2         lmg %r2,%r3,16+160(%r15);
00099 #define LM_3         lmg %r2,%r4,16+160(%r15);
00100 #define LM_4         lmg %r2,%r5,16+160(%r15);
00101 #define LM_5         lmg %r2,%r5,16+160(%r15);
00102 #define LM_6         lmg %r2,%r5,16+160(%r15); \
00103                      cfi_offset (%r7, -104); \
00104                      lg %r7,160+160(%r15);
00105 
00106 #define LR7_0        /* Nothing */
00107 #define LR7_1        /* Nothing */
00108 #define LR7_2        /* Nothing */
00109 #define LR7_3        /* Nothing */
00110 #define LR7_4        /* Nothing */
00111 #define LR7_5        /* Nothing */
00112 #define LR7_6        lg %r7,56+160(%r15); \
00113                      cfi_restore (%r7);
00114 
00115 # if defined IS_IN_libpthread || !defined NOT_IN_libc
00116 #  ifndef __ASSEMBLER__
00117 extern int __local_multiple_threads attribute_hidden;
00118 #   define SINGLE_THREAD_P \
00119   __builtin_expect (__local_multiple_threads == 0, 1)
00120 #  else
00121 #   define SINGLE_THREAD_P \
00122        larl   %r1,__local_multiple_threads;                                 \
00123        icm    %r0,15,0(%r1);
00124 #  endif
00125 
00126 # else
00127 
00128 #  ifndef __ASSEMBLER__
00129 #   define SINGLE_THREAD_P \
00130   __builtin_expect (THREAD_GETMEM (THREAD_SELF,                             \
00131                                header.multiple_threads) == 0, 1)
00132 #  else
00133 #   define SINGLE_THREAD_P \
00134        ear    %r1,%a0;                                               \
00135        sllg   %r1,%r1,32;                                            \
00136        ear    %r1,%a1;                                               \
00137        icm    %r1,15,MULTIPLE_THREADS_OFFSET(%r1);
00138 #  endif
00139 
00140 # endif
00141 
00142 #elif !defined __ASSEMBLER__
00143 
00144 # define SINGLE_THREAD_P (1)
00145 # define NO_CANCELLATION 1
00146 
00147 #endif
00148 
00149 #ifndef __ASSEMBLER__
00150 # define RTLD_SINGLE_THREAD_P \
00151   __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
00152                                header.multiple_threads) == 0, 1)
00153 #endif