* sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_rdlock.S: Access
[glibc.git] / nptl / sysdeps / unix / sysv / linux / i386 / i486 / pthread_rwlock_unlock.S
blobbf9c33ea9f00b0c856568c7b6f8b77b795b11f69
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 <kernel-features.h>
26         .text
28         .globl  __pthread_rwlock_unlock
29         .type   __pthread_rwlock_unlock,@function
30         .align  16
31 __pthread_rwlock_unlock:
32         pushl   %ebx
33         pushl   %edi
35         movl    12(%esp), %edi
37         /* Get the lock.  */
38         movl    $1, %edx
39         xorl    %eax, %eax
40         LOCK
41 #if MUTEX == 0
42         cmpxchgl %edx, (%edi)
43 #else
44         cmpxchgl %edx, MUTEX(%edi)
45 #endif
46         jnz     1f
48 2:      cmpl    $0, WRITER(%edi)
49         jne     5f
50         subl    $1, NR_READERS(%edi)
51         jnz     6f
53 5:      movl    $0, WRITER(%edi)
55         movl    $1, %edx
56         leal    WRITERS_WAKEUP(%edi), %ebx
57         cmpl    $0, WRITERS_QUEUED(%edi)
58         jne     0f
60         /* If also no readers waiting nothing to do.  */
61         cmpl    $0, READERS_QUEUED(%edi)
62         je      6f
64         movl    $0x7fffffff, %edx
65         leal    READERS_WAKEUP(%edi), %ebx
67 0:      addl    $1, (%ebx)
68         LOCK
69 #if MUTEX == 0
70         subl    $1, (%edi)
71 #else
72         subl    $1, MUTEX(%edi)
73 #endif
74         jne     7f
77 #ifdef __ASSUME_PRIVATE_FUTEX
78         movzbl  PSHARED(%edi), %ecx
79         xorl    $FUTEX_PRIVATE_FLAG|FUTEX_WAKE, %ecx
80 #else
81         movzbl  PSHARED(%edi), %ecx
82         orl     $FUTEX_WAKE, %ecx
83         xorl    %gs:PRIVATE_FUTEX, %ecx
84 #endif
85         movl    $SYS_futex, %eax
86         ENTER_KERNEL
88         xorl    %eax, %eax
89         popl    %edi
90         popl    %ebx
91         ret
93         .align  16
94 6:      LOCK
95 #if MUTEX == 0
96         subl    $1, (%edi)
97 #else
98         subl    $1, MUTEX(%edi)
99 #endif
100         jne     3f
102 4:      xorl    %eax, %eax
103         popl    %edi
104         popl    %ebx
105         ret
108 #if MUTEX == 0
109         movl    %edi, %edx
110 #else
111         leal    MUTEX(%edi), %edx
112 #endif
113         movzbl  PSHARED(%edi), %ecx
114         call    __lll_lock_wait
115         jmp     2b
118 #if MUTEX == 0
119         movl    %edi, %eax
120 #else
121         leal    MUTEX(%edi), %eax
122 #endif
123         movzbl  PSHARED(%edi), %ecx
124         call    __lll_unlock_wake
125         jmp     4b
128 #if MUTEX == 0
129         movl    %edi, %eax
130 #else
131         leal    MUTEX(%edi), %eax
132 #endif
133         movzbl  PSHARED(%edi), %ecx
134         call    __lll_unlock_wake
135         jmp     8b
137         .size   __pthread_rwlock_unlock,.-__pthread_rwlock_unlock
139         .globl  pthread_rwlock_unlock
140 pthread_rwlock_unlock = __pthread_rwlock_unlock
142         .globl  __pthread_rwlock_unlock_internal
143 __pthread_rwlock_unlock_internal = __pthread_rwlock_unlock