* sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_rdlock.S: Access
[glibc.git] / nptl / sysdeps / unix / sysv / linux / i386 / i486 / pthread_rwlock_wrlock.S
blobd13bb5132cbbb752ef201de2736ca5413b4cc9f2
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.
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 <lowlevellock.h>
22 #include <lowlevelrwlock.h>
23 #include <pthread-errnos.h>
24 #include <kernel-features.h>
27         .text
29         .globl  __pthread_rwlock_wrlock
30         .type   __pthread_rwlock_wrlock,@function
31         .align  16
32 __pthread_rwlock_wrlock:
33         pushl   %esi
34         pushl   %ebx
36         xorl    %esi, %esi
37         movl    12(%esp), %ebx
39         /* Get the lock.  */
40         movl    $1, %edx
41         xorl    %eax, %eax
42         LOCK
43 #if MUTEX == 0
44         cmpxchgl %edx, (%ebx)
45 #else
46         cmpxchgl %edx, MUTEX(%ebx)
47 #endif
48         jnz     1f
50 2:      movl    WRITER(%ebx), %eax
51         testl   %eax, %eax
52         jne     14f
53         cmpl    $0, NR_READERS(%ebx)
54         je      5f
56 3:      addl    $1, WRITERS_QUEUED(%ebx)
57         je      4f
59         movl    WRITERS_WAKEUP(%ebx), %edx
61         LOCK
62 #if MUTEX == 0
63         subl    $1, (%ebx)
64 #else
65         subl    $1, MUTEX(%ebx)
66 #endif
67         jne     10f
69 11:
70 #ifdef __ASSUME_PRIVATE_FUTEX
71         movzbl  PSHARED(%ebx), %ecx
72         xorl    $FUTEX_PRIVATE_FLAG|FUTEX_WAIT, %ecx
73 #else
74         movzbl  PSHARED(%ebx), %ecx
75 # if FUTEX_WAIT != 0
76         orl     $FUTEX_WAIT, %ecx
77 # endif
78         xorl    %gs:PRIVATE_FUTEX, %ecx
79 #endif
80         addl    $WRITERS_WAKEUP, %ebx
81         movl    $SYS_futex, %eax
82         ENTER_KERNEL
84         subl    $WRITERS_WAKEUP, %ebx
86         /* Reget the lock.  */
87         movl    $1, %edx
88         xorl    %eax, %eax
89         LOCK
90 #if MUTEX == 0
91         cmpxchgl %edx, (%ebx)
92 #else
93         cmpxchgl %edx, MUTEX(%ebx)
94 #endif
95         jnz     12f
97 13:     subl    $1, WRITERS_QUEUED(%ebx)
98         jmp     2b
100 5:      xorl    %edx, %edx
101         movl    %gs:TID, %eax
102         movl    %eax, WRITER(%ebx)
103 9:      LOCK
104 #if MUTEX == 0
105         subl    $1, (%ebx)
106 #else
107         subl    $1, MUTEX(%ebx)
108 #endif
109         jne     6f
112         movl    %edx, %eax
113         popl    %ebx
114         popl    %esi
115         ret
118 #if MUTEX == 0
119         movl    %ebx, %edx
120 #else
121         leal    MUTEX(%ebx), %edx
122 #endif
123         movzbl  PSHARED(%ebx), %ecx
124         call    __lll_lock_wait
125         jmp     2b
127 14:     cmpl    %gs:TID , %eax
128         jne     3b
129         movl    $EDEADLK, %edx
130         jmp     9b
133 #if MUTEX == 0
134         movl    %ebx, %eax
135 #else
136         leal    MUTEX(%ebx), %eax
137 #endif
138         movzbl  PSHARED(%ebx), %ecx
139         call    __lll_unlock_wake
140         jmp     7b
142 4:      subl    $1, WRITERS_QUEUED(%ebx)
143         movl    $EAGAIN, %edx
144         jmp     9b
147 #if MUTEX == 0
148         movl    %ebx, %eax
149 #else
150         leal    MUTEX(%ebx), %eax
151 #endif
152         movzbl  PSHARED(%ebx), %ecx
153         call    __lll_unlock_wake
154         jmp     11b
157 #if MUTEX == 0
158         movl    %ebx, %edx
159 #else
160         leal    MUTEX(%ebx), %edx
161 #endif
162         movzbl  PSHARED(%ebx), %ecx
163         call    __lll_lock_wait
164         jmp     13b
165         .size   __pthread_rwlock_wrlock,.-__pthread_rwlock_wrlock
167         .globl  pthread_rwlock_wrlock
168 pthread_rwlock_wrlock = __pthread_rwlock_wrlock
170         .globl  __pthread_rwlock_wrlock_internal
171 __pthread_rwlock_wrlock_internal = __pthread_rwlock_wrlock