]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/uclibc/lib/contrib/uclibc/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_unlock.S
update
[l4.git] / l4 / pkg / uclibc / lib / contrib / uclibc / libpthread / nptl / sysdeps / unix / sysv / linux / sh / pthread_rwlock_unlock.S
1 /* Copyright (C) 2003, 2007 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, see
16    <http://www.gnu.org/licenses/>.  */
17
18 #include <sysdep.h>
19 #include <lowlevellock.h>
20 #include <lowlevelrwlock.h>
21 #include <bits/kernel-features.h>
22 #include <tcb-offsets.h>
23 #include "lowlevel-atomic.h"
24
25
26         .text
27
28         .globl  __pthread_rwlock_unlock
29         .type   __pthread_rwlock_unlock,@function
30         .protected      __pthread_rwlock_unlock
31         .align  5
32 __pthread_rwlock_unlock:
33         mov.l   r12, @-r15
34         mov.l   r8, @-r15
35         sts.l   pr, @-r15
36         mov     r4, r8
37
38         /* Get the lock.  */
39         mov     #0, r3
40         mov     #1, r4
41 #if MUTEX == 0
42         CMPXCHG (r3, @r8, r4, r2)
43 #else
44         CMPXCHG (r3, @(MUTEX,r8), r4, r2)
45 #endif
46         bf      1f
47 2:
48         mov.l   @(WRITER,r8), r0
49         tst     r0, r0
50         bf      5f
51         mov.l   @(NR_READERS,r8), r0
52         add     #-1, r0
53         mov.l   r0, @(NR_READERS,r8)
54         tst     r0, r0
55         bf      6f
56 5:
57         mov     #0, r0
58         mov.l   r0, @(WRITER,r8)
59         mov     #1, r6
60         mov     r8, r4
61         add     #WRITERS_WAKEUP, r4
62         mov.l   @(WRITERS_QUEUED,r8), r0
63         tst     r0, r0
64         bf      0f
65
66         /* If also no readers waiting nothing to do.  */
67         mov.l   @(READERS_QUEUED,r8), r0
68         tst     r0, r0
69         bt      6f
70
71         mov     #-1, r6
72         shlr    r6              /* r6 = 0x7fffffff */
73         mov     r8, r4
74         add     #READERS_WAKEUP, r4
75
76 0:
77         mov.l   @r4, r0
78         add     #1, r0
79         mov.l   r0, @r4
80 #if MUTEX == 0
81         DEC (@r8, r2)
82 #else
83         DEC (@(MUTEX,r8), r2)
84 #endif
85         tst     r2, r2
86         bf      7f
87
88 8:
89 #ifdef __ASSUME_PRIVATE_FUTEX
90         mov     #PSHARED, r0
91         mov.b   @(r0,r8), r5
92         mov     #(FUTEX_PRIVATE_FLAG|FUTEX_WAKE), r0
93         xor     r0, r5
94         extu.b  r5, r5
95 #else
96         mov     #PSHARED, r0
97         mov.b   @(r0,r8), r5
98         extu.b  r5, r5
99         mov     #FUTEX_WAKE, r0
100         or      r0, r5
101         stc     gbr, r1
102         mov.w   .Lpfoff, r2
103         add     r2, r1
104         mov.l   @r1, r0
105         xor     r0, r5
106 #endif
107         mov     #SYS_futex, r3
108         mov     #0, r7
109         extu.b  r3, r3
110         trapa   #0x14
111         SYSCALL_INST_PAD
112
113         lds.l   @r15+, pr
114         mov.l   @r15+, r8
115         mov.l   @r15+, r12
116         rts
117          mov    #0, r0
118 6:
119 #if MUTEX == 0
120         DEC (@r8, r2)
121 #else
122         DEC (@(MUTEX,r8), r2)
123 #endif
124         tst     r2, r2
125         bf      3f
126 4:
127         lds.l   @r15+, pr
128         mov.l   @r15+, r8
129         mov.l   @r15+, r12
130         rts
131          mov    #0, r0
132
133 1:
134         mov     r8, r5
135 #if MUTEX != 0
136         add     #MUTEX, r5
137 #endif
138         mov     #PSHARED, r0
139         mov.b   @(r0,r8), r6
140         extu.b  r6, r6
141         mov.l   .Lwait8, r1
142         bsrf    r1
143          mov    r2, r4
144 .Lwait8b:
145         bra     2b
146          nop
147 3:
148         mov     r8, r4
149 #if MUTEX != 0
150         add     #MUTEX, r4
151 #endif
152         mov     #PSHARED, r0
153         mov.b   @(r0,r8), r5
154         extu.b  r5, r5
155         mov.l   .Lwake8, r1
156         bsrf    r1
157          nop
158 .Lwake8b:
159         bra     4b
160          nop
161
162 7:
163         mov.l   r4, @-r15
164         mov.l   r6, @-r15
165         mov     r8, r4
166 #if MUTEX != 0
167         add     #MUTEX, r4
168 #endif
169         mov     #PSHARED, r0
170         mov.b   @(r0,r8), r5
171         extu.b  r5, r5
172         mov.l   .Lwake9, r1
173         bsrf    r1
174          nop
175 .Lwake9b:
176
177         mov.l   @r15+, r6
178         bra     8b
179          mov.l  @r15+, r4
180
181 #ifndef __ASSUME_PRIVATE_FUTEX
182 .Lpfoff:
183         .word   PRIVATE_FUTEX - TLS_PRE_TCB_SIZE
184 #endif
185         .align  2
186 .Lwait8:
187         .long   __lll_lock_wait-.Lwait8b
188 .Lwake8:
189         .long   __lll_unlock_wake-.Lwake8b
190 .Lwake9:
191         .long   __lll_unlock_wake-.Lwake9b
192         .size   __pthread_rwlock_unlock,.-__pthread_rwlock_unlock
193
194         .globl  pthread_rwlock_unlock
195 pthread_rwlock_unlock = __pthread_rwlock_unlock
196
197         .globl  __pthread_rwlock_unlock_internal
198 __pthread_rwlock_unlock_internal = __pthread_rwlock_unlock