Back to index

glibc  2.9
sysdep-cancel.h
Go to the documentation of this file.
00001 /* Copyright (C) 2002, 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>, 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 <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 
00030 # if USE___THREAD
00031 #  ifndef NOT_IN_libc
00032 #   define SYSDEP_CANCEL_ERRNO __libc_errno
00033 #  else
00034 #   define SYSDEP_CANCEL_ERRNO errno
00035 #  endif
00036 #  define SYSDEP_CANCEL_ERROR(args)                                         \
00037 .section .gnu.linkonce.t.__syscall_error_##args, "ax";                      \
00038      .align 32;                                                             \
00039      .proc __syscall_error_##args;                                   \
00040      .global __syscall_error_##args;                                        \
00041      .hidden __syscall_error_##args;                                        \
00042      .size __syscall_error_##args, 64;                                      \
00043 __syscall_error_##args:                                                     \
00044      .prologue;                                                             \
00045      .regstk args, 5, args, 0;                                              \
00046      .save ar.pfs, loc0;                                             \
00047      .save rp, loc1;                                                 \
00048      .body;                                                          \
00049      addl loc4 = @ltoff(@tprel(SYSDEP_CANCEL_ERRNO)), gp;;                  \
00050      ld8 loc4 = [loc4];                                                     \
00051      mov rp = loc1;;                                                 \
00052      mov r8 = -1;                                                    \
00053      add loc4 = loc4, r13;;                                          \
00054      st4 [loc4] = loc3;                                                     \
00055      mov ar.pfs = loc0
00056 # else
00057 #  define SYSDEP_CANCEL_ERROR(args)                                         \
00058 .section .gnu.linkonce.t.__syscall_error_##args, "ax";                      \
00059      .align 32;                                                             \
00060      .proc __syscall_error_##args;                                   \
00061      .global __syscall_error_##args;                                        \
00062      .hidden __syscall_error_##args;                                        \
00063      .size __syscall_error_##args, 64;                                      \
00064 __syscall_error_##args:                                                     \
00065      .prologue;                                                             \
00066      .regstk args, 5, args, 0;                                              \
00067      .save ar.pfs, loc0;                                             \
00068      .save rp, loc1;                                                 \
00069      .body;                                                          \
00070      mov loc4 = r1;;                                                 \
00071      br.call.sptk.many b0 = __errno_location;;                              \
00072      st4 [r8] = loc3;                                                       \
00073      mov r1 = loc4;                                                  \
00074      mov rp = loc1;                                                  \
00075      mov r8 = -1;                                                    \
00076      mov ar.pfs = loc0
00077 # endif
00078 
00079 # ifndef USE_DL_SYSINFO
00080 
00081 #  define PSEUDO(name, syscall_name, args)                                  \
00082 .text;                                                               \
00083 ENTRY (name)                                                         \
00084      adds r14 = MULTIPLE_THREADS_OFFSET, r13;;                              \
00085      ld4 r14 = [r14];                                                       \
00086      mov r15 = SYS_ify(syscall_name);;                                      \
00087      cmp4.ne p6, p7 = 0, r14;                                               \
00088 (p6) br.cond.spnt .Lpseudo_cancel;;                                         \
00089      break __BREAK_SYSCALL;;                                                \
00090      cmp.eq p6,p0=-1,r10;                                            \
00091 (p6) br.cond.spnt.few __syscall_error;                                      \
00092      ret;;                                                           \
00093      .endp name;                                                     \
00094      .proc __GC_##name;                                                     \
00095      .globl __GC_##name;                                             \
00096      .hidden __GC_##name;                                            \
00097 __GC_##name:                                                         \
00098 .Lpseudo_cancel:                                                     \
00099      .prologue;                                                             \
00100      .regstk args, 5, args, 0;                                              \
00101      .save ar.pfs, loc0;                                             \
00102      alloc loc0 = ar.pfs, args, 5, args, 0;                                 \
00103      .save rp, loc1;                                                 \
00104      mov loc1 = rp;;                                                 \
00105      .body;                                                          \
00106      CENABLE;;                                                              \
00107      mov loc2 = r8;                                                  \
00108      COPY_ARGS_##args                                                       \
00109      mov r15 = SYS_ify(syscall_name);                                       \
00110      break __BREAK_SYSCALL;;                                                \
00111      mov loc3 = r8;                                                  \
00112      mov loc4 = r10;                                                 \
00113      mov out0 = loc2;                                                       \
00114      CDISABLE;;                                                             \
00115      cmp.eq p6,p0=-1,loc4;                                           \
00116 (p6) br.cond.spnt.few __syscall_error_##args;                               \
00117      mov r8 = loc3;                                                  \
00118      mov rp = loc1;                                                  \
00119      mov ar.pfs = loc0;                                                     \
00120 .Lpseudo_end:                                                        \
00121      ret;                                                            \
00122      .endp __GC_##name;                                                     \
00123      SYSDEP_CANCEL_ERROR(args)
00124 
00125 # else /* USE_DL_SYSINFO */
00126 
00127 #  define PSEUDO(name, syscall_name, args)                                  \
00128 .text;                                                               \
00129 ENTRY (name)                                                         \
00130      .prologue;                                                             \
00131      adds r2 = SYSINFO_OFFSET, r13;                                         \
00132      adds r14 = MULTIPLE_THREADS_OFFSET, r13;                               \
00133      .save ar.pfs, r11;                                                     \
00134      mov r11 = ar.pfs;;                                                     \
00135      .body;                                                          \
00136      ld4 r14 = [r14];                                                       \
00137      ld8 r2 = [r2];                                                  \
00138      mov r15 = SYS_ify(syscall_name);;                                      \
00139      cmp4.ne p6, p7 = 0, r14;                                               \
00140      mov b7 = r2;                                                    \
00141 (p6) br.cond.spnt .Lpseudo_cancel;                                   \
00142      br.call.sptk.many b6 = b7;;                                     \
00143      mov ar.pfs = r11;                                                      \
00144      cmp.eq p6,p0 = -1, r10;                                                \
00145 (p6) br.cond.spnt.few __syscall_error;                                      \
00146      ret;;                                                           \
00147      .endp name;                                                     \
00148      .proc __GC_##name;                                                     \
00149      .globl __GC_##name;                                             \
00150      .hidden __GC_##name;                                            \
00151 __GC_##name:                                                         \
00152 .Lpseudo_cancel:                                                     \
00153      .prologue;                                                             \
00154      .regstk args, 5, args, 0;                                              \
00155      .save ar.pfs, loc0;                                             \
00156      alloc loc0 = ar.pfs, args, 5, args, 0;                                 \
00157      adds loc4 = SYSINFO_OFFSET, r13;                                       \
00158      .save rp, loc1;                                                 \
00159      mov loc1 = rp;;                                                 \
00160      .body;                                                          \
00161      ld8 loc4 = [loc4];                                                     \
00162      CENABLE;;                                                              \
00163      mov loc2 = r8;                                                  \
00164      mov b7 = loc4;                                                  \
00165      COPY_ARGS_##args                                                       \
00166      mov r15 = SYS_ify(syscall_name);                                       \
00167      br.call.sptk.many b6 = b7;;                                     \
00168      mov loc3 = r8;                                                  \
00169      mov loc4 = r10;                                                 \
00170      mov out0 = loc2;                                                       \
00171      CDISABLE;;                                                             \
00172      cmp.eq p6,p0=-1,loc4;                                           \
00173 (p6) br.cond.spnt.few __syscall_error_##args;                               \
00174      mov r8 = loc3;                                                  \
00175      mov rp = loc1;                                                  \
00176      mov ar.pfs = loc0;                                                     \
00177 .Lpseudo_end:                                                        \
00178      ret;                                                            \
00179      .endp __GC_##name;                                                     \
00180      SYSDEP_CANCEL_ERROR(args)
00181 
00182 # endif /* USE_DL_SYSINFO */
00183 
00184 # undef PSEUDO_END
00185 # define PSEUDO_END(name) .endp
00186 
00187 # ifdef IS_IN_libpthread
00188 #  define CENABLE    br.call.sptk.many b0 = __pthread_enable_asynccancel
00189 #  define CDISABLE   br.call.sptk.many b0 = __pthread_disable_asynccancel
00190 # elif !defined NOT_IN_libc
00191 #  define CENABLE    br.call.sptk.many b0 = __libc_enable_asynccancel
00192 #  define CDISABLE   br.call.sptk.many b0 = __libc_disable_asynccancel
00193 # elif defined IS_IN_librt
00194 #  define CENABLE    br.call.sptk.many b0 = __librt_enable_asynccancel
00195 #  define CDISABLE   br.call.sptk.many b0 = __librt_disable_asynccancel
00196 # else
00197 #  error Unsupported library
00198 # endif
00199 
00200 # define COPY_ARGS_0 /* Nothing */
00201 # define COPY_ARGS_1 COPY_ARGS_0 mov out0 = in0;
00202 # define COPY_ARGS_2 COPY_ARGS_1 mov out1 = in1;
00203 # define COPY_ARGS_3 COPY_ARGS_2 mov out2 = in2;
00204 # define COPY_ARGS_4 COPY_ARGS_3 mov out3 = in3;
00205 # define COPY_ARGS_5 COPY_ARGS_4 mov out4 = in4;
00206 # define COPY_ARGS_6 COPY_ARGS_5 mov out5 = in5;
00207 # define COPY_ARGS_7 COPY_ARGS_6 mov out6 = in6;
00208 
00209 # ifndef __ASSEMBLER__
00210 #  define SINGLE_THREAD_P \
00211   __builtin_expect (THREAD_GETMEM (THREAD_SELF, header.multiple_threads) == 0, 1)
00212 # else
00213 #  define SINGLE_THREAD_P \
00214   adds r14 = MULTIPLE_THREADS_OFFSET, r13 ;; ld4 r14 = [r14] ;; cmp4.ne p6, p7 = 0, r14
00215 # endif
00216 
00217 #elif !defined __ASSEMBLER__
00218 
00219 # define SINGLE_THREAD_P (1)
00220 # define NO_CANCELLATION 1
00221 
00222 #endif
00223 
00224 #ifndef __ASSEMBLER__
00225 # define RTLD_SINGLE_THREAD_P \
00226   __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
00227                                header.multiple_threads) == 0, 1)
00228 #endif