* sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedrdlock.S
[glibc.git] / nptl / sysdeps / unix / sysv / linux / i386 / i486 / pthread_rwlock_unlock.S
blobed977aa1417b4fdd85bfce584e11450cc37afda1
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>
24 #define SYS_futex               240
25 #define FUTEX_WAIT              0
26 #define FUTEX_WAKE              1
28 #ifndef UP
29 # define LOCK lock
30 #else
31 # define LOCK
32 #endif
35         .text
37         .globl  __pthread_rwlock_unlock
38         .type   __pthread_rwlock_unlock,@function
39         .align  16
40 __pthread_rwlock_unlock:
41         pushl   %ebx
42         pushl   %edi
44         movl    12(%esp), %edi
46         /* Get the lock.  */
47         movl    $1, %edx
48         xorl    %eax, %eax
49         LOCK
50 #if MUTEX == 0
51         cmpxchgl %edx, (%edi)
52 #else
53         cmpxchgl %edx, MUTEX(%edi)
54 #endif
55         jnz     1f
57 2:      cmpl    $0, WRITER(%edi)
58         jne     5f
59         subl    $1, NR_READERS(%edi)
60         jnz     6f
62 5:      movl    $0, WRITER(%edi)
64         movl    $1, %edx
65         leal    WRITERS_WAKEUP(%edi), %ebx
66         cmpl    $0, WRITERS_QUEUED(%edi)
67         jne     0f
69         /* If also no readers waiting nothing to do.  */
70         cmpl    $0, READERS_QUEUED(%edi)
71         je      6f
73         movl    $0x7fffffff, %edx
74         leal    READERS_WAKEUP(%edi), %ebx
76 0:      addl    $1, (%ebx)
77         LOCK
78 #if MUTEX == 0
79         subl    $1, (%edi)
80 #else
81         subl    $1, MUTEX(%edi)
82 #endif
83         jne     7f
86 #if __ASSUME_PRIVATE_FUTEX
87         movzbl  PSHARED(%edi), %ecx
88         xorl    $FUTEX_PRIVATE_FLAG|FUTEX_WAKE, %ecx
89 #else
90         movzbl  PSHARED(%edi), %ecx
91         orl     $FUTEX_WAKE, %ecx
92         xorl    %gs:PRIVATE_FUTEX, %ecx
93 #endif
94         movl    $SYS_futex, %eax
95         ENTER_KERNEL
97         xorl    %eax, %eax
98         popl    %edi
99         popl    %ebx
100         ret
102         .align  16
103 6:      LOCK
104 #if MUTEX == 0
105         subl    $1, (%edi)
106 #else
107         subl    $1, MUTEX(%edi)
108 #endif
109         jne     3f
111 4:      xorl    %eax, %eax
112         popl    %edi
113         popl    %ebx
114         ret
117 #if MUTEX == 0
118         movl    %edi, %ecx
119 #else
120         leal    MUTEX(%edi), %ecx
121 #endif
122         call    __lll_mutex_lock_wait
123         jmp     2b
126 #if MUTEX == 0
127         movl    %edi, %eax
128 #else
129         leal    MUTEX(%edi), %eax
130 #endif
131         call    __lll_mutex_unlock_wake
132         jmp     4b
135 #if MUTEX == 0
136         movl    %edi, %eax
137 #else
138         leal    MUTEX(%edi), %eax
139 #endif
140         call    __lll_mutex_unlock_wake
141         jmp     8b
143         .size   __pthread_rwlock_unlock,.-__pthread_rwlock_unlock
145         .globl  pthread_rwlock_unlock
146 pthread_rwlock_unlock = __pthread_rwlock_unlock
148         .globl  __pthread_rwlock_unlock_internal
149 __pthread_rwlock_unlock_internal = __pthread_rwlock_unlock