1 /* Copyright (C) 2003, 2004, 2005, 2009 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
22 # include <pthreadP.h>
25 #if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt
27 /* NOTE: We do mark syscalls with unwind annotations, for the benefit of
28 cancellation; but they're really only accurate at the point of the
29 syscall. The ARM unwind directives are not rich enough without adding
30 a custom personality function. */
39 #endif /* __ASSEMBLER__ */
42 # define PSEUDO(name, syscall_name, args) \
44 .type ___##syscall_name##_nocancel,%function; \
45 .globl ___##syscall_name##_nocancel; \
46 ___##syscall_name##_nocancel: \
48 DO_CALL (syscall_name, args); \
51 .size ___##syscall_name##_nocancel,.-___##syscall_name##_nocancel; \
53 .type _##name, @function; \
59 BNE .Lpseudo_cancel; \
61 DO_CALL (syscall_name, 0); \
65 MSETL [A0StP++], D0FrT, D0.5; \
66 DOCARGS_##args; /* save syscall args etc. around CENABLE. */ \
68 MOV D0FrT, D0Re0; /* put mask in safe place. */ \
69 UNDOCARGS_##args; /* restore syscall args. */ \
70 DO_CALL(syscall_name, 0); /* do the call. */ \
71 MOV D0.5, D0Re0; /* save syscall return value. */ \
72 MOV D1Ar1, D0FrT; /* get mask back. */ \
74 MOV D0Re0, D0.5; /* retrieve return value. */ \
75 GETL D0.5, D1.5, [--A0StP]; \
76 GETL D0FrT, D1RtP, [--A0StP];
82 SETL [A0StP++], D1Ar1, D0Ar2
83 # define UNDOCARGS_1 \
84 GETL D1Ar1, D0Ar2, [--A0StP]
86 # define DOCARGS_2 DOCARGS_1
88 # define UNDOCARGS_2 UNDOCARGS_2
91 MSETL [A0StP++], D1Ar1, D1Ar3
93 # define UNDOCARGS_3 \
94 GETL D1Ar1, D0Ar2, [--A0StP]; \
95 GETL D1Ar3, D0Ar4, [--A0StP]
97 # define DOCARGS_4 DOCARGS_3
98 # define UNDOCARGS_4 UNDOCARGS_3
101 MSETL [A0StP++], D1Ar1, D1Ar3, D1Ar5
102 # define UNDOCARGS_5 \
103 GETL D1Ar1, D0Ar2, [--A0StP]; \
104 GETL D1Ar3, D0Ar4, [--A0StP]; \
105 GETL D1Ar5, D0Ar6, [--A0StP]
107 # define DOCARGS_6 DOCARGS_5
108 # define UNDOCARGS_6 UNDOCARGS_5
110 # ifdef IS_IN_libpthread
111 # define CENABLE CALLR D1RtP, ___pthread_enable_asynccancel@PLT
112 # define CDISABLE CALLR D1RtP, ___pthread_disable_asynccancel@PLT
113 # define __local_multiple_threads __pthread_multiple_threads
114 # elif !defined NOT_IN_libc
115 # define CENABLE CALLR D1RtP, ___libc_enable_asynccancel@PLT
116 # define CDISABLE CALLR D1RtP, ___libc_disable_asynccancel@PLT
117 # define __local_multiple_threads __libc_multiple_threads
118 # elif defined IS_IN_librt
119 # define CENABLE CALLR D1RtP, ___librt_enable_asynccancel@PLT
120 # define CDISABLE CALLR D1RtP, ___librt_disable_asynccancel@PLT
122 # error Unsupported library
125 #ifndef __ASSEMBLER__
126 # define SINGLE_THREAD_P \
127 likely(THREAD_GETMEM (THREAD_SELF, \
128 header.multiple_threads) == 0)
130 # define SINGLE_THREAD_P \
131 SETL [A0StP++], D0FrT, D1RtP; \
132 CALLR D1RtP, ___metag_load_tp@PLT; \
133 SUB D0Re0, D0Re0, #TLS_PRE_TCB_SIZE; \
134 GETD D0Re0, [D0Re0 + #MULTIPLE_THREADS_OFFSET]; \
136 GETL D0FrT, D1RtP, [--A0StP]
140 #elif !defined __ASSEMBLER__
142 /* For rtld, et cetera. */
143 # define SINGLE_THREAD_P 1
144 # define NO_CANCELLATION 1
148 #ifndef __ASSEMBLER__
149 # define RTLD_SINGLE_THREAD_P \
150 likely(THREAD_GETMEM (THREAD_SELF, \
151 header.multiple_threads) == 0)