2.9
[glibc/nacl-glibc.git] / nptl / sysdeps / unix / sysv / linux / sh / lowlevelrobustlock.S
blob13093422a32cceabd5c4c2a08af82c209f1f32af
1 /* Copyright (C) 2003, 2004, 2005, 2006, 2007
2    Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
10    The GNU C Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library; if not, write to the Free
17    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18    02111-1307 USA.  */
20 #include <sysdep.h>
21 #include <pthread-errnos.h>
22 #include <lowlevellock.h>
23 #include <lowlevelrobustlock.h>
24 #include <kernel-features.h>
25 #include "lowlevel-atomic.h"
27         .text
29 #define FUTEX_WAITERS           0x80000000
30 #define FUTEX_OWNER_DIED        0x40000000
32 #ifdef __ASSUME_PRIVATE_FUTEX
33 # define LOAD_FUTEX_WAIT(reg,tmp,tmp2) \
34         mov     #(FUTEX_WAIT | FUTEX_PRIVATE_FLAG), tmp; \
35         extu.b  tmp, tmp; \
36         xor     tmp, reg
37 #else
38 # if FUTEX_WAIT == 0
39 #  define LOAD_FUTEX_WAIT(reg,tmp,tmp2) \
40         stc     gbr, tmp        ; \
41         mov.w   99f, tmp2       ; \
42         add     tmp2, tmp       ; \
43         mov.l   @tmp, tmp2      ; \
44         bra     98f             ; \
45          mov    #FUTEX_PRIVATE_FLAG, tmp ; \
46 99:     .word   PRIVATE_FUTEX - TLS_PRE_TCB_SIZE ; \
47 98:     extu.b  tmp, tmp        ; \
48         xor     tmp, reg        ; \
49         and     tmp2, reg
50 # else
51 #  define LOAD_FUTEX_WAIT(reg,tmp,tmp2) \
52         stc     gbr, tmp        ; \
53         mov.w   99f, tmp2       ; \
54         add     tmp2, tmp       ; \
55         mov.l   @tmp, tmp2      ; \
56         bra     98f             ; \
57          mov    #FUTEX_PRIVATE_FLAG, tmp ; \
58 99:     .word   PRIVATE_FUTEX - TLS_PRE_TCB_SIZE ; \
59 98:     extu.b  tmp, tmp        ; \
60         xor     tmp, reg        ; \
61         and     tmp2, reg       ; \
62         mov     #FUTEX_WAIT, tmp ; \
63         or      tmp, reg
64 # endif
65 #endif
67         .globl  __lll_robust_lock_wait
68         .type   __lll_robust_lock_wait,@function
69         .hidden __lll_robust_lock_wait
70         .align  5
71         cfi_startproc
72 __lll_robust_lock_wait:
73         mov.l   r8, @-r15
74         cfi_adjust_cfa_offset(4)
75         cfi_rel_offset (r8, 0)
76         mov     r5, r8
77         mov     #0, r7          /* No timeout.  */
78         mov     r6, r5
79         LOAD_FUTEX_WAIT (r5, r0, r1)
82         mov     r4, r6
83         mov.l   .L_FUTEX_WAITERS, r0
84         or      r0, r6
85         shlr    r0              /* r0 = FUTEX_OWNER_DIED */
86         tst     r0, r4
87         bf/s    3f
88          cmp/eq r4, r6
89         bt      1f
91         CMPXCHG (r4, @r8, r6, r2)
92         bf      2f
95         mov     r8, r4
96         mov     #SYS_futex, r3
97         extu.b  r3, r3
98         trapa   #0x14
99         SYSCALL_INST_PAD
101         mov.l   @r8, r2
104         tst     r2, r2
105         bf/s    4b
106          mov    r2, r4
108         stc     gbr, r1
109         mov.w   .Ltidoff, r2
110         add     r2, r1
111         mov.l   @r1, r6
112         mov     #0, r3
113         CMPXCHG (r3, @r8, r6, r4)
114         bf      4b
115         mov     #0, r4
118         mov.l   @r15+, r8
119         ret
120          mov    r4, r0
121         cfi_endproc
122         .align  2
123 .L_FUTEX_WAITERS:
124         .long   FUTEX_WAITERS
125 .Ltidoff:
126         .word   TID - TLS_PRE_TCB_SIZE
127         .size   __lll_robust_lock_wait,.-__lll_robust_lock_wait
130         .globl  __lll_robust_timedlock_wait
131         .type   __lll_robust_timedlock_wait,@function
132         .hidden __lll_robust_timedlock_wait
133         .align  5
134         cfi_startproc
135 __lll_robust_timedlock_wait:
136         /* Check for a valid timeout value.  */
137         mov.l   @(4,r6), r1
138         mov.l   .L1g, r0
139         cmp/hs  r0, r1
140         bt      3f
142         mov.l   r11, @-r15
143         cfi_adjust_cfa_offset(4)
144         cfi_rel_offset (r11, 0)
145         mov.l   r10, @-r15
146         cfi_adjust_cfa_offset(4)
147         cfi_rel_offset (r10, 0)
148         mov.l   r9, @-r15
149         cfi_adjust_cfa_offset(4)
150         cfi_rel_offset (r9, 0)
151         mov.l   r8, @-r15
152         cfi_adjust_cfa_offset(4)
153         cfi_rel_offset (r8, 0)
154         mov     r7, r11
155         mov     r4, r10
156         mov     r6, r9
157         mov     r5, r8
159         /* Stack frame for the timespec and timeval structs.  */
160         add     #-8, r15
161         cfi_adjust_cfa_offset(8)
164         /* Get current time.  */
165         mov     r15, r4
166         mov     #0, r5
167         mov     #__NR_gettimeofday, r3
168         trapa   #0x12
169         SYSCALL_INST_PAD
171         /* Compute relative timeout.  */
172         mov.l   @(4,r15), r0
173         mov.w   .L1k, r1
174         dmulu.l r0, r1          /* Micro seconds to nano seconds.  */
175         mov.l   @r9, r2
176         mov.l   @(4,r9), r3
177         mov.l   @r15, r0
178         sts     macl, r1
179         sub     r0, r2
180         clrt
181         subc    r1, r3
182         bf      4f
183         mov.l   .L1g, r1
184         add     r1, r3
185         add     #-1, r2
187         cmp/pz  r2
188         bf      8f              /* Time is already up.  */
190         mov.l   r2, @r15        /* Store relative timeout.  */
191         mov.l   r3, @(4,r15)
193         mov     r10, r6
194         mov.l   .L_FUTEX_WAITERS2, r0
195         or      r0, r6
196         shlr    r0              /* r0 = FUTEX_OWNER_DIED */
197         tst     r0, r4
198         bf/s    6f
199          cmp/eq r4, r6
200         bt      2f
202         CMPXCHG (r4, @r8, r6, r2)
203         bf/s    5f
204          mov    #0, r5
207         mov     r8, r4
208         mov     r11, r5
209         LOAD_FUTEX_WAIT (r5, r0, r1)
210         mov     r10, r6
211         mov     r15, r7
212         mov     #SYS_futex, r3
213         extu.b  r3, r3
214         trapa   #0x14
215         SYSCALL_INST_PAD
216         mov     r0, r5
218         mov.l   @r8, r2
221         tst     r2, r2
222         bf/s    7f
223          mov    r2, r10
225         stc     gbr, r1
226         mov.w   .Ltidoff2, r2
227         add     r2, r1
228         mov.l   @r1, r4
229         mov     #0, r3
230         CMPXCHG (r3, @r8, r4, r10)
231         bf      7f
232         mov     #0, r0
235         add     #8, r15
236         mov.l   @r15+, r8
237         mov.l   @r15+, r9
238         mov.l   @r15+, r10
239         rts
240          mov.l  @r15+, r11
243         /* Check whether the time expired.  */
244         mov     #-ETIMEDOUT, r1
245         cmp/eq  r5, r1
246         bf      1b
249         bra     6b
250          mov    #ETIMEDOUT, r0
252         rts
253          mov    #EINVAL, r0
254         cfi_endproc
255         .align  2
256 .L_FUTEX_WAITERS2:
257         .long   FUTEX_WAITERS
258 .L1g:
259         .long   1000000000
260 .Ltidoff2:
261         .word   TID - TLS_PRE_TCB_SIZE
262 .L1k:
263         .word   1000
264         .size   __lll_robust_timedlock_wait,.-__lll_robust_timedlock_wait