OSDN Git Service

e34c42ea20b79e2ab23b44524b08424c074e45fe
[uclinux-h8/uClibc.git] / libpthread / 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 <bits/kernel-features.h>
24
25
26         .text
27
28         .globl  __pthread_rwlock_unlock
29         .type   __pthread_rwlock_unlock,@function
30         .protected      __pthread_rwlock_unlock
31         .align  16
32 __pthread_rwlock_unlock:
33         cfi_startproc
34         /* Get the lock.  */
35         movl    $1, %esi
36         xorl    %eax, %eax
37         LOCK
38 #if MUTEX == 0
39         cmpxchgl %esi, (%rdi)
40 #else
41         cmpxchgl %esi, MUTEX(%rdi)
42 #endif
43         jnz     1f
44
45 2:      cmpl    $0, WRITER(%rdi)
46         jne     5f
47         decl    NR_READERS(%rdi)
48         jnz     6f
49
50 5:      movl    $0, WRITER(%rdi)
51
52         movl    $1, %edx
53         leaq    WRITERS_WAKEUP(%rdi), %r10
54         cmpl    $0, WRITERS_QUEUED(%rdi)
55         jne     0f
56
57         /* If also no readers waiting nothing to do.  */
58         cmpl    $0, READERS_QUEUED(%rdi)
59         je      6f
60
61         movl    $0x7fffffff, %edx
62         leaq    READERS_WAKEUP(%rdi), %r10
63
64 0:      incl    (%r10)
65         LOCK
66 #if MUTEX == 0
67         decl    (%rdi)
68 #else
69         decl    MUTEX(%rdi)
70 #endif
71         jne     7f
72
73 8:
74 #ifdef __ASSUME_PRIVATE_FUTEX
75         movl    $FUTEX_PRIVATE_FLAG|FUTEX_WAKE, %esi
76         xorl    PSHARED(%rdi), %esi
77 #else
78         movl    $FUTEX_WAKE, %esi
79         orl     PSHARED(%rdi), %esi
80         xorl    %fs:PRIVATE_FUTEX, %esi
81 #endif
82         movl    $SYS_futex, %eax
83         movq    %r10, %rdi
84         syscall
85
86         xorl    %eax, %eax
87         retq
88
89         .align  16
90 6:      LOCK
91 #if MUTEX == 0
92         decl    (%rdi)
93 #else
94         decl    MUTEX(%rdi)
95 #endif
96         jne     3f
97
98 4:      xorl    %eax, %eax
99         retq
100
101 1:      movl    PSHARED(%rdi), %esi
102 #if MUTEX != 0
103         addq    $MUTEX, %rdi
104 #endif
105         callq   __lll_lock_wait
106 #if MUTEX != 0
107         subq    $MUTEX, %rdi
108 #endif
109         jmp     2b
110
111 3:      movl    PSHARED(%rdi), %esi
112 #if MUTEX != 0
113         addq    $MUTEX, %rdi
114 #endif
115         callq   __lll_unlock_wake
116         jmp     4b
117
118 7:      movl    PSHARED(%rdi), %esi
119 #if MUTEX != 0
120         addq    $MUTEX, %rdi
121 #endif
122         callq   __lll_unlock_wake
123         jmp     8b
124         cfi_endproc
125         .size   __pthread_rwlock_unlock,.-__pthread_rwlock_unlock
126
127         .globl  pthread_rwlock_unlock
128 pthread_rwlock_unlock = __pthread_rwlock_unlock
129
130         .globl  __pthread_rwlock_unlock_internal
131 __pthread_rwlock_unlock_internal = __pthread_rwlock_unlock