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 
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 #ifndef __ASSEMBLER__
00021 # include <linuxthreads/internals.h>
00022 #endif
00023 
00024 #if !defined NOT_IN_libc || defined IS_IN_libpthread
00025 
00026 # ifdef PROF
00027 #  define PSEUDO_PROF                            \
00028        .set noat;                         \
00029        lda    AT, _mcount;                \
00030        jsr    AT, (AT), _mcount;          \
00031        .set at
00032 # else
00033 #  define PSEUDO_PROF
00034 # endif
00035 
00036 /* ??? Assumes that nothing comes between PSEUDO and PSEUDO_END
00037    besides "ret".  */
00038 
00039 # undef PSEUDO
00040 # define PSEUDO(name, syscall_name, args)               \
00041        .globl name;                                     \
00042        .align 4;                                        \
00043        .type name, @function;                                  \
00044        .usepv name, std;                                \
00045        cfi_startproc;                                          \
00046 __LABEL(name)                                           \
00047        ldgp   gp, 0(pv);                                \
00048        PSEUDO_PROF;                                     \
00049        PSEUDO_PREPARE_ARGS                              \
00050        SINGLE_THREAD_P(t0);                             \
00051        bne    t0, $pseudo_cancel;                       \
00052        lda    v0, SYS_ify(syscall_name);                \
00053        call_pal PAL_callsys;                                   \
00054        bne    a3, SYSCALL_ERROR_LABEL;                  \
00055 __LABEL($pseudo_ret)                                    \
00056        .subsection 2;                                          \
00057 __LABEL($pseudo_cancel)                                        \
00058        subq   sp, 64, sp;                               \
00059        cfi_def_cfa_offset(64);                                 \
00060        stq    ra, 0(sp);                                \
00061        cfi_offset(ra, -64);                             \
00062        SAVE_ARGS_##args;                                \
00063        CENABLE;                                         \
00064        LOAD_ARGS_##args;                                \
00065        lda    v0, SYS_ify(syscall_name);                \
00066        call_pal PAL_callsys;                                   \
00067        stq    v0, 8(sp);                                \
00068        bne    a3, $multi_error;                         \
00069        CDISABLE;                                        \
00070        ldq    ra, 0(sp);                                \
00071        ldq    v0, 8(sp);                                \
00072        addq   sp, 64, sp;                               \
00073        cfi_remember_state;                              \
00074        cfi_restore(ra);                                 \
00075        cfi_def_cfa_offset(0);                                  \
00076        ret;                                             \
00077        cfi_restore_state;                               \
00078 __LABEL($multi_error)                                          \
00079        CDISABLE;                                        \
00080        ldq    ra, 0(sp);                                \
00081        ldq    v0, 8(sp);                                \
00082        addq   sp, 64, sp;                               \
00083        cfi_restore(ra);                                 \
00084        cfi_def_cfa_offset(0);                                  \
00085 __LABEL($syscall_error)                                        \
00086        SYSCALL_ERROR_HANDLER;                                  \
00087        .previous
00088 
00089 # undef PSEUDO_END
00090 # define PSEUDO_END(sym)                                \
00091        .subsection 2;                                          \
00092        cfi_endproc;                                     \
00093        .size sym, .-sym
00094 
00095 # define SAVE_ARGS_0 /* Nothing.  */
00096 # define SAVE_ARGS_1 SAVE_ARGS_0; stq a0, 8(sp)
00097 # define SAVE_ARGS_2 SAVE_ARGS_1; stq a1, 16(sp)
00098 # define SAVE_ARGS_3 SAVE_ARGS_2; stq a2, 24(sp)
00099 # define SAVE_ARGS_4 SAVE_ARGS_3; stq a3, 32(sp)
00100 # define SAVE_ARGS_5 SAVE_ARGS_4; stq a4, 40(sp)
00101 # define SAVE_ARGS_6 SAVE_ARGS_5; stq a5, 48(sp)
00102 
00103 # define LOAD_ARGS_0 /* Nothing.  */
00104 # define LOAD_ARGS_1 LOAD_ARGS_0; ldq a0, 8(sp)
00105 # define LOAD_ARGS_2 LOAD_ARGS_1; ldq a1, 16(sp)
00106 # define LOAD_ARGS_3 LOAD_ARGS_2; ldq a2, 24(sp)
00107 # define LOAD_ARGS_4 LOAD_ARGS_3; ldq a3, 32(sp)
00108 # define LOAD_ARGS_5 LOAD_ARGS_4; ldq a4, 40(sp)
00109 # define LOAD_ARGS_6 LOAD_ARGS_5; ldq a5, 48(sp)
00110 
00111 # ifdef IS_IN_libpthread
00112 #  define __local_enable_asynccancel      __pthread_enable_asynccancel
00113 #  define __local_disable_asynccancel     __pthread_disable_asynccancel
00114 #  define __local_multiple_threads __pthread_multiple_threads
00115 # else
00116 #  define __local_enable_asynccancel      __libc_enable_asynccancel
00117 #  define __local_disable_asynccancel     __libc_disable_asynccancel
00118 #  define __local_multiple_threads __libc_multiple_threads
00119 # endif
00120 
00121 # ifdef PIC
00122 #  define CENABLE    bsr ra, __local_enable_asynccancel !samegp
00123 #  define CDISABLE   bsr ra, __local_disable_asynccancel !samegp
00124 # else
00125 #  define CENABLE    jsr ra, __local_enable_asynccancel; ldgp ra, 0(gp)
00126 #  define CDISABLE   jsr ra, __local_disable_asynccancel; ldgp ra, 0(gp)
00127 # endif
00128 
00129 # ifndef __ASSEMBLER__
00130 extern int __local_multiple_threads attribute_hidden;
00131 #   define SINGLE_THREAD_P \
00132   __builtin_expect (__local_multiple_threads == 0, 1)
00133 # elif defined(PIC)
00134 #  define SINGLE_THREAD_P(reg)  ldl reg, __local_multiple_threads(gp) !gprel
00135 # else
00136 #  define SINGLE_THREAD_P(reg)                                 \
00137        ldah   reg, __local_multiple_threads(gp) !gprelhigh;    \
00138        ldl    reg, __local_multiple_threads(reg) !gprellow
00139 # endif
00140 
00141 #elif !defined __ASSEMBLER__
00142 
00143 /* This code should never be used but we define it anyhow.  */
00144 # define SINGLE_THREAD_P (1)
00145 
00146 #endif