aabb92960b2fa4f153b1ee26d7aa16676a3e8c50
[glibc/nacl-glibc.git] / nptl / sysdeps / unix / sysv / linux / i386 / i486 / pthread_rwlock_unlock.S
blobaabb92960b2fa4f153b1ee26d7aa16676a3e8c50
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         cfi_startproc
33         pushl   %ebx
34         cfi_adjust_cfa_offset(4)
35         pushl   %edi
36         cfi_adjust_cfa_offset(4)
37         cfi_offset(%ebx, -8)
38         cfi_offset(%edi, -12)
40         movl    12(%esp), %edi
42         /* Get the lock.  */
43         movl    $1, %edx
44         xorl    %eax, %eax
45         LOCK
46 #if MUTEX == 0
47         cmpxchgl %edx, (%edi)
48 #else
49         cmpxchgl %edx, MUTEX(%edi)
50 #endif
51         jnz     1f
53 2:      cmpl    $0, WRITER(%edi)
54         jne     5f
55         subl    $1, NR_READERS(%edi)
56         jnz     6f
58 5:      movl    $0, WRITER(%edi)
60         movl    $1, %edx
61         leal    WRITERS_WAKEUP(%edi), %ebx
62         cmpl    $0, WRITERS_QUEUED(%edi)
63         jne     0f
65         /* If also no readers waiting nothing to do.  */
66         cmpl    $0, READERS_QUEUED(%edi)
67         je      6f
69         movl    $0x7fffffff, %edx
70         leal    READERS_WAKEUP(%edi), %ebx
72 0:      addl    $1, (%ebx)
73         LOCK
74 #if MUTEX == 0
75         subl    $1, (%edi)
76 #else
77         subl    $1, MUTEX(%edi)
78 #endif
79         jne     7f
82 #ifdef __ASSUME_PRIVATE_FUTEX
83         movzbl  PSHARED(%edi), %ecx
84         xorl    $FUTEX_PRIVATE_FLAG|FUTEX_WAKE, %ecx
85 #else
86         movzbl  PSHARED(%edi), %ecx
87         orl     $FUTEX_WAKE, %ecx
88         xorl    %gs:PRIVATE_FUTEX, %ecx
89 #endif
90         movl    $SYS_futex, %eax
91         ENTER_KERNEL
93         xorl    %eax, %eax
94         popl    %edi
95         cfi_adjust_cfa_offset(-4)
96         cfi_restore(%edi)
97         popl    %ebx
98         cfi_adjust_cfa_offset(-4)
99         cfi_restore(%ebx)
100         ret
102         cfi_adjust_cfa_offset(8)
103         cfi_offset(%ebx, -8)
104         cfi_offset(%edi, -12)
105         .align  16
106 6:      LOCK
107 #if MUTEX == 0
108         subl    $1, (%edi)
109 #else
110         subl    $1, MUTEX(%edi)
111 #endif
112         jne     3f
114 4:      xorl    %eax, %eax
115         popl    %edi
116         popl    %ebx
117         ret
120 #if MUTEX == 0
121         movl    %edi, %edx
122 #else
123         leal    MUTEX(%edi), %edx
124 #endif
125         movzbl  PSHARED(%edi), %ecx
126         call    __lll_lock_wait
127         jmp     2b
130 #if MUTEX == 0
131         movl    %edi, %eax
132 #else
133         leal    MUTEX(%edi), %eax
134 #endif
135         movzbl  PSHARED(%edi), %ecx
136         call    __lll_unlock_wake
137         jmp     4b
140 #if MUTEX == 0
141         movl    %edi, %eax
142 #else
143         leal    MUTEX(%edi), %eax
144 #endif
145         movzbl  PSHARED(%edi), %ecx
146         call    __lll_unlock_wake
147         jmp     8b
148         cfi_endproc
149         .size   __pthread_rwlock_unlock,.-__pthread_rwlock_unlock
151         .globl  pthread_rwlock_unlock
152 pthread_rwlock_unlock = __pthread_rwlock_unlock
154         .globl  __pthread_rwlock_unlock_internal
155 __pthread_rwlock_unlock_internal = __pthread_rwlock_unlock