Back to index

glibc  2.9
sysdep-cancel.h
Go to the documentation of this file.
00001 /* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
00002    This file is part of the GNU C Library.
00003    Contributed by Alexandre Oliva <aoliva@redhat.com>
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 #include <pt-machine.h>
00023 #ifndef __ASSEMBLER__
00024 # include <linuxthreads/internals.h>
00025 #endif
00026 
00027 #if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt
00028 
00029 # undef PSEUDO
00030 # define PSEUDO(name, syscall_name, args)                      \
00031   .text       ;                                                       \
00032  ENTRY (name)                                                  \
00033   PUSHARGS_##args                                              \
00034   DOARGS_##args                                                       \
00035   SINGLE_THREAD_P;                                             \
00036   bne L(pseudo_cancel);                                               \
00037   mov SYS_ify (syscall_name),d0;                               \
00038   syscall 0                                                    \
00039   POPARGS_##args ;                                             \
00040   cmp -126,d0;                                                        \
00041   bls L(pseudo_end);                                           \
00042   jmp SYSCALL_ERROR_LABEL;                                     \
00043  L(pseudo_cancel):                                             \
00044   add -(16+STACK_SPACE (args)),sp;                             \
00045   SAVE_ARGS_##args                                             \
00046   CENABLE                                                      \
00047   mov d0,r0;                                                   \
00048   LOAD_ARGS_##args                                             \
00049   mov SYS_ify (syscall_name),d0;                               \
00050   syscall 0;                                                   \
00051   mov d0,(12,sp);                                              \
00052   mov r0,d0;                                                   \
00053   CDISABLE                                                     \
00054   mov (12,sp),d0;                                              \
00055   add +16+STACK_SPACE (args),sp                                       \
00056   POPARGS_##args ;                                             \
00057   cmp -126,d0;                                                        \
00058   bls L(pseudo_end);                                           \
00059   jmp SYSCALL_ERROR_LABEL;                                     \
00060  L(pseudo_end):                                                       \
00061   mov d0,a0
00062 
00063 /* Reserve up to 2 stack slots for a0 and d1, but fewer than that if
00064    we don't have that many arguments.  */
00065 # define STACK_SPACE(n) (((((n) < 3) * (2 - (n))) + 2) * 4)
00066 
00067 # define SAVE_ARGS_0
00068 # define SAVE_ARGS_1 mov a0,(20,sp) ;
00069 # define SAVE_ARGS_2 SAVE_ARGS_1 mov d1,(24,sp) ;
00070 # define SAVE_ARGS_3 SAVE_ARGS_2
00071 # define SAVE_ARGS_4 SAVE_ARGS_3
00072 # define SAVE_ARGS_5 SAVE_ARGS_4
00073 # define SAVE_ARGS_6 SAVE_ARGS_5
00074 
00075 # define LOAD_ARGS_0
00076 # define LOAD_ARGS_1 mov (20,sp),a0 ;
00077 # define LOAD_ARGS_2 LOAD_ARGS_1 mov (24,sp),d1 ;
00078 # define LOAD_ARGS_3 LOAD_ARGS_2
00079 # define LOAD_ARGS_4 LOAD_ARGS_3
00080 # define LOAD_ARGS_5 LOAD_ARGS_4
00081 # define LOAD_ARGS_6 LOAD_ARGS_5
00082 
00083 # ifdef IS_IN_libpthread
00084 #  define CENABLE    call __pthread_enable_asynccancel,[],0;
00085 #  define CDISABLE   call __pthread_disable_asynccancel,[],0;
00086 # elif defined IS_IN_librt
00087 #  ifdef PIC
00088 #   define CENABLE   movm [a2],(sp); \
00089                      1: mov pc,a2; \
00090                      add _GLOBAL_OFFSET_TABLE_-(1b-.),a2; \
00091                      call +__librt_enable_asynccancel@PLT,[],0; \
00092                      movm (sp),[a2];
00093 #   define CENABLE   movm [a2],(sp); \
00094                      1: mov pc,a2; \
00095                      add _GLOBAL_OFFSET_TABLE_-(1b-.),a2; \
00096                      call +__librt_disable_asynccancel@PLT,[],0; \
00097                      movm (sp),[a2];
00098 #  else
00099 #   define CENABLE   call +__librt_enable_asynccancel,[],0;
00100 #   define CDISABLE  call +__librt_disable_asynccancel,[],0;
00101 #  endif
00102 # else
00103 #  define CENABLE    call +__libc_enable_asynccancel,[],0;
00104 #  define CDISABLE   call +__libc_disable_asynccancel,[],0;
00105 # endif
00106 
00107 #if !defined NOT_IN_libc
00108 # define __local_multiple_threads __libc_multiple_threads
00109 #elif defined IS_IN_libpthread
00110 # define __local_multiple_threads __pthread_multiple_threads
00111 #else
00112 # define __local_multiple_threads __librt_multiple_threads
00113 #endif
00114 
00115 # ifndef __ASSEMBLER__
00116 #  if defined FLOATING_STACKS && USE___THREAD && defined PIC
00117 #   define SINGLE_THREAD_P \
00118   __builtin_expect (THREAD_GETMEM (THREAD_SELF,                             \
00119                                p_header.data.multiple_threads) == 0, 1)
00120 #  else
00121 extern int __local_multiple_threads
00122 #   if !defined NOT_IN_libc || defined IS_IN_libpthread
00123   attribute_hidden;
00124 #   else
00125   ;
00126 #   endif
00127 #   define SINGLE_THREAD_P __builtin_expect (__local_multiple_threads == 0, 1)
00128 #  endif
00129 # else
00130 #  if !defined PIC
00131 #   define SINGLE_THREAD_P \
00132        mov (+__local_multiple_threads),d0; \
00133        cmp 0,d0
00134 #  elif !defined NOT_IN_libc || defined IS_IN_libpthread
00135 #   define SINGLE_THREAD_P \
00136        movm [a2],(sp); \
00137      1: mov pc,a2; \
00138        add _GLOBAL_OFFSET_TABLE_-(1b-.),a2; \
00139        mov (+__local_multiple_threads@GOTOFF,a2),d0; \
00140        movm (sp),[a2]; \
00141        cmp 0,d0
00142 #  else
00143 #   define SINGLE_THREAD_P \
00144        movm [a2],(sp); \
00145      1: mov pc,a2; \
00146        add _GLOBAL_OFFSET_TABLE_-(1b-.),a2; \
00147        mov (+__local_multiple_threads@GOT,a2),a2; \
00148        mov (a2),d0; \
00149        movm (sp),[a2]; \
00150        cmp 0,d0
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