* Makefile (tests): Add tst-sem10.
[glibc.git] / nptl / sysdeps / unix / sysv / linux / i386 / i486 / pthread_rwlock_wrlock.S
blobea9cc170dbccc826759465a224dfdf5913455c26
1 /* Copyright (C) 2002, 2003 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 <lowlevelrwlock.h>
22 #include <pthread-errnos.h>
25 #define SYS_futex               240
26 #define FUTEX_WAIT              0
27 #define FUTEX_WAKE              1
29 #ifndef UP
30 # define LOCK lock
31 #else
32 # define LOCK
33 #endif
36         .text
38         .globl  __pthread_rwlock_wrlock
39         .type   __pthread_rwlock_wrlock,@function
40         .align  16
41 __pthread_rwlock_wrlock:
42         pushl   %esi
43         pushl   %ebx
45         xorl    %esi, %esi
46         movl    12(%esp), %ebx
48         /* Get the lock.  */
49         movl    $1, %edx
50         xorl    %eax, %eax
51         LOCK
52 #if MUTEX == 0
53         cmpxchgl %edx, (%ebx)
54 #else
55         cmpxchgl %edx, MUTEX(%ebx)
56 #endif
57         jnz     1f
59 2:      movl    WRITER(%ebx), %eax
60         testl   %eax, %eax
61         jne     14f
62         cmpl    $0, NR_READERS(%ebx)
63         je      5f
65 3:      addl    $1, WRITERS_QUEUED(%ebx)
66         je      4f
68         movl    WRITERS_WAKEUP(%ebx), %edx
70         LOCK
71 #if MUTEX == 0
72         subl    $1, (%ebx)
73 #else
74         subl    $1, MUTEX(%ebx)
75 #endif
76         jne     10f
78 11:     addl    $WRITERS_WAKEUP, %ebx
79         movl    %esi, %ecx      /* movl $FUTEX_WAIT, %ecx */
80         movl    $SYS_futex, %eax
81         ENTER_KERNEL
83         subl    $WRITERS_WAKEUP, %ebx
85         /* Reget the lock.  */
86         movl    $1, %edx
87         xorl    %eax, %eax
88         LOCK
89 #if MUTEX == 0
90         cmpxchgl %edx, (%ebx)
91 #else
92         cmpxchgl %edx, MUTEX(%ebx)
93 #endif
94         jnz     12f
96 13:     subl    $1, WRITERS_QUEUED(%ebx)
97         jmp     2b
99 5:      xorl    %ecx, %ecx
100         movl    %gs:TID, %eax
101         movl    %eax, WRITER(%ebx)
102 9:      LOCK
103 #if MUTEX == 0
104         subl    $1, (%ebx)
105 #else
106         subl    $1, MUTEX(%ebx)
107 #endif
108         jne     6f
111         movl    %ecx, %eax
112         popl    %ebx
113         popl    %esi
114         ret
117 #if MUTEX == 0
118         movl    %ebx, %ecx
119 #else
120         leal    MUTEX(%ebx), %ecx
121 #endif
122         call    __lll_mutex_lock_wait
123         jmp     2b
125 14:     cmpl    %gs:TID , %eax
126         jne     3b
127         movl    $EDEADLK, %ecx
128         jmp     9b
131 #if MUTEX == 0
132         movl    %ebx, %eax
133 #else
134         leal    MUTEX(%ebx), %eax
135 #endif
136         call    __lll_mutex_unlock_wake
137         jmp     7b
139 4:      subl    $1, WRITERS_QUEUED(%ebx)
140         movl    $EAGAIN, %ecx
141         jmp     9b
144 #if MUTEX == 0
145         movl    %ebx, %eax
146 #else
147         leal    MUTEX(%ebx), %eax
148 #endif
149         call    __lll_mutex_unlock_wake
150         jmp     11b
153 #if MUTEX == 0
154         movl    %ebx, %ecx
155 #else
156         leal    MUTEX(%ebx), %ecx
157 #endif
158         call    __lll_mutex_lock_wait
159         jmp     13b
160         .size   __pthread_rwlock_wrlock,.-__pthread_rwlock_wrlock
162         .globl  pthread_rwlock_wrlock
163 pthread_rwlock_wrlock = __pthread_rwlock_wrlock
165         .globl  __pthread_rwlock_wrlock_internal
166 __pthread_rwlock_wrlock_internal = __pthread_rwlock_wrlock