]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/uclibc/lib/contrib/uclibc/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_wrlock.S
update
[l4.git] / l4 / pkg / uclibc / lib / contrib / uclibc / libpthread / nptl / sysdeps / unix / sysv / linux / x86_64 / pthread_rwlock_wrlock.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_wrlock
30         .type   __pthread_rwlock_wrlock,@function
31         .protected      __pthread_rwlock_wrlock
32         .align  16
33 __pthread_rwlock_wrlock:
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, NR_READERS(%rdi)
52         je      5f
53
54 3:      incl    WRITERS_QUEUED(%rdi)
55         je      4f
56
57         movl    WRITERS_WAKEUP(%rdi), %edx
58
59         LOCK
60 #if MUTEX == 0
61         decl    (%rdi)
62 #else
63         decl    MUTEX(%rdi)
64 #endif
65         jne     10f
66
67 11:
68 #ifdef __ASSUME_PRIVATE_FUTEX
69         movl    $FUTEX_PRIVATE_FLAG|FUTEX_WAIT, %esi
70         xorl    PSHARED(%rdi), %esi
71 #else
72 # if FUTEX_WAIT == 0
73         movl    PSHARED(%rdi), %esi
74 # else
75         movl    $FUTEX_WAIT, %esi
76         orl     PSHARED(%rdi), %esi
77 # endif
78         xorl    %fs:PRIVATE_FUTEX, %esi
79 #endif
80         addq    $WRITERS_WAKEUP, %rdi
81         movl    $SYS_futex, %eax
82         syscall
83
84         subq    $WRITERS_WAKEUP, %rdi
85
86         /* Reget the lock.  */
87         movl    $1, %esi
88         xorl    %eax, %eax
89         LOCK
90 #if MUTEX == 0
91         cmpxchgl %esi, (%rdi)
92 #else
93         cmpxchgl %esi, MUTEX(%rdi)
94 #endif
95         jnz     12f
96
97 13:     decl    WRITERS_QUEUED(%rdi)
98         jmp     2b
99
100 5:      xorl    %edx, %edx
101         movl    %fs:TID, %eax
102         movl    %eax, WRITER(%rdi)
103 9:      LOCK
104 #if MUTEX == 0
105         decl    (%rdi)
106 #else
107         decl    MUTEX(%rdi)
108 #endif
109         jne     6f
110 7:
111
112         movq    %rdx, %rax
113         retq
114
115 1:      movl    PSHARED(%rdi), %esi
116 #if MUTEX != 0
117         addq    $MUTEX, %rdi
118 #endif
119         callq   __lll_lock_wait
120 #if MUTEX != 0
121         subq    $MUTEX, %rdi
122 #endif
123         jmp     2b
124
125 14:     cmpl    %fs:TID, %eax
126         jne     3b
127         movl    $EDEADLK, %edx
128         jmp     9b
129
130 6:      movl    PSHARED(%rdi), %esi
131 #if MUTEX != 0
132         addq    $MUTEX, %rdi
133 #endif
134         callq   __lll_unlock_wake
135         jmp     7b
136
137 4:      decl    WRITERS_QUEUED(%rdi)
138         movl    $EAGAIN, %edx
139         jmp     9b
140
141 10:     movl    PSHARED(%rdi), %esi
142 #if MUTEX != 0
143         addq    $MUTEX, %rdi
144 #endif
145         callq   __lll_unlock_wake
146 #if MUTEX != 0
147         subq    $MUTEX, %rdi
148 #endif
149         jmp     11b
150
151 12:     movl    PSHARED(%rdi), %esi
152 #if MUTEX != 0
153         addq    $MUTEX, %rdi
154 #endif
155         callq   __lll_lock_wait
156 #if MUTEX != 0
157         subq    $MUTEX, %rdi
158 #endif
159         jmp     13b
160         cfi_endproc
161         .size   __pthread_rwlock_wrlock,.-__pthread_rwlock_wrlock
162
163         .globl  pthread_rwlock_wrlock
164 pthread_rwlock_wrlock = __pthread_rwlock_wrlock
165
166         .globl  __pthread_rwlock_wrlock_internal
167 __pthread_rwlock_wrlock_internal = __pthread_rwlock_wrlock