* sysdeps/i386/tls.h (THREAD_GSCOPE_RESET_FLAG): Use explicit
[glibc/pb-stable.git] / nptl / sysdeps / unix / sysv / linux / i386 / i486 / pthread_rwlock_wrlock.S
blob88044c040bccdba6da1f8144c568a759338e12d8
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 <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:
79 #if __ASSUME_PRIVATE_FUTEX
80         movzbl  PSHARED(%ebx), %ecx
81         xorl    $FUTEX_PRIVATE_FLAG|FUTEX_WAIT, %ecx
82 #else
83         movzbl  PSHARED(%ebx), %ecx
84 # if FUTEX_WAIT != 0
85         orl     $FUTEX_WAIT, %ecx
86 # endif
87         xorl    %gs:PRIVATE_FUTEX, %ecx
88 #endif
89         addl    $WRITERS_WAKEUP, %ebx
90         movl    $SYS_futex, %eax
91         ENTER_KERNEL
93         subl    $WRITERS_WAKEUP, %ebx
95         /* Reget the lock.  */
96         movl    $1, %edx
97         xorl    %eax, %eax
98         LOCK
99 #if MUTEX == 0
100         cmpxchgl %edx, (%ebx)
101 #else
102         cmpxchgl %edx, MUTEX(%ebx)
103 #endif
104         jnz     12f
106 13:     subl    $1, WRITERS_QUEUED(%ebx)
107         jmp     2b
109 5:      xorl    %ecx, %ecx
110         movl    %gs:TID, %eax
111         movl    %eax, WRITER(%ebx)
112 9:      LOCK
113 #if MUTEX == 0
114         subl    $1, (%ebx)
115 #else
116         subl    $1, MUTEX(%ebx)
117 #endif
118         jne     6f
121         movl    %ecx, %eax
122         popl    %ebx
123         popl    %esi
124         ret
127 #if MUTEX == 0
128         movl    %ebx, %ecx
129 #else
130         leal    MUTEX(%ebx), %ecx
131 #endif
132         call    __lll_mutex_lock_wait
133         jmp     2b
135 14:     cmpl    %gs:TID , %eax
136         jne     3b
137         movl    $EDEADLK, %ecx
138         jmp     9b
141 #if MUTEX == 0
142         movl    %ebx, %eax
143 #else
144         leal    MUTEX(%ebx), %eax
145 #endif
146         call    __lll_mutex_unlock_wake
147         jmp     7b
149 4:      subl    $1, WRITERS_QUEUED(%ebx)
150         movl    $EAGAIN, %ecx
151         jmp     9b
154 #if MUTEX == 0
155         movl    %ebx, %eax
156 #else
157         leal    MUTEX(%ebx), %eax
158 #endif
159         call    __lll_mutex_unlock_wake
160         jmp     11b
163 #if MUTEX == 0
164         movl    %ebx, %ecx
165 #else
166         leal    MUTEX(%ebx), %ecx
167 #endif
168         call    __lll_mutex_lock_wait
169         jmp     13b
170         .size   __pthread_rwlock_wrlock,.-__pthread_rwlock_wrlock
172         .globl  pthread_rwlock_wrlock
173 pthread_rwlock_wrlock = __pthread_rwlock_wrlock
175         .globl  __pthread_rwlock_wrlock_internal
176 __pthread_rwlock_wrlock_internal = __pthread_rwlock_wrlock