2.5-18.1
[glibc.git] / nptl / sysdeps / unix / sysv / linux / sh / lowlevelrobustlock.S
blobc57d3cff183cab9abd5daa75d07ec5c3c5671117
1 /* Copyright (C) 2003, 2004, 2005, 2006 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
17    02111-1307 USA.  */
19 #include <sysdep.h>
20 #include <pthread-errnos.h>
21 #include <lowlevelrobustlock.h>
22 #include "lowlevel-atomic.h"
24         .text
26 #define SYS_gettimeofday        __NR_gettimeofday
27 #define SYS_futex               240
28 #define FUTEX_WAIT              0
29 #define FUTEX_WAKE              1
30 #define FUTEX_WAITERS           0x80000000
31 #define FUTEX_OWNER_DIED        0x40000000
34         .globl  __lll_robust_mutex_lock_wait
35         .type   __lll_robust_mutex_lock_wait,@function
36         .hidden __lll_robust_mutex_lock_wait
37         .align  5
38         cfi_startproc
39 __lll_robust_mutex_lock_wait:
40         mov.l   r8, @-r15
41         cfi_adjust_cfa_offset(4)
42         cfi_rel_offset (r8, 0)
43         mov     r5, r8
44         mov     #0, r7          /* No timeout.  */
45         mov     #FUTEX_WAIT, r5
48         mov     r4, r6
49         mov.l   .L_FUTEX_WAITERS, r0
50         or      r0, r6
51         shlr    r0              /* r0 = FUTEX_OWNER_DIED */
52         tst     r0, r4
53         bf/s    3f
54          cmp/eq r4, r6
55         bt      1f
57         CMPXCHG (r4, @r8, r6, r2)
58         bf      2f
61         mov     r8, r4
62         mov     #SYS_futex, r3
63         extu.b  r3, r3
64         trapa   #0x14
65         SYSCALL_INST_PAD
67         mov.l   @r8, r2
70         tst     r2, r2
71         bf/s    4b
72          mov    r2, r4
74         stc     gbr, r1
75         mov.w   .Ltidoff, r2
76         add     r2, r1
77         mov.l   @r1, r6
78         mov     #0, r3
79         CMPXCHG (r3, @r8, r6, r4)
80         bf      4b
81         mov     #0, r4
84         mov.l   @r15+, r8
85         ret
86          mov    r4, r0
87         cfi_endproc
88         .align  2
89 .L_FUTEX_WAITERS:
90         .long   FUTEX_WAITERS
91 .Ltidoff:
92         .word   TID - TLS_PRE_TCB_SIZE
93         .size   __lll_robust_mutex_lock_wait,.-__lll_robust_mutex_lock_wait
96         .globl  __lll_robust_mutex_timedlock_wait
97         .type   __lll_robust_mutex_timedlock_wait,@function
98         .hidden __lll_robust_mutex_timedlock_wait
99         .align  5
100         cfi_startproc
101 __lll_robust_mutex_timedlock_wait:
102         /* Check for a valid timeout value.  */
103         mov.l   @(4,r6), r1
104         mov.l   .L1g, r0
105         cmp/hs  r0, r1
106         bt      3f
108         mov.l   r10, @-r15
109         cfi_adjust_cfa_offset(4)
110         cfi_rel_offset (r10, 0)
111         mov.l   r9, @-r15
112         cfi_adjust_cfa_offset(4)
113         cfi_rel_offset (r9, 0)
114         mov.l   r8, @-r15
115         cfi_adjust_cfa_offset(4)
116         cfi_rel_offset (r8, 0)
117         mov     r4, r10
118         mov     r6, r9
119         mov     r5, r8
121         /* Stack frame for the timespec and timeval structs.  */
122         add     #-8, r15
123         cfi_adjust_cfa_offset(8)
126         /* Get current time.  */
127         mov     r15, r4
128         mov     #0, r5
129         mov     #SYS_gettimeofday, r3
130         trapa   #0x12
131         SYSCALL_INST_PAD
133         /* Compute relative timeout.  */
134         mov.l   @(4,r15), r0
135         mov.w   .L1k, r1
136         dmulu.l r0, r1          /* Micro seconds to nano seconds.  */
137         mov.l   @r9, r2
138         mov.l   @(4,r9), r3
139         mov.l   @r15, r0
140         sts     macl, r1
141         sub     r0, r2
142         clrt
143         subc    r1, r3
144         bf      4f
145         mov.l   .L1g, r1
146         add     r1, r3
147         add     #-1, r2
149         cmp/pz  r2
150         bf      8f              /* Time is already up.  */
152         mov.l   r2, @r15        /* Store relative timeout.  */
153         mov.l   r3, @(4,r15)
155         mov     r10, r6
156         mov.l   .L_FUTEX_WAITERS2, r0
157         or      r0, r6
158         shlr    r0              /* r0 = FUTEX_OWNER_DIED */
159         tst     r0, r4
160         bf/s    6f
161          cmp/eq r4, r6
162         bt      2f
164         CMPXCHG (r4, @r8, r6, r2)
165         bf/s    5f
166          mov    #0, r5
169         mov     r8, r4
170         mov     #FUTEX_WAIT, r5
171         mov     r10, r6
172         mov     r15, r7
173         mov     #SYS_futex, r3
174         extu.b  r3, r3
175         trapa   #0x14
176         SYSCALL_INST_PAD
177         mov     r0, r5
179         mov.l   @r8, r2
182         tst     r2, r2
183         bf/s    7f
184          mov    r2, r10
186         stc     gbr, r1
187         mov.w   .Ltidoff2, r2
188         add     r2, r1
189         mov.l   @r1, r4
190         mov     #0, r3
191         CMPXCHG (r3, @r8, r4, r10)
192         bf      7f
193         mov     #0, r0
196         add     #8, r15
197         mov.l   @r15+, r8
198         mov.l   @r15+, r9
199         rts
200          mov.l  @r15+, r10
203         /* Check whether the time expired.  */
204         mov     #-ETIMEDOUT, r1
205         cmp/eq  r5, r1
206         bf      1b
209         bra     6b
210          mov    #ETIMEDOUT, r0
212         rts
213          mov    #EINVAL, r0
214         cfi_endproc
215         .align  2
216 .L_FUTEX_WAITERS2:
217         .long   FUTEX_WAITERS
218 .L1g:
219         .long   1000000000
220 .Ltidoff2:
221         .word   TID - TLS_PRE_TCB_SIZE
222 .L1k:
223         .word   1000
224         .size   __lll_robust_mutex_timedlock_wait,.-__lll_robust_mutex_timedlock_wait