* init.c: Make it compile with older kernel headers.
[glibc.git] / nptl / sysdeps / unix / sysv / linux / x86_64 / pthread_rwlock_unlock.S
blob4ac9ae62eaf44c2e0fdd53d6939c9cc0eeb7720f
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 <lowlevelrwlock.h>
24 #define SYS_futex               202
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         /* Get the lock.  */
42         movl    $1, %esi
43         xorl    %eax, %eax
44         LOCK
45 #if MUTEX == 0
46         cmpxchgl %esi, (%rdi)
47 #else
48         cmpxchgl %esi, MUTEX(%rdi)
49 #endif
50         jnz     1f
52 2:      cmpl    $0, WRITER(%rdi)
53         jne     5f
54         decl    NR_READERS(%rdi)
55         jnz     6f
57 5:      movl    $0, WRITER(%rdi)
59         leaq    WRITERS_WAKEUP(%rdi), %r10
60         movq    %rsi, %rdx
61         cmpl    $0, WRITERS_QUEUED(%rdi)
62         jne     0f
64         /* If also no readers waiting nothing to do.  */
65         cmpl    $0, READERS_QUEUED(%rdi)
66         je      6f
68         movl    $0x7fffffff, %edx
69         leaq    READERS_WAKEUP(%rdi), %r10
71 0:      incl    (%r10)
72         LOCK
73 #if MUTEX == 0
74         decl    (%rdi)
75 #else
76         decl    MUTEX(%rdi)
77 #endif
78         jne     7f
81 #if __ASSUME_PRIVATE_FUTEX
82         movl    $FUTEX_PRIVATE_FLAG|FUTEX_WAKE, %esi
83         xorl    PSHARED(%rdi), %esi
84 #else
85         movl    $FUTEX_WAKE, %esi
86         orl     PSHARED(%rdi), %esi
87         xorl    %fs:PRIVATE_FUTEX, %esi
88 #endif
89         movl    $SYS_futex, %eax
90         movq    %r10, %rdi
91         syscall
93         xorl    %eax, %eax
94         retq
96         .align  16
97 6:      LOCK
98 #if MUTEX == 0
99         decl    (%rdi)
100 #else
101         decl    MUTEX(%rdi)
102 #endif
103         jne     3f
105 4:      xorl    %eax, %eax
106         retq
109 #if MUTEX != 0
110         addq    $MUTEX, %rdi
111 #endif
112         callq   __lll_mutex_lock_wait
113 #if MUTEX != 0
114         subq    $MUTEX, %rdi
115 #endif
116         jmp     2b
119 #if MUTEX != 0
120         addq    $MUTEX, %rdi
121 #endif
122         callq   __lll_mutex_unlock_wake
123         jmp     4b
126 #if MUTEX != 0
127         addq    $MUTEX, %rdi
128 #endif
129         callq   __lll_mutex_unlock_wake
130         jmp     8b
132         .size   __pthread_rwlock_unlock,.-__pthread_rwlock_unlock
134         .globl  pthread_rwlock_unlock
135 pthread_rwlock_unlock = __pthread_rwlock_unlock
137         .globl  __pthread_rwlock_unlock_internal
138 __pthread_rwlock_unlock_internal = __pthread_rwlock_unlock