OSDN Git Service

Replace FSF snail mail address with URLs
[uclinux-h8/uClibc.git] / libpthread / nptl / sysdeps / unix / sysv / linux / x86_64 / pthread_rwlock_rdlock.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, see
17    <http://www.gnu.org/licenses/>.  */
18
19 #include <sysdep.h>
20 #include <lowlevellock.h>
21 #include <lowlevelrwlock.h>
22 #include <pthread-errnos.h>
23 #include <bits/kernel-features.h>
24 #include <tcb-offsets.h>
25
26
27         .text
28
29         .globl  __pthread_rwlock_rdlock
30         .type   __pthread_rwlock_rdlock,@function
31         .protected      __pthread_rwlock_rdlock
32         .align  16
33 __pthread_rwlock_rdlock:
34         cfi_startproc
35         xorq    %r10, %r10
36
37         /* Get the lock.  */
38         movl    $1, %esi
39         xorl    %eax, %eax
40         LOCK
41 #if MUTEX == 0
42         cmpxchgl %esi, (%rdi)
43 #else
44         cmpxchgl %esi, MUTEX(%rdi)
45 #endif
46         jnz     1f
47
48 2:      movl    WRITER(%rdi), %eax
49         testl   %eax, %eax
50         jne     14f
51         cmpl    $0, WRITERS_QUEUED(%rdi)
52         je      5f
53         cmpl    $0, FLAGS(%rdi)
54         je      5f
55
56 3:      incl    READERS_QUEUED(%rdi)
57         je      4f
58
59         movl    READERS_WAKEUP(%rdi), %edx
60
61         LOCK
62 #if MUTEX == 0
63         decl    (%rdi)
64 #else
65         decl    MUTEX(%rdi)
66 #endif
67         jne     10f
68
69 11:
70 #ifdef __ASSUME_PRIVATE_FUTEX
71         movl    $FUTEX_PRIVATE_FLAG|FUTEX_WAIT, %esi
72         xorl    PSHARED(%rdi), %esi
73 #else
74 # if FUTEX_WAIT == 0
75         movl    PSHARED(%rdi), %esi
76 # else
77         movl    $FUTEX_WAIT, %esi
78         orl     PSHARED(%rdi), %esi
79 # endif
80         xorl    %fs:PRIVATE_FUTEX, %esi
81 #endif
82         addq    $READERS_WAKEUP, %rdi
83         movl    $SYS_futex, %eax
84         syscall
85
86         subq    $READERS_WAKEUP, %rdi
87
88         /* Reget the lock.  */
89         movl    $1, %esi
90         xorl    %eax, %eax
91         LOCK
92 #if MUTEX == 0
93         cmpxchgl %esi, (%rdi)
94 #else
95         cmpxchgl %esi, MUTEX(%rdi)
96 #endif
97         jnz     12f
98
99 13:     decl    READERS_QUEUED(%rdi)
100         jmp     2b
101
102 5:      xorl    %edx, %edx
103         incl    NR_READERS(%rdi)
104         je      8f
105 9:      LOCK
106 #if MUTEX == 0
107         decl    (%rdi)
108 #else
109         decl    MUTEX(%rdi)
110 #endif
111         jne     6f
112 7:
113
114         movq    %rdx, %rax
115         retq
116
117 1:      movl    PSHARED(%rdi), %esi
118 #if MUTEX != 0
119         addq    $MUTEX, %rdi
120 #endif
121         callq   __lll_lock_wait
122 #if MUTEX != 0
123         subq    $MUTEX, %rdi
124 #endif
125         jmp     2b
126
127 14:     cmpl    %fs:TID, %eax
128         jne     3b
129         /* Deadlock detected.  */
130         movl    $EDEADLK, %edx
131         jmp     9b
132
133 6:      movl    PSHARED(%rdi), %esi
134 #if MUTEX != 0
135         addq    $MUTEX, %rdi
136 #endif
137         callq   __lll_unlock_wake
138 #if MUTEX != 0
139         subq    $MUTEX, %rdi
140 #endif
141         jmp     7b
142
143         /* Overflow.  */
144 8:      decl    NR_READERS(%rdi)
145         movl    $EAGAIN, %edx
146         jmp     9b
147
148         /* Overflow.  */
149 4:      decl    READERS_QUEUED(%rdi)
150         movl    $EAGAIN, %edx
151         jmp     9b
152
153 10:     movl    PSHARED(%rdi), %esi
154 #if MUTEX != 0
155         addq    $MUTEX, %rdi
156 #endif
157         callq   __lll_unlock_wake
158 #if MUTEX != 0
159         subq    $MUTEX, %rdi
160 #endif
161         jmp     11b
162
163 12:     movl    PSHARED(%rdi), %esi
164 #if MUTEX == 0
165         addq    $MUTEX, %rdi
166 #endif
167         callq   __lll_lock_wait
168 #if MUTEX != 0
169         subq    $MUTEX, %rdi
170 #endif
171         jmp     13b
172         cfi_endproc
173         .size   __pthread_rwlock_rdlock,.-__pthread_rwlock_rdlock
174
175         .globl  pthread_rwlock_rdlock
176 pthread_rwlock_rdlock = __pthread_rwlock_rdlock
177
178         .globl  __pthread_rwlock_rdlock_internal
179 __pthread_rwlock_rdlock_internal = __pthread_rwlock_rdlock