sem_timedwait implementation on Linux/SH.
[kopensolaris-gnu/glibc.git] / nptl / sysdeps / unix / sysv / linux / sh / lowlevellock.S
1 /* Copyright (C) 2003 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 "lowlevel-atomic.h"
21
22         .text
23
24 #define SYS_gettimeofday        __NR_gettimeofday
25 #define SYS_futex               240
26 #define FUTEX_WAIT              0
27 #define FUTEX_WAKE              1
28
29 #define ETIMEDOUT               110
30
31
32         .globl  __lll_lock_wait
33         .type   __lll_lock_wait,@function
34         .hidden __lll_lock_wait
35         .align  5
36 __lll_lock_wait:
37         mov     r4, r6
38         mov     r5, r4
39         mov     #0, r7          /* No timeout.  */
40         mov     #FUTEX_WAIT, r5
41 2:
42         add     #-1, r6         /* account for the preceeded xadd.  */
43         mov     #SYS_futex, r3
44         extu.b  r3, r3
45         trapa   #0x14
46         SYSCALL_INST_PAD
47
48         mov     #-1, r3
49         XADD (r3, @r4, r2)
50         tst     r3, r3
51         bf/s    2b
52          mov    r2, r6
53
54         mov     #-1, r1
55         mov.l   r1, @r4
56         rts
57          mov    r2, r0
58         .size   __lll_lock_wait,.-__lll_lock_wait
59
60
61         .globl  lll_unlock_wake_cb
62         .type   lll_unlock_wake_cb,@function
63         .hidden lll_unlock_wake_cb
64         .align  5
65 lll_unlock_wake_cb:
66
67         .align  2
68         mova    1f, r0
69         mov     r15, r1
70         mov     #-6, r15
71 0:
72         mov.l   @r4, r2
73         add     #1, r2
74         mov.l   r2, @r4
75 1:
76         mov     r1, r15
77         cmp/pl  r2
78         bf      2f
79         rts
80          nop
81         .size   lll_unlock_wake_cb,.-lll_unlock_wake_cb
82
83
84         .globl  __lll_unlock_wake
85         .type   __lll_unlock_wake,@function
86         .hidden __lll_unlock_wake
87 __lll_unlock_wake:
88 2:
89         mov     #FUTEX_WAKE, r5
90         mov     #1, r6          /* Wake one thread.  */
91         mov     #0, r7
92         mov.l   r6, @r4         /* Stores 1.  */
93         mov     #SYS_futex, r3
94         extu.b  r3, r3
95         trapa   #0x14
96         SYSCALL_INST_PAD
97         rts
98          nop
99         .size   __lll_unlock_wake,.-__lll_unlock_wake
100
101
102         .globl  __lll_wait_tid
103         .type   __lll_wait_tid,@function
104         .hidden __lll_wait_tid
105 __lll_wait_tid:
106         mov.l   @r4, r6
107 1:
108         mov     #FUTEX_WAIT, r5
109         mov     #0, r7
110         mov     #SYS_futex, r3
111         extu.b  r3, r3
112         trapa   #0x14
113         SYSCALL_INST_PAD
114
115         mov     r0, r1
116
117         mov.l   @r4, r0
118         tst     r0, r0
119         bf/s    1b
120          mov    r0, r6
121         rts
122          nop
123         .size   __lll_wait_tid,.-__lll_wait_tid
124
125         
126         .globl  __lll_timedwait_tid
127         .type   __lll_timedwait_tid,@function
128         .hidden __lll_timedwait_tid
129 __lll_timedwait_tid:
130         mov.l   r9, @-r15
131         mov.l   r8, @-r15
132         mov     r4, r8
133         mov     r5, r9
134         add     #-8, r15
135
136 2:
137         /* Get current time.  */
138         mov     r15, r4
139         mov     #0, r5
140         mov     #SYS_gettimeofday, r3
141         trapa   #0x12
142         SYSCALL_INST_PAD
143
144         /* Compute relative timeout.  */
145         mov.l   @(4,r15), r0
146         mov.w   .L1k, r1
147         dmulu.l r0, r1          /* Milli seconds to nano seconds.  */
148         mov.l   @r9, r2
149         mov.l   @(4,r9), r3
150         mov.l   @r15, r0
151         sts     macl, r1
152         sub     r0, r2
153         clrt
154         subc    r1, r3
155         bf      5f
156         mov.l   .L1g, r1
157         add     r1, r3
158         add     #-1, r2
159 5:
160         cmp/pz  r2
161         bf      6f              /* Time is already up.  */
162
163         mov.l   r2, @r15        /* Store relative timeout.  */
164         mov.l   r3, @(4,r15)
165
166         mov.l   @r8, r6
167         tst     r6, r6
168         bt      4f
169
170         mov     r8, r4
171         mov     #FUTEX_WAIT, r5
172         mov     r15, r7
173         mov     #SYS_futex, r3
174         extu.b  r3, r3
175         trapa   #0x14
176         SYSCALL_INST_PAD
177
178         mov     r0, r1
179
180         mov.l   @r8, r0
181         tst     r0, r0
182         bf      1f
183 4:
184         mov     #0, r0
185 3:
186         add     #8, r15
187         mov.l   @r15+, r8
188         rts
189          mov.l  @r15+, r9
190
191 1:
192         mov     #-ETIMEDOUT, r1
193         cmp/eq  r0, r1
194         bf      2b
195 6:
196         bra     3b
197          mov    #ETIMEDOUT, r0
198
199 .L1k:
200         .word   1000
201         .align  2
202 .L1g:
203         .long   1000000000
204
205         .size   __lll_timedwait_tid,.-__lll_timedwait_tid
206
207
208         .globl  __lll_wake_tid
209         .type   __lll_wake_tid,@function
210         .hidden __lll_wake_tid
211 __lll_wake_tid:
212         mov     #FUTEX_WAKE, r5
213         mov     #-1, r6
214         shlr    r6              /* r6 = 0x7fffffff */
215         mov     #0, r7
216         mov     #SYS_futex, r3
217         extu.b  r3, r3
218         trapa   #0x14
219         SYSCALL_INST_PAD
220         rts
221          nop
222         .size   __lll_wake_tid,.-__lll_wake_tid
223
224