chiark / gitweb /
eglibc (2.11.3-4+deb6u3) squeeze-lts; urgency=medium
[eglibc.git] / nptl / sysdeps / unix / sysv / linux / x86_64 / pthread_rwlock_unlock.S
1 /* Copyright (C) 2002, 2003, 2005, 2007, 2009 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
4
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.
9
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.
14
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.  */
19
20 #include <sysdep.h>
21 #include <lowlevellock.h>
22 #include <lowlevelrwlock.h>
23 #include <kernel-features.h>
24
25
26         .text
27
28         .globl  __pthread_rwlock_unlock
29         .type   __pthread_rwlock_unlock,@function
30         .align  16
31 __pthread_rwlock_unlock:
32         cfi_startproc
33         /* Get the lock.  */
34         movl    $1, %esi
35         xorl    %eax, %eax
36         LOCK
37 #if MUTEX == 0
38         cmpxchgl %esi, (%rdi)
39 #else
40         cmpxchgl %esi, MUTEX(%rdi)
41 #endif
42         jnz     1f
43
44 2:      cmpl    $0, WRITER(%rdi)
45         jne     5f
46         decl    NR_READERS(%rdi)
47         jnz     6f
48
49 5:      movl    $0, WRITER(%rdi)
50
51         movl    $1, %edx
52         leaq    WRITERS_WAKEUP(%rdi), %r10
53         cmpl    $0, WRITERS_QUEUED(%rdi)
54         jne     0f
55
56         /* If also no readers waiting nothing to do.  */
57         cmpl    $0, READERS_QUEUED(%rdi)
58         je      6f
59
60         movl    $0x7fffffff, %edx
61         leaq    READERS_WAKEUP(%rdi), %r10
62
63 0:      incl    (%r10)
64         LOCK
65 #if MUTEX == 0
66         decl    (%rdi)
67 #else
68         decl    MUTEX(%rdi)
69 #endif
70         jne     7f
71
72 8:
73 #ifdef __ASSUME_PRIVATE_FUTEX
74         movl    $FUTEX_PRIVATE_FLAG|FUTEX_WAKE, %esi
75         xorl    PSHARED(%rdi), %esi
76 #else
77         movl    $FUTEX_WAKE, %esi
78         orl     PSHARED(%rdi), %esi
79         xorl    %fs:PRIVATE_FUTEX, %esi
80 #endif
81         movl    $SYS_futex, %eax
82         movq    %r10, %rdi
83         syscall
84
85         xorl    %eax, %eax
86         retq
87
88         .align  16
89 6:      LOCK
90 #if MUTEX == 0
91         decl    (%rdi)
92 #else
93         decl    MUTEX(%rdi)
94 #endif
95         jne     3f
96
97 4:      xorl    %eax, %eax
98         retq
99
100 1:      movl    PSHARED(%rdi), %esi
101 #if MUTEX != 0
102         addq    $MUTEX, %rdi
103 #endif
104         callq   __lll_lock_wait
105 #if MUTEX != 0
106         subq    $MUTEX, %rdi
107 #endif
108         jmp     2b
109
110 3:      movl    PSHARED(%rdi), %esi
111 #if MUTEX != 0
112         addq    $MUTEX, %rdi
113 #endif
114         callq   __lll_unlock_wake
115         jmp     4b
116
117 7:      movl    PSHARED(%rdi), %esi
118 #if MUTEX != 0
119         addq    $MUTEX, %rdi
120 #endif
121         callq   __lll_unlock_wake
122         jmp     8b
123         cfi_endproc
124         .size   __pthread_rwlock_unlock,.-__pthread_rwlock_unlock
125
126         .globl  pthread_rwlock_unlock
127 pthread_rwlock_unlock = __pthread_rwlock_unlock
128
129         .globl  __pthread_rwlock_unlock_internal
130 __pthread_rwlock_unlock_internal = __pthread_rwlock_unlock