Back to index

glibc  2.9
sysdep-cancel.h
Go to the documentation of this file.
00001 /* Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
00002    This file is part of the GNU C Library.
00003 
00004    The GNU C Library is free software; you can redistribute it and/or
00005    modify it under the terms of the GNU Lesser General Public
00006    License as published by the Free Software Foundation; either
00007    version 2.1 of the License, or (at your option) any later version.
00008 
00009    The GNU C Library is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY; without even the implied warranty of
00011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012    Lesser General Public License for more details.
00013 
00014    You should have received a copy of the GNU Lesser General Public
00015    License along with the GNU C Library; if not, write to the Free
00016    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00017    02111-1307 USA.  */
00018 
00019 #include <sysdep.h>
00020 #include <tls.h>
00021 #ifndef __ASSEMBLER__
00022 # include <nptl/pthreadP.h>
00023 #endif
00024 
00025 #if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt
00026 
00027 # define _IMM12 #-12
00028 # define _IMM16 #-16
00029 # define _IMP16 #16
00030 # undef PSEUDO
00031 # define PSEUDO(name, syscall_name, args) \
00032   .text; \
00033   ENTRY (name); \
00034   .Lpseudo_start: \
00035     SINGLE_THREAD_P; \
00036     bf .Lpseudo_cancel; \
00037     .type __##syscall_name##_nocancel,@function; \
00038     .globl __##syscall_name##_nocancel; \
00039     __##syscall_name##_nocancel: \
00040     DO_CALL (syscall_name, args); \
00041     mov r0,r1; \
00042     mov _IMM12,r2; \
00043     shad r2,r1; \
00044     not r1,r1; \
00045     tst r1,r1; \
00046     bt .Lsyscall_error; \
00047     bra .Lpseudo_end; \
00048      nop; \
00049     .size __##syscall_name##_nocancel,.-__##syscall_name##_nocancel; \
00050  .Lpseudo_cancel: \
00051     sts.l pr,@-r15; \
00052     cfi_adjust_cfa_offset (4); \
00053     cfi_rel_offset (pr, 0); \
00054     add _IMM16,r15; \
00055     cfi_adjust_cfa_offset (16); \
00056     SAVE_ARGS_##args; \
00057     CENABLE; \
00058     LOAD_ARGS_##args; \
00059     add _IMP16,r15; \
00060     cfi_adjust_cfa_offset (-16); \
00061     lds.l @r15+,pr; \
00062     cfi_adjust_cfa_offset (-4); \
00063     cfi_restore (pr); \
00064     DO_CALL(syscall_name, args); \
00065     SYSCALL_INST_PAD; \
00066     sts.l pr,@-r15; \
00067     cfi_adjust_cfa_offset (4); \
00068     cfi_rel_offset (pr, 0); \
00069     mov.l r0,@-r15; \
00070     cfi_adjust_cfa_offset (4); \
00071     cfi_rel_offset (r0, 0); \
00072     CDISABLE; \
00073     mov.l @r15+,r0; \
00074     cfi_adjust_cfa_offset (-4); \
00075     lds.l @r15+,pr; \
00076     cfi_adjust_cfa_offset (-4); \
00077     cfi_restore (pr); \
00078     mov r0,r1; \
00079     mov _IMM12,r2; \
00080     shad r2,r1; \
00081     not r1,r1; \
00082     tst r1,r1; \
00083     bf .Lpseudo_end; \
00084  .Lsyscall_error: \
00085     SYSCALL_ERROR_HANDLER; \
00086  .Lpseudo_end:
00087 
00088 # undef PSEUDO_END
00089 # define PSEUDO_END(sym) \
00090   END (sym)
00091 
00092 # define SAVE_ARGS_0 /* Nothing.  */
00093 # define SAVE_ARGS_1 SAVE_ARGS_0; mov.l r4,@(0,r15); cfi_offset (r4,-4)
00094 # define SAVE_ARGS_2 SAVE_ARGS_1; mov.l r5,@(4,r15); cfi_offset (r5,-8)
00095 # define SAVE_ARGS_3 SAVE_ARGS_2; mov.l r6,@(8,r15); cfi_offset (r6,-12)
00096 # define SAVE_ARGS_4 SAVE_ARGS_3; mov.l r7,@(12,r15); cfi_offset (r7,-16)
00097 # define SAVE_ARGS_5 SAVE_ARGS_4
00098 # define SAVE_ARGS_6 SAVE_ARGS_5
00099 
00100 # define LOAD_ARGS_0 /* Nothing.  */
00101 # define LOAD_ARGS_1 LOAD_ARGS_0; mov.l @(0,r15),r4
00102 # define LOAD_ARGS_2 LOAD_ARGS_1; mov.l @(4,r15),r5
00103 # define LOAD_ARGS_3 LOAD_ARGS_2; mov.l @(8,r15),r6
00104 # define LOAD_ARGS_4 LOAD_ARGS_3; mov.l @(12,r15),r7
00105 # define LOAD_ARGS_5 LOAD_ARGS_4
00106 # define LOAD_ARGS_6 LOAD_ARGS_5
00107 
00108 # ifdef IS_IN_libpthread
00109 #  define __local_enable_asynccancel      __pthread_enable_asynccancel
00110 #  define __local_disable_asynccancel     __pthread_disable_asynccancel
00111 # elif !defined NOT_IN_libc
00112 #  define __local_enable_asynccancel      __libc_enable_asynccancel
00113 #  define __local_disable_asynccancel     __libc_disable_asynccancel
00114 # elif defined IS_IN_librt
00115 #  define __local_enable_asynccancel      __librt_enable_asynccancel
00116 #  define __local_disable_asynccancel     __librt_disable_asynccancel
00117 # else
00118 #  error Unsupported library
00119 # endif
00120 
00121 # define CENABLE \
00122        mov.l 1f,r0; \
00123        bsrf r0; \
00124         nop; \
00125      0: bra 2f; \
00126         mov r0,r2; \
00127        .align 2; \
00128      1: .long __local_enable_asynccancel - 0b; \
00129      2:
00130 
00131 # define CDISABLE \
00132        mov.l 1f,r0; \
00133        bsrf r0; \
00134         mov r2,r4; \
00135      0: bra 2f; \
00136         nop; \
00137        .align 2; \
00138      1: .long __local_disable_asynccancel - 0b; \
00139      2:
00140 
00141 # ifndef __ASSEMBLER__
00142 #  define SINGLE_THREAD_P \
00143   __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
00144                                header.multiple_threads) == 0, 1)
00145 # else
00146 #  define SINGLE_THREAD_P \
00147        stc gbr,r0; \
00148        mov.w 0f,r1; \
00149        sub r1,r0; \
00150        mov.l @(MULTIPLE_THREADS_OFFSET,r0),r0; \
00151        bra 1f; \
00152         tst r0,r0; \
00153      0: .word TLS_PRE_TCB_SIZE; \
00154      1:
00155 
00156 # endif
00157 
00158 #elif !defined __ASSEMBLER__
00159 
00160 # define SINGLE_THREAD_P (1)
00161 # define NO_CANCELLATION 1
00162 
00163 #endif
00164 
00165 #ifndef __ASSEMBLER__
00166 # define RTLD_SINGLE_THREAD_P \
00167   __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
00168                                header.multiple_threads) == 0, 1)
00169 #endif