]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/uclibc/lib/contrib/uclibc/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_wrlock.S
update
[l4.git] / l4 / pkg / uclibc / lib / contrib / uclibc / libpthread / nptl / sysdeps / unix / sysv / linux / i386 / i486 / pthread_rwlock_wrlock.S
1 /* Copyright (C) 2002, 2003, 2007 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
4
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.
9
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.
14
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library; if not, see
17    <http://www.gnu.org/licenses/>.  */
18
19 #include <sysdep.h>
20 #include <lowlevellock.h>
21 #include <lowlevelrwlock.h>
22 #include <pthread-errnos.h>
23 #include <bits/kernel-features.h>
24 #include <tls.h>
25
26
27         .text
28
29         .globl  __pthread_rwlock_wrlock
30         .type   __pthread_rwlock_wrlock,@function
31         .protected      __pthread_rwlock_wrlock
32         .align  16
33 __pthread_rwlock_wrlock:
34         cfi_startproc
35         pushl   %esi
36         cfi_adjust_cfa_offset(4)
37         pushl   %ebx
38         cfi_adjust_cfa_offset(4)
39         cfi_offset(%esi, -8)
40         cfi_offset(%ebx, -12)
41
42         xorl    %esi, %esi
43         movl    12(%esp), %ebx
44
45         /* Get the lock.  */
46         movl    $1, %edx
47         xorl    %eax, %eax
48         LOCK
49 #if MUTEX == 0
50         cmpxchgl %edx, (%ebx)
51 #else
52         cmpxchgl %edx, MUTEX(%ebx)
53 #endif
54         jnz     1f
55
56 2:      movl    WRITER(%ebx), %eax
57         testl   %eax, %eax
58         jne     14f
59         cmpl    $0, NR_READERS(%ebx)
60         je      5f
61
62 3:      addl    $1, WRITERS_QUEUED(%ebx)
63         je      4f
64
65         movl    WRITERS_WAKEUP(%ebx), %edx
66
67         LOCK
68 #if MUTEX == 0
69         subl    $1, (%ebx)
70 #else
71         subl    $1, MUTEX(%ebx)
72 #endif
73         jne     10f
74
75 11:
76 #ifdef __ASSUME_PRIVATE_FUTEX
77         movzbl  PSHARED(%ebx), %ecx
78         xorl    $FUTEX_PRIVATE_FLAG|FUTEX_WAIT, %ecx
79 #else
80         movzbl  PSHARED(%ebx), %ecx
81 # if FUTEX_WAIT != 0
82         orl     $FUTEX_WAIT, %ecx
83 # endif
84         xorl    %gs:PRIVATE_FUTEX, %ecx
85 #endif
86         addl    $WRITERS_WAKEUP, %ebx
87         movl    $SYS_futex, %eax
88         ENTER_KERNEL
89
90         subl    $WRITERS_WAKEUP, %ebx
91
92         /* Reget the lock.  */
93         movl    $1, %edx
94         xorl    %eax, %eax
95         LOCK
96 #if MUTEX == 0
97         cmpxchgl %edx, (%ebx)
98 #else
99         cmpxchgl %edx, MUTEX(%ebx)
100 #endif
101         jnz     12f
102
103 13:     subl    $1, WRITERS_QUEUED(%ebx)
104         jmp     2b
105
106 5:      xorl    %edx, %edx
107         movl    %gs:TID, %eax
108         movl    %eax, WRITER(%ebx)
109 9:      LOCK
110 #if MUTEX == 0
111         subl    $1, (%ebx)
112 #else
113         subl    $1, MUTEX(%ebx)
114 #endif
115         jne     6f
116 7:
117
118         movl    %edx, %eax
119         popl    %ebx
120         cfi_adjust_cfa_offset(-4)
121         cfi_restore(%ebx)
122         popl    %esi
123         cfi_adjust_cfa_offset(-4)
124         cfi_restore(%esi)
125         ret
126
127         cfi_adjust_cfa_offset(8)
128         cfi_offset(%esi, -8)
129         cfi_offset(%ebx, -12)
130 1:
131 #if MUTEX == 0
132         movl    %ebx, %edx
133 #else
134         leal    MUTEX(%ebx), %edx
135 #endif
136         movzbl  PSHARED(%ebx), %ecx
137         call    __lll_lock_wait
138         jmp     2b
139
140 14:     cmpl    %gs:TID , %eax
141         jne     3b
142         movl    $EDEADLK, %edx
143         jmp     9b
144
145 6:
146 #if MUTEX == 0
147         movl    %ebx, %eax
148 #else
149         leal    MUTEX(%ebx), %eax
150 #endif
151         movzbl  PSHARED(%ebx), %ecx
152         call    __lll_unlock_wake
153         jmp     7b
154
155 4:      subl    $1, WRITERS_QUEUED(%ebx)
156         movl    $EAGAIN, %edx
157         jmp     9b
158
159 10:
160 #if MUTEX == 0
161         movl    %ebx, %eax
162 #else
163         leal    MUTEX(%ebx), %eax
164 #endif
165         movzbl  PSHARED(%ebx), %ecx
166         call    __lll_unlock_wake
167         jmp     11b
168
169 12:
170 #if MUTEX == 0
171         movl    %ebx, %edx
172 #else
173         leal    MUTEX(%ebx), %edx
174 #endif
175         movzbl  PSHARED(%ebx), %ecx
176         call    __lll_lock_wait
177         jmp     13b
178         cfi_endproc
179         .size   __pthread_rwlock_wrlock,.-__pthread_rwlock_wrlock
180
181         .globl  pthread_rwlock_wrlock
182 pthread_rwlock_wrlock = __pthread_rwlock_wrlock
183
184         .globl  __pthread_rwlock_wrlock_internal
185 __pthread_rwlock_wrlock_internal = __pthread_rwlock_wrlock