Back to index

glibc  2.9
sysdep-cancel.h
Go to the documentation of this file.
00001 /* Copyright (C) 2003, 2004 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 <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        .text;                                                        \
00031 L(pseudo_cancel):                                                    \
00032        STM_##args                                                    \
00033        stmg   %r13,%r15,104(%r15);                                   \
00034        lgr    %r14,%r15;                                             \
00035        aghi   %r15,-160;                                             \
00036        stg    %r14,0(%r15);                                          \
00037        brasl  %r14,CENABLE;                                          \
00038        lgr    %r0,%r2;                                               \
00039        LM_##args                                                     \
00040        DO_CALL(syscall_name, args);                                         \
00041        lgr    %r13,%r2;                                              \
00042        lgr    %r2,%r0;                                               \
00043        brasl  %r14,CDISABLE;                                                \
00044        lgr    %r2,%r13;                                              \
00045        lmg    %r13,%r15,104+160(%r15);                               \
00046        j      L(pseudo_check);                                       \
00047 ENTRY(name)                                                          \
00048        SINGLE_THREAD_P                                                      \
00049        jne    L(pseudo_cancel);                                      \
00050        DO_CALL(syscall_name, args);                                         \
00051 L(pseudo_check):                                                     \
00052        lghi   %r4,-4095;                                             \
00053        clgr   %r2,%r4;                                               \
00054        jgnl   SYSCALL_ERROR_LABEL;                                   \
00055 L(pseudo_end):
00056 
00057 # ifdef IS_IN_libpthread
00058 #  define CENABLE    __pthread_enable_asynccancel
00059 #  define CDISABLE   __pthread_disable_asynccancel
00060 #  define __local_multiple_threads __pthread_multiple_threads
00061 # elif !defined NOT_IN_libc
00062 #  define CENABLE    __libc_enable_asynccancel
00063 #  define CDISABLE   __libc_disable_asynccancel
00064 #  define __local_multiple_threads __libc_multiple_threads
00065 # else
00066 #  define CENABLE    __librt_enable_asynccancel@PLT
00067 #  define CDISABLE   __librt_disable_asynccancel@PLT
00068 # endif
00069 
00070 #define STM_0        /* Nothing */
00071 #define STM_1        stg %r2,16(%r15);
00072 #define STM_2        stmg %r2,%r3,16(%r15);
00073 #define STM_3        stmg %r2,%r4,16(%r15);
00074 #define STM_4        stmg %r2,%r5,16(%r15);
00075 #define STM_5        stmg %r2,%r5,16(%r15);
00076 
00077 #define LM_0         /* Nothing */
00078 #define LM_1         lg %r2,16+160(%r15);
00079 #define LM_2         lmg %r2,%r3,16+160(%r15);
00080 #define LM_3         lmg %r2,%r4,16+160(%r15);
00081 #define LM_4         lmg %r2,%r5,16+160(%r15);
00082 #define LM_5         lmg %r2,%r5,16+160(%r15);
00083 
00084 # if !defined NOT_IN_libc || defined IS_IN_libpthread
00085 #  ifndef __ASSEMBLER__
00086 extern int __local_multiple_threads attribute_hidden;
00087 #   define SINGLE_THREAD_P \
00088   __builtin_expect (__local_multiple_threads == 0, 1)
00089 #  else
00090 #   define SINGLE_THREAD_P \
00091        larl   %r1,__local_multiple_threads;                                 \
00092        icm    %r0,15,0(%r1);
00093 #  endif
00094 
00095 # else
00096 
00097 #  ifndef __ASSEMBLER__
00098 #   define SINGLE_THREAD_P \
00099   __builtin_expect (THREAD_GETMEM (THREAD_SELF,                             \
00100                                p_header.data.multiple_threads) == 0, 1)
00101 #  else
00102 #   define SINGLE_THREAD_P \
00103        ear    %r1,%a0;                                               \
00104        sllg   %r1,%r1,32;                                            \
00105        ear    %r1,%a1;                                               \
00106        icm    %r1,15,MULTIPLE_THREADS_OFFSET(%r1);
00107 #  endif
00108 
00109 # endif
00110 
00111 #elif !defined __ASSEMBLER__
00112 
00113 /* This code should never be used but we define it anyhow.  */
00114 # define SINGLE_THREAD_P (1)
00115 
00116 #endif