Back to index

glibc  2.9
sysdep-cancel.h
Go to the documentation of this file.
00001 /* Copyright (C) 2003 Free Software Foundation, Inc.
00002    This file is part of the GNU C Library.
00003    Contributed by Franz Sirl <Franz.Sirl-kernel@lauterbach.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   .section ".text";                                            \
00031   ENTRY (name)                                                        \
00032     SINGLE_THREAD_P;                                           \
00033     bne- .Lpseudo_cancel;                                      \
00034     DO_CALL (SYS_ify (syscall_name));                                 \
00035     PSEUDO_RET;                                                       \
00036   .Lpseudo_cancel:                                             \
00037     stdu 1,-128(1);                                            \
00038     mflr 9;                                                    \
00039     std  9,128+16(1);                                                 \
00040     DOCARGS_##args;  /* save syscall args around CENABLE.  */  \
00041     CENABLE;                                                   \
00042     std  3,72(1);    /* store CENABLE return value (MASK).  */ \
00043     UNDOCARGS_##args;       /* restore syscall args.  */                     \
00044     DO_CALL (SYS_ify (syscall_name));                                 \
00045     mfcr 0;          /* save CR/R3 around CDISABLE.  */        \
00046     std  3,64(1);                                                     \
00047     std  0,8(1);                                               \
00048     ld   3,72(1);    /* pass MASK to CDISABLE.  */                    \
00049     CDISABLE;                                                  \
00050     ld   9,128+16(1);                                                 \
00051     ld   0,8(1);     /* restore CR/R3. */                      \
00052     ld   3,64(1);                                                     \
00053     mtlr 9;                                                    \
00054     mtcr 0;                                                    \
00055     addi 1,1,128;
00056 
00057 # define DOCARGS_0
00058 # define UNDOCARGS_0
00059 
00060 # define DOCARGS_1   std 3,80(1); DOCARGS_0
00061 # define UNDOCARGS_1 ld 3,80(1); UNDOCARGS_0
00062 
00063 # define DOCARGS_2   std 4,88(1); DOCARGS_1
00064 # define UNDOCARGS_2 ld 4,88(1); UNDOCARGS_1
00065 
00066 # define DOCARGS_3   std 5,96(1); DOCARGS_2
00067 # define UNDOCARGS_3 ld 5,96(1); UNDOCARGS_2
00068 
00069 # define DOCARGS_4   std 6,104(1); DOCARGS_3
00070 # define UNDOCARGS_4 ld 6,104(1); UNDOCARGS_3
00071 
00072 # define DOCARGS_5   std 7,112(1); DOCARGS_4
00073 # define UNDOCARGS_5 ld 7,112(1); UNDOCARGS_4
00074 
00075 # define DOCARGS_6   std 8,120(1); DOCARGS_5
00076 # define UNDOCARGS_6 ld 8,120(1); UNDOCARGS_5
00077 
00078 # ifdef IS_IN_libpthread
00079 #  define CENABLE    bl JUMPTARGET(__pthread_enable_asynccancel)
00080 #  define CDISABLE   bl JUMPTARGET(__pthread_disable_asynccancel)
00081 #  define __local_multiple_threads __pthread_multiple_threads
00082 # elif !defined NOT_IN_libc
00083 #  define CENABLE    bl JUMPTARGET(__libc_enable_asynccancel)
00084 #  define CDISABLE   bl JUMPTARGET(__libc_disable_asynccancel)
00085 #  define __local_multiple_threads __libc_multiple_threads
00086 # else
00087 #  define CENABLE    bl JUMPTARGET(__librt_enable_asynccancel); nop
00088 #  define CDISABLE   bl JUMPTARGET(__librt_disable_asynccancel); nop
00089 #  define __local_multiple_threads __librt_multiple_threads
00090 # endif
00091 
00092 # ifdef HAVE_TLS_SUPPORT
00093 #  ifndef __ASSEMBLER__
00094 #   define SINGLE_THREAD_P                                     \
00095   __builtin_expect (THREAD_GETMEM (THREAD_SELF, p_multiple_threads) == 0, 1)
00096 #  else
00097 #   define SINGLE_THREAD_P                                     \
00098   lwz 10,MULTIPLE_THREADS_OFFSET(13);                                 \
00099   cmpwi 10,0
00100 #  endif
00101 # else /* !HAVE_TLS_SUPPORT */
00102 #  ifndef __ASSEMBLER__
00103 extern int __local_multiple_threads
00104 #   if !defined NOT_IN_libc || defined IS_IN_libpthread
00105   attribute_hidden;
00106 #   else
00107   ;
00108 #   endif
00109 #   define SINGLE_THREAD_P __builtin_expect (__local_multiple_threads == 0, 1)
00110 #  else
00111 #   define SINGLE_THREAD_P                                     \
00112        .section      ".toc","aw";                              \
00113 .LC__local_multiple_threads:;                                         \
00114        .tc __local_multiple_threads[TC],__local_multiple_threads;     \
00115   .previous;                                                   \
00116   ld    10,.LC__local_multiple_threads@toc(2);                        \
00117   lwz   10,0(10);                                              \
00118   cmpwi 10,0
00119 #  endif
00120 # endif
00121 
00122 #elif !defined __ASSEMBLER__
00123 
00124 /* This code should never be used but we define it anyhow.  */
00125 # define SINGLE_THREAD_P (1)
00126 
00127 #endif