1 /* Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
14 You should have received a copy of the GNU Lesser General Public
15 License along with the GNU C Library; if not, write to the Free
16 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 # include <pthreadP.h>
24 #if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt
27 # define PSEUDO(name, syscall_name, args) \
30 .type __##syscall_name##_nocancel,%function; \
31 .globl __##syscall_name##_nocancel; \
32 __##syscall_name##_nocancel: \
33 DO_CALL (syscall_name, args); \
35 .size __##syscall_name##_nocancel,.-__##syscall_name##_nocancel; \
39 bne .Lpseudo_cancel; \
40 DO_CALL (syscall_name, 0); \
45 DOCARGS_##args; /* save syscall args etc. around CENABLE. */ \
47 mov ip, r0; /* put mask in safe place. */ \
48 UNDOCARGS_##args; /* restore syscall args. */ \
49 swi SYS_ify (syscall_name); /* do the call. */ \
50 str r0, [sp, $-4]!; /* save syscall return value. */ \
51 mov r0, ip; /* get mask back. */ \
53 ldmfd sp!, {r0, lr}; /* retrieve return value and address. */ \
57 # define DOCARGS_0 str lr, [sp, #-4]!;
60 # define DOCARGS_1 stmfd sp!, {r0, lr};
61 # define UNDOCARGS_1 ldr r0, [sp], #4;
63 # define DOCARGS_2 stmfd sp!, {r0, r1, lr};
64 # define UNDOCARGS_2 ldmfd sp!, {r0, r1};
66 # define DOCARGS_3 stmfd sp!, {r0, r1, r2, lr};
67 # define UNDOCARGS_3 ldmfd sp!, {r0, r1, r2};
69 # define DOCARGS_4 stmfd sp!, {r0, r1, r2, r3, lr};
70 # define UNDOCARGS_4 ldmfd sp!, {r0, r1, r2, r3};
72 # define DOCARGS_5 DOCARGS_4
73 # define UNDOCARGS_5 UNDOCARGS_4
75 # define DOCARGS_6 DOCARGS_5
76 # define UNDOCARGS_6 UNDOCARGS_5
78 # ifdef IS_IN_libpthread
79 # define CENABLE bl PLTJMP(__pthread_enable_asynccancel)
80 # define CDISABLE bl PLTJMP(__pthread_disable_asynccancel)
81 # define __local_multiple_threads __pthread_multiple_threads
82 # elif !defined NOT_IN_libc
83 # define CENABLE bl PLTJMP(__libc_enable_asynccancel)
84 # define CDISABLE bl PLTJMP(__libc_disable_asynccancel)
85 # define __local_multiple_threads __libc_multiple_threads
86 # elif defined IS_IN_librt
87 # define CENABLE bl PLTJMP(__librt_enable_asynccancel)
88 # define CDISABLE bl PLTJMP(__librt_disable_asynccancel)
90 # error Unsupported library
93 # if defined IS_IN_libpthread || !defined NOT_IN_libc
94 # ifndef __ASSEMBLER__
95 extern int __local_multiple_threads attribute_hidden
;
96 # define SINGLE_THREAD_P __builtin_expect (__local_multiple_threads == 0, 1)
98 # define SINGLE_THREAD_P \
103 # define PSEUDO_PROLOGUE \
104 1: .word __local_multiple_threads - 2f - 8;
107 /* There is no __local_multiple_threads for librt, so use the TCB. */
108 # ifndef __ASSEMBLER__
109 # define SINGLE_THREAD_P \
110 __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
111 header.multiple_threads) == 0, 1)
113 # define PSEUDO_PROLOGUE
114 # define SINGLE_THREAD_P \
115 stmfd sp!, {r0, lr}; \
116 bl __aeabi_read_tp; \
117 ldr ip, [r0, #MULTIPLE_THREADS_OFFSET]; \
118 ldmfd sp!, {r0, lr}; \
120 # define SINGLE_THREAD_P_PIC(x) SINGLE_THREAD_P
124 #elif !defined __ASSEMBLER__
126 /* For rtld, et cetera. */
127 # define SINGLE_THREAD_P 1
128 # define NO_CANCELLATION 1
132 #ifndef __ASSEMBLER__
133 # define RTLD_SINGLE_THREAD_P \
134 __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
135 header.multiple_threads) == 0, 1)