2.9
[glibc/nacl-glibc.git] / nptl / sysdeps / unix / sysv / linux / x86_64 / pthread_rwlock_unlock.S
blobcf7f607d9ce06709f39eca33178c4675b0f58afc
1 /* Copyright (C) 2002, 2003, 2005, 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         /* Get the lock.  */
33         movl    $1, %esi
34         xorl    %eax, %eax
35         LOCK
36 #if MUTEX == 0
37         cmpxchgl %esi, (%rdi)
38 #else
39         cmpxchgl %esi, MUTEX(%rdi)
40 #endif
41         jnz     1f
43 2:      cmpl    $0, WRITER(%rdi)
44         jne     5f
45         decl    NR_READERS(%rdi)
46         jnz     6f
48 5:      movl    $0, WRITER(%rdi)
50         movl    $1, %edx
51         leaq    WRITERS_WAKEUP(%rdi), %r10
52         cmpl    $0, WRITERS_QUEUED(%rdi)
53         jne     0f
55         /* If also no readers waiting nothing to do.  */
56         cmpl    $0, READERS_QUEUED(%rdi)
57         je      6f
59         movl    $0x7fffffff, %edx
60         leaq    READERS_WAKEUP(%rdi), %r10
62 0:      incl    (%r10)
63         LOCK
64 #if MUTEX == 0
65         decl    (%rdi)
66 #else
67         decl    MUTEX(%rdi)
68 #endif
69         jne     7f
72 #ifdef __ASSUME_PRIVATE_FUTEX
73         movl    $FUTEX_PRIVATE_FLAG|FUTEX_WAKE, %esi
74         xorl    PSHARED(%rdi), %esi
75 #else
76         movl    $FUTEX_WAKE, %esi
77         orl     PSHARED(%rdi), %esi
78         xorl    %fs:PRIVATE_FUTEX, %esi
79 #endif
80         movl    $SYS_futex, %eax
81         movq    %r10, %rdi
82         syscall
84         xorl    %eax, %eax
85         retq
87         .align  16
88 6:      LOCK
89 #if MUTEX == 0
90         decl    (%rdi)
91 #else
92         decl    MUTEX(%rdi)
93 #endif
94         jne     3f
96 4:      xorl    %eax, %eax
97         retq
99 1:      movl    PSHARED(%rdi), %esi
100 #if MUTEX != 0
101         addq    $MUTEX, %rdi
102 #endif
103         callq   __lll_lock_wait
104 #if MUTEX != 0
105         subq    $MUTEX, %rdi
106 #endif
107         jmp     2b
109 3:      movl    PSHARED(%rdi), %esi
110 #if MUTEX != 0
111         addq    $MUTEX, %rdi
112 #endif
113         callq   __lll_unlock_wake
114         jmp     4b
116 7:      movl    PSHARED(%rdi), %esi
117 #if MUTEX != 0
118         addq    $MUTEX, %rdi
119 #endif
120         callq   __lll_unlock_wake
121         jmp     8b
123         .size   __pthread_rwlock_unlock,.-__pthread_rwlock_unlock
125         .globl  pthread_rwlock_unlock
126 pthread_rwlock_unlock = __pthread_rwlock_unlock
128         .globl  __pthread_rwlock_unlock_internal
129 __pthread_rwlock_unlock_internal = __pthread_rwlock_unlock