]> git.ipfire.org Git - thirdparty/glibc.git/blob - nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.S
2.5-18.1
[thirdparty/glibc.git] / nptl / sysdeps / unix / sysv / linux / sh / lowlevellock.S
1 /* Copyright (C) 2003, 2004, 2005 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 <sysdep.h>
20 #include <pthread-errnos.h>
21 #include "lowlevel-atomic.h"
22
23 .text
24
25 #define SYS_gettimeofday __NR_gettimeofday
26 #define SYS_futex 240
27 #define FUTEX_WAIT 0
28 #define FUTEX_WAKE 1
29
30
31 .globl __lll_mutex_lock_wait
32 .type __lll_mutex_lock_wait,@function
33 .hidden __lll_mutex_lock_wait
34 .align 5
35 cfi_startproc
36 __lll_mutex_lock_wait:
37 mov.l r8, @-r15
38 cfi_adjust_cfa_offset(4)
39 cfi_rel_offset (r8, 0)
40 mov r4, r6
41 mov r5, r8
42 mov #0, r7 /* No timeout. */
43 mov #FUTEX_WAIT, r5
44
45 mov #2, r4
46 cmp/eq r4, r6
47 bf 2f
48
49 1:
50 mov r8, r4
51 mov #SYS_futex, r3
52 extu.b r3, r3
53 trapa #0x14
54 SYSCALL_INST_PAD
55
56 2:
57 mov #2, r6
58 XCHG (r6, @r8, r2)
59 tst r2, r2
60 bf 1b
61
62 mov.l @r15+, r8
63 ret
64 mov r2, r0
65 cfi_endproc
66 .size __lll_mutex_lock_wait,.-__lll_mutex_lock_wait
67
68
69 #ifdef NOT_IN_libc
70 .globl __lll_mutex_timedlock_wait
71 .type __lll_mutex_timedlock_wait,@function
72 .hidden __lll_mutex_timedlock_wait
73 .align 5
74 cfi_startproc
75 __lll_mutex_timedlock_wait:
76 /* Check for a valid timeout value. */
77 mov.l @(4,r6), r1
78 mov.l .L1g, r0
79 cmp/hs r0, r1
80 bt 3f
81
82 mov.l r10, @-r15
83 cfi_adjust_cfa_offset(4)
84 cfi_rel_offset (r10, 0)
85 mov.l r9, @-r15
86 cfi_adjust_cfa_offset(4)
87 cfi_rel_offset (r9, 0)
88 mov.l r8, @-r15
89 cfi_adjust_cfa_offset(4)
90 cfi_rel_offset (r8, 0)
91 mov r4, r10
92 mov r6, r9
93 mov r5, r8
94
95 /* Stack frame for the timespec and timeval structs. */
96 add #-8, r15
97 cfi_adjust_cfa_offset(8)
98
99 1:
100 /* Get current time. */
101 mov r15, r4
102 mov #0, r5
103 mov #SYS_gettimeofday, r3
104 trapa #0x12
105 SYSCALL_INST_PAD
106
107 /* Compute relative timeout. */
108 mov.l @(4,r15), r0
109 mov.w .L1k, r1
110 dmulu.l r0, r1 /* Micro seconds to nano seconds. */
111 mov.l @r9, r2
112 mov.l @(4,r9), r3
113 mov.l @r15, r0
114 sts macl, r1
115 sub r0, r2
116 clrt
117 subc r1, r3
118 bf 4f
119 mov.l .L1g, r1
120 add r1, r3
121 add #-1, r2
122 4:
123 cmp/pz r2
124 bf 5f /* Time is already up. */
125
126 mov.l r2, @r15 /* Store relative timeout. */
127 mov.l r3, @(4,r15)
128
129 mov #1, r3
130 mov #2, r4
131 CMPXCHG (r3, @r8, r4, r2)
132 tst r2, r2
133 bt 8f
134
135 mov r8, r4
136 mov #FUTEX_WAIT, r5
137 mov r10, r6
138 mov r15, r7
139 mov #SYS_futex, r3
140 extu.b r3, r3
141 trapa #0x14
142 SYSCALL_INST_PAD
143 mov r0, r5
144
145 8:
146 mov #0, r3
147 mov #2, r4
148 CMPXCHG (r3, @r8, r4, r2)
149 bf/s 7f
150 mov #0, r0
151
152 6:
153 add #8, r15
154 mov.l @r15+, r8
155 mov.l @r15+, r9
156 rts
157 mov.l @r15+, r10
158 7:
159 /* Check whether the time expired. */
160 mov #-ETIMEDOUT, r1
161 cmp/eq r5, r1
162 bt 5f
163
164 /* Make sure the current holder knows we are going to sleep. */
165 XCHG (r2, @r8, r3)
166 tst r3, r3
167 bt/s 6b
168 mov #0, r0
169 bra 1b
170 nop
171 3:
172 rts
173 mov #EINVAL, r0
174 5:
175 bra 6b
176 mov #ETIMEDOUT, r0
177 cfi_endproc
178
179 .L1k:
180 .word 1000
181 .align 2
182 .L1g:
183 .long 1000000000
184
185 .size __lll_mutex_timedlock_wait,.-__lll_mutex_timedlock_wait
186 #endif
187
188
189 #ifdef NOT_IN_libc
190 .globl lll_unlock_wake_cb
191 .type lll_unlock_wake_cb,@function
192 .hidden lll_unlock_wake_cb
193 .align 5
194 cfi_startproc
195 lll_unlock_wake_cb:
196 DEC (@r4, r2)
197 tst r2, r2
198 bt 1f
199
200 mov #FUTEX_WAKE, r5
201 mov #1, r6 /* Wake one thread. */
202 mov #0, r7
203 mov.l r7, @r4 /* Stores 0. */
204 mov #SYS_futex, r3
205 extu.b r3, r3
206 trapa #0x14
207 SYSCALL_INST_PAD
208
209 1:
210 rts
211 nop
212 cfi_endproc
213 .size lll_unlock_wake_cb,.-lll_unlock_wake_cb
214 #endif
215
216
217 .globl __lll_mutex_unlock_wake
218 .type __lll_mutex_unlock_wake,@function
219 .hidden __lll_mutex_unlock_wake
220 .align 5
221 cfi_startproc
222 __lll_mutex_unlock_wake:
223 mov #FUTEX_WAKE, r5
224 mov #1, r6 /* Wake one thread. */
225 mov #0, r7
226 mov.l r7, @r4 /* Stores 0. */
227 mov #SYS_futex, r3
228 extu.b r3, r3
229 trapa #0x14
230 SYSCALL_INST_PAD
231 rts
232 nop
233 cfi_endproc
234 .size __lll_mutex_unlock_wake,.-__lll_mutex_unlock_wake
235
236
237 #ifdef NOT_IN_libc
238 .globl __lll_timedwait_tid
239 .type __lll_timedwait_tid,@function
240 .hidden __lll_timedwait_tid
241 .align 5
242 cfi_startproc
243 __lll_timedwait_tid:
244 mov.l r9, @-r15
245 cfi_adjust_cfa_offset(4)
246 cfi_rel_offset (r9, 0)
247 mov.l r8, @-r15
248 cfi_adjust_cfa_offset(4)
249 cfi_rel_offset (r8, 0)
250 mov r4, r8
251 mov r5, r9
252
253 /* Stack frame for the timespec and timeval structs. */
254 add #-8, r15
255 cfi_adjust_cfa_offset(8)
256
257 2:
258 /* Get current time. */
259 mov r15, r4
260 mov #0, r5
261 mov #SYS_gettimeofday, r3
262 trapa #0x12
263 SYSCALL_INST_PAD
264
265 /* Compute relative timeout. */
266 mov.l @(4,r15), r0
267 mov.w .L1k2, r1
268 dmulu.l r0, r1 /* Micro seconds to nano seconds. */
269 mov.l @r9, r2
270 mov.l @(4,r9), r3
271 mov.l @r15, r0
272 sts macl, r1
273 sub r0, r2
274 clrt
275 subc r1, r3
276 bf 5f
277 mov.l .L1g2, r1
278 add r1, r3
279 add #-1, r2
280 5:
281 cmp/pz r2
282 bf 6f /* Time is already up. */
283
284 mov.l r2, @r15 /* Store relative timeout. */
285 mov.l r3, @(4,r15)
286
287 mov.l @r8, r2
288 tst r2, r2
289 bt 4f
290
291 mov r8, r4
292 mov #FUTEX_WAIT, r5
293 mov r2, r6
294 mov r15, r7
295 mov #SYS_futex, r3
296 extu.b r3, r3
297 trapa #0x14
298 SYSCALL_INST_PAD
299
300 mov.l @r8, r2
301 tst r2, r2
302 bf 1f
303 4:
304 mov #0, r0
305 3:
306 add #8, r15
307 mov.l @r15+, r8
308 rts
309 mov.l @r15+, r9
310 1:
311 /* Check whether the time expired. */
312 mov #-ETIMEDOUT, r1
313 cmp/eq r0, r1
314 bf 2b
315 6:
316 bra 3b
317 mov #ETIMEDOUT, r0
318 cfi_endproc
319
320 .L1k2:
321 .word 1000
322 .align 2
323 .L1g2:
324 .long 1000000000
325 .size __lll_timedwait_tid,.-__lll_timedwait_tid
326 #endif