2.5-18.1
[glibc.git] / nptl / sysdeps / unix / sysv / linux / i386 / i486 / pthread_rwlock_unlock.S
blob64aac3255adce579d86e5fe934a135ec8e3f75d8
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>
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, %ecx
65         leal    WRITERS_WAKEUP(%edi), %ebx
66         movl    %ecx, %edx
67         cmpl    $0, WRITERS_QUEUED(%edi)
68         jne     0f
70         /* If also no readers waiting nothing to do.  */
71         cmpl    $0, READERS_QUEUED(%edi)
72         je      6f
74         movl    $0x7fffffff, %edx
75         leal    READERS_WAKEUP(%edi), %ebx
77 0:      addl    $1, (%ebx)
78         LOCK
79 #if MUTEX == 0
80         subl    $1, (%edi)
81 #else
82         subl    $1, MUTEX(%edi)
83 #endif
84         jne     7f
86 8:      movl    $SYS_futex, %eax
87         ENTER_KERNEL
89         xorl    %eax, %eax
90         popl    %edi
91         popl    %ebx
92         ret
94         .align  16
95 6:      LOCK
96 #if MUTEX == 0
97         subl    $1, (%edi)
98 #else
99         subl    $1, MUTEX(%edi)
100 #endif
101         jne     3f
103 4:      xorl    %eax, %eax
104         popl    %edi
105         popl    %ebx
106         ret
109 #if MUTEX == 0
110         movl    %edi, %ecx
111 #else
112         leal    MUTEX(%edx), %ecx
113 #endif
114         call    __lll_mutex_lock_wait
115         jmp     2b
118 #if MUTEX == 0
119         movl    %edi, %eax
120 #else
121         leal    MUTEX(%edx), %eax
122 #endif
123         call    __lll_mutex_unlock_wake
124         jmp     4b
127 #if MUTEX == 0
128         movl    %edi, %eax
129 #else
130         leal    MUTEX(%edx), %eax
131 #endif
132         call    __lll_mutex_unlock_wake
133         jmp     8b
135         .size   __pthread_rwlock_unlock,.-__pthread_rwlock_unlock
137         .globl  pthread_rwlock_unlock
138 pthread_rwlock_unlock = __pthread_rwlock_unlock
140         .globl  __pthread_rwlock_unlock_internal
141 __pthread_rwlock_unlock_internal = __pthread_rwlock_unlock