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 Guido Guenther <agx@sigxcpu.org>, 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 #ifndef __ASSEMBLER__
00022 # include <linuxthreads/internals.h>
00023 #endif
00024 
00025 #if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt
00026 
00027 #ifdef __PIC__
00028 # undef PSEUDO
00029 # define PSEUDO(name, syscall_name, args)                            \
00030   .align 2;                                                          \
00031   99: la t9,__syscall_error;                                                \
00032   jr t9;                                                             \
00033   ENTRY (name)                                                              \
00034     .set noreorder;                                                  \
00035     .cpload t9;                                                             \
00036     .set reorder;                                                    \
00037     SINGLE_THREAD_P(t0);                                             \
00038     bne zero, t0, L(pseudo_cancel);                                         \
00039     .set noreorder;                                                  \
00040     li v0, SYS_ify(syscall_name);                                    \
00041     syscall;                                                         \
00042     .set reorder;                                                    \
00043     bne a3, zero, SYSCALL_ERROR_LABEL;                                             \
00044     ret;                                                             \
00045   L(pseudo_cancel):                                                  \
00046     SAVESTK_##args;                                                   \
00047     sw ra, 28(sp);                                                   \
00048     sw gp, 32(sp);                                                   \
00049     PUSHARGS_##args;               /* save syscall args */                  \
00050     CENABLE;                                                         \
00051     lw gp, 32(sp);                                                   \
00052     sw v0, 44(sp);                 /* save mask */                          \
00053     POPARGS_##args;                /* restore syscall args */        \
00054     .set noreorder;                                                  \
00055     li v0, SYS_ify (syscall_name);                                   \
00056     syscall;                                                         \
00057     .set reorder;                                                    \
00058     sw v0, 36(sp);                 /* save syscall result */             \
00059     sw a3, 40(sp);                 /* save syscall error flag */            \
00060     lw a0, 44(sp);                 /* pass mask as arg1 */                  \
00061     CDISABLE;                                                        \
00062     lw gp, 32(sp);                                                   \
00063     lw v0, 36(sp);                 /* restore syscall result */          \
00064     lw a3, 40(sp);                 /* restore syscall error flag */      \
00065     lw ra, 28(sp);                 /* restore return address */             \
00066     RESTORESTK;                                                              \
00067     bne a3, zero, SYSCALL_ERROR_LABEL;                                      \
00068   L(pseudo_end):
00069 #endif
00070 
00071 # define PUSHARGS_0  /* nothing to do */
00072 # define PUSHARGS_1  PUSHARGS_0 sw a0, 0(sp);
00073 # define PUSHARGS_2  PUSHARGS_1 sw a1, 4(sp);
00074 # define PUSHARGS_3  PUSHARGS_2 sw a2, 8(sp);
00075 # define PUSHARGS_4  PUSHARGS_3 sw a3, 12(sp);
00076 # define PUSHARGS_5  PUSHARGS_4 /* handeld by SAVESTK_## */
00077 # define PUSHARGS_6  PUSHARGS_5
00078 # define PUSHARGS_7  PUSHARGS_6
00079 
00080 # define POPARGS_0   /* nothing to do */
00081 # define POPARGS_1   POPARGS_0 lw a0, 0(sp);
00082 # define POPARGS_2   POPARGS_1 lw a1, 4(sp);
00083 # define POPARGS_3   POPARGS_2 lw a2, 8(sp);
00084 # define POPARGS_4   POPARGS_3 lw a3, 12(sp);
00085 # define POPARGS_5   POPARGS_4 /* args already in new stackframe */
00086 # define POPARGS_6   POPARGS_5
00087 # define POPARGS_7   POPARGS_6
00088 
00089 
00090 # define STKSPACE    48
00091 # define SAVESTK_0   subu sp, STKSPACE
00092 # define SAVESTK_1      SAVESTK_0
00093 # define SAVESTK_2      SAVESTK_1
00094 # define SAVESTK_3      SAVESTK_2
00095 # define SAVESTK_4      SAVESTK_3
00096 # define SAVESTK_5      lw t0, 16(sp);           \
00097                      subu sp, STKSPACE;   \
00098                      sw t0, 16(sp)
00099 
00100 # define SAVESTK_6      lw t0, 16(sp);           \
00101                      lw t1, 20(sp);              \
00102                      subu sp, STKSPACE;   \
00103                      sw t0, 16(sp);              \
00104                      sw t1, 20(sp)
00105 
00106 # define SAVESTK_7      lw t0, 16(sp);           \
00107                      lw t1, 20(sp);              \
00108                      lw t2, 24(sp);              \
00109                      subu sp, STKSPACE;   \
00110                      sw t0, 16(sp);              \
00111                      sw t1, 20(sp);              \
00112                      sw t2, 24(sp)
00113 
00114 # define RESTORESTK  addu sp, STKSPACE
00115 
00116 
00117 # ifdef IS_IN_libpthread
00118 #  define CENABLE    la t9, __pthread_enable_asynccancel; jalr t9;
00119 #  define CDISABLE   la t9, __pthread_disable_asynccancel; jalr t9;
00120 #  define __local_multiple_threads __pthread_multiple_threads
00121 # elif defined IS_IN_librt
00122 #  define CENABLE    la t9, __librt_enable_asynccancel; jalr t9;
00123 #  define CDISABLE   la t9, __librt_disable_asynccancel; jalr t9;
00124 #  define __local_multiple_threads __librt_multiple_threads
00125 # else
00126 #  define CENABLE    la t9, __libc_enable_asynccancel; jalr t9;
00127 #  define CDISABLE   la t9, __libc_disable_asynccancel; jalr t9;
00128 #  define __local_multiple_threads __libc_multiple_threads
00129 # endif
00130 
00131 # ifndef __ASSEMBLER__
00132 extern int __local_multiple_threads attribute_hidden;
00133 #  define SINGLE_THREAD_P __builtin_expect (__local_multiple_threads == 0, 1)
00134 # else
00135 #  define SINGLE_THREAD_P(reg) lw reg, __local_multiple_threads
00136 #endif
00137 
00138 #elif !defined __ASSEMBLER__
00139 
00140 /* This code should never be used but we define it anyhow.  */
00141 # define SINGLE_THREAD_P (1)
00142 
00143 #endif