Back to index

glibc  2.9
sysdep-cancel.h
Go to the documentation of this file.
00001 /* Copyright (C) 2003, 2005 Free Software Foundation, Inc.
00002    This file is part of the GNU C Library.
00003    Contributed by Phil Blundell <pb@nexus.co.uk>, 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
00026 
00027 /* We push lr onto the stack, so we have to use ldmib instead of ldmia
00028    to find the saved arguments.  */
00029 # ifdef PIC
00030 #  undef DOARGS_5
00031 #  undef DOARGS_6
00032 #  undef DOARGS_7
00033 #  define DOARGS_5 str r4, [sp, $-4]!; ldr r4, [sp, $8];
00034 #  define DOARGS_6 mov ip, sp; stmfd sp!, {r4, r5}; ldmib ip, {r4, r5};
00035 #  define DOARGS_7 mov ip, sp; stmfd sp!, {r4, r5, r6}; ldmib ip, {r4, r5, r6};
00036 # endif
00037 
00038 # undef PSEUDO_RET
00039 # define PSEUDO_RET                                             \
00040     ldrcc pc, [sp], $4;                                                \
00041     ldr       lr, [sp], $4;                                           \
00042     b PLTJMP(SYSCALL_ERROR)
00043 
00044 # undef PSEUDO
00045 # define PSEUDO(name, syscall_name, args)                      \
00046   .section ".text";                                            \
00047     PSEUDO_PROLOGUE;                                           \
00048   ENTRY (name);                                                       \
00049     SINGLE_THREAD_P;                                           \
00050     bne .Lpseudo_cancel;                                       \
00051     DO_CALL (syscall_name, args);                              \
00052     cmn r0, $4096;                                             \
00053     RETINSTR(cc, lr);                                                 \
00054     b PLTJMP(SYSCALL_ERROR);                                          \
00055   .Lpseudo_cancel:                                             \
00056     str lr, [sp, $-4]!;                                               \
00057     DOCARGS_##args;  /* save syscall args around CENABLE.  */  \
00058     CENABLE;                                                   \
00059     mov ip, r0;             /* put mask in safe place.  */                   \
00060     UNDOCARGS_##args;       /* restore syscall args.  */                     \
00061     swi SYS_ify (syscall_name);    /* do the call.  */                \
00062     str r0, [sp, $-4]!; /* save syscall return value.  */             \
00063     mov r0, ip;             /* get mask back.  */                            \
00064     CDISABLE;                                                  \
00065     ldr r0, [sp], $4;       /* retrieve return value.  */                    \
00066     UNDOC2ARGS_##args;      /* fix register damage.  */               \
00067     cmn r0, $4096;
00068 
00069 # define DOCARGS_0
00070 # define UNDOCARGS_0
00071 # define UNDOC2ARGS_0
00072 
00073 # define DOCARGS_1   str r0, [sp, #-4]!;
00074 # define UNDOCARGS_1 ldr r0, [sp], #4;
00075 # define UNDOC2ARGS_1
00076 
00077 # define DOCARGS_2   str r1, [sp, #-4]!; str r0, [sp, #-4]!;
00078 # define UNDOCARGS_2 ldr r0, [sp], #4; ldr r1, [sp], #4;
00079 # define UNDOC2ARGS_2
00080 
00081 # define DOCARGS_3   str r2, [sp, #-4]!; str r1, [sp, #-4]!; str r0, [sp, #-4]!;
00082 # define UNDOCARGS_3 ldr r0, [sp], #4; ldr r1, [sp], #4; ldr r2, [sp], #4
00083 # define UNDOC2ARGS_3
00084 
00085 # define DOCARGS_4   stmfd sp!, {r0-r3}
00086 # define UNDOCARGS_4 ldmfd sp!, {r0-r3}
00087 # define UNDOC2ARGS_4
00088 
00089 # define DOCARGS_5   stmfd sp!, {r0-r3}
00090 # define UNDOCARGS_5 ldmfd sp, {r0-r3}; str r4, [sp, #-4]!; ldr r4, [sp, #24]
00091 # define UNDOC2ARGS_5   ldr r4, [sp], #20
00092 
00093 # ifdef IS_IN_libpthread
00094 #  define CENABLE    bl PLTJMP(__pthread_enable_asynccancel)
00095 #  define CDISABLE   bl PLTJMP(__pthread_disable_asynccancel)
00096 #  define __local_multiple_threads __pthread_multiple_threads
00097 # else
00098 #  define CENABLE    bl PLTJMP(__libc_enable_asynccancel)
00099 #  define CDISABLE   bl PLTJMP(__libc_disable_asynccancel)
00100 #  define __local_multiple_threads __libc_multiple_threads
00101 # endif
00102 
00103 # ifndef __ASSEMBLER__
00104 extern int __local_multiple_threads attribute_hidden;
00105 #  define SINGLE_THREAD_P __builtin_expect (__local_multiple_threads == 0, 1)
00106 # else
00107 #  if !defined PIC
00108 #   define SINGLE_THREAD_P                                     \
00109   ldr ip, =__local_multiple_threads;                                  \
00110   ldr ip, [ip];                                                       \
00111   teq ip, #0;
00112 #   define PSEUDO_PROLOGUE
00113 #  else
00114 #   define SINGLE_THREAD_P                                     \
00115   ldr ip, 1b;                                                  \
00116 2:                                                             \
00117   ldr ip, [pc, ip];                                            \
00118   teq ip, #0;
00119 #   define PSEUDO_PROLOGUE                                     \
00120   1:  .word __local_multiple_threads - 2f - 8;
00121 #  endif
00122 # endif
00123 
00124 #elif !defined __ASSEMBLER__
00125 
00126 /* This code should never be used but we define it anyhow.  */
00127 # define SINGLE_THREAD_P (1)
00128 
00129 #endif