]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/l4re-core/uclibc/lib/contrib/uclibc/libpthread/nptl/sysdeps/unix/sysv/linux/metag/sysdep-cancel.h
Update
[l4.git] / l4 / pkg / l4re-core / uclibc / lib / contrib / uclibc / libpthread / nptl / sysdeps / unix / sysv / linux / metag / sysdep-cancel.h
1 /* Copyright (C) 2003, 2004, 2005, 2009 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3
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.
8
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.
13
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
17    02111-1307 USA.  */
18
19 #include <tls.h>
20 #include <sysdep.h>
21 #ifndef __ASSEMBLER__
22 # include <pthreadP.h>
23 #endif
24
25 #if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt
26
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.  */
31
32 #ifdef __ASSEMBLER__
33 #undef ret
34 #define ret                                                             \
35    CMP D0Re0, #-4095;                                                   \
36    MOVLO PC, D1RtP;                                                     \
37    MOV D1Ar1, D0Re0;                                                    \
38    B SYSCALL_ERROR;
39 #endif /* __ASSEMBLER__ */
40
41 # undef PSEUDO
42 # define PSEUDO(name, syscall_name, args)                               \
43   .section ".text";                                                     \
44   .type ___##syscall_name##_nocancel,%function;                         \
45   .globl ___##syscall_name##_nocancel;                                  \
46   ___##syscall_name##_nocancel:                                         \
47     cfi_startproc;                                                      \
48     DO_CALL (syscall_name, args);                                       \
49     MOV PC, D1RtP;                                                      \
50     cfi_endproc;                                                        \
51   .size ___##syscall_name##_nocancel,.-___##syscall_name##_nocancel;    \
52     .globl _##name;                                                     \
53     .type _##name, @function;                                           \
54 name##:                                                                 \
55 _##name##:                                                              \
56     DOCARGS_##args;                                                     \
57     SINGLE_THREAD_P;                                                    \
58     UNDOCARGS_##args;                                                   \
59     BNE .Lpseudo_cancel;                                                \
60     cfi_remember_state;                                                 \
61     DO_CALL (syscall_name, 0);                                          \
62     ret                                                                 \
63     cfi_restore_state;                                                  \
64   .Lpseudo_cancel:                                                      \
65     MSETL [A0StP++], D0FrT, D0.5;                                       \
66     DOCARGS_##args;     /* save syscall args etc. around CENABLE.  */   \
67     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.  */                           \
73     CDISABLE;                                                           \
74     MOV D0Re0, D0.5;    /* retrieve return value.  */                   \
75     GETL D0.5, D1.5, [--A0StP];                                         \
76     GETL D0FrT, D1RtP, [--A0StP];
77
78 # define DOCARGS_0
79 # define UNDOCARGS_0
80
81 # define DOCARGS_1 \
82   SETL [A0StP++], D1Ar1, D0Ar2
83 # define UNDOCARGS_1 \
84   GETL D1Ar1, D0Ar2, [--A0StP]
85
86 # define DOCARGS_2 DOCARGS_1
87
88 # define UNDOCARGS_2 UNDOCARGS_2
89
90 # define DOCARGS_3 \
91   MSETL [A0StP++], D1Ar1, D1Ar3
92
93 # define UNDOCARGS_3 \
94   GETL D1Ar1, D0Ar2, [--A0StP];         \
95   GETL D1Ar3, D0Ar4, [--A0StP]
96
97 # define DOCARGS_4 DOCARGS_3
98 # define UNDOCARGS_4 UNDOCARGS_3
99
100 # define DOCARGS_5 \
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]
106
107 # define DOCARGS_6 DOCARGS_5
108 # define UNDOCARGS_6 UNDOCARGS_5
109
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
121 # else
122 #  error Unsupported library
123 # endif
124
125 #ifndef __ASSEMBLER__
126 #   define SINGLE_THREAD_P                                              \
127     likely(THREAD_GETMEM (THREAD_SELF,                  \
128                                    header.multiple_threads) == 0)
129 #else
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]; \
135         CMP     D0Re0, #0; \
136         GETL    D0FrT, D1RtP, [--A0StP]
137 #endif
138
139
140 #elif !defined __ASSEMBLER__
141
142 /* For rtld, et cetera.  */
143 # define SINGLE_THREAD_P 1
144 # define NO_CANCELLATION 1
145
146 #endif
147
148 #ifndef __ASSEMBLER__
149 # define RTLD_SINGLE_THREAD_P \
150     likely(THREAD_GETMEM (THREAD_SELF,  \
151                                    header.multiple_threads) == 0)
152 #endif