]>
Commit | Line | Data |
---|---|---|
da49194d UD |
1 | /* Copyright (C) 2002, 2003 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 <lowlevelrwlock.h> | |
22 | ||
23 | ||
46a32546 | 24 | #define SYS_futex 202 |
da49194d UD |
25 | #define FUTEX_WAIT 0 |
26 | #define FUTEX_WAKE 1 | |
27 | ||
28 | #ifndef UP | |
29 | # define LOCK lock | |
30 | #else | |
31 | # define LOCK | |
32 | #endif | |
33 | ||
34 | ||
35 | .text | |
36 | ||
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 | |
3a226d33 | 43 | xorl %eax, %eax |
da49194d UD |
44 | LOCK |
45 | #if MUTEX == 0 | |
3a226d33 | 46 | cmpxchgl %esi, (%rdi) |
da49194d | 47 | #else |
3a226d33 | 48 | cmpxchgl %esi, MUTEX(%rdi) |
da49194d | 49 | #endif |
3a226d33 | 50 | jnz 1f |
da49194d UD |
51 | |
52 | 2: cmpq $0, WRITER(%rdi) | |
53 | jne 5f | |
54 | decl NR_READERS(%rdi) | |
55 | jnz 6f | |
56 | ||
57 | 5: movq $0, WRITER(%rdi) | |
58 | ||
59 | movq $1, %rsi | |
46a32546 | 60 | leaq WRITERS_WAKEUP(%rdi), %r10 |
da49194d UD |
61 | movq %rsi, %rdx |
62 | cmpl $0, WRITERS_QUEUED(%rdi) | |
63 | jne 0f | |
64 | ||
65 | /* If also no readers waiting nothing to do. */ | |
66 | cmpl $0, READERS_QUEUED(%rdi) | |
67 | je 6f | |
68 | ||
46a32546 UD |
69 | movl $0x7fffffff, %edx |
70 | leaq READERS_WAKEUP(%rdi), %r10 | |
da49194d | 71 | |
46a32546 | 72 | 0: incl (%r10) |
da49194d UD |
73 | LOCK |
74 | #if MUTEX == 0 | |
75 | decl (%rdi) | |
76 | #else | |
77 | decl MUTEX(%rdi) | |
78 | #endif | |
79 | jne 7f | |
80 | ||
81 | 8: movq $SYS_futex, %rax | |
46a32546 | 82 | movq %r10, %rdi |
da49194d UD |
83 | syscall |
84 | ||
85 | xorq %rax, %rax | |
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: xorq %rax, %rax | |
98 | retq | |
99 | ||
100 | 1: | |
101 | #if MUTEX != 0 | |
102 | addq $MUTEX, %rdi | |
103 | #endif | |
92ed3daf | 104 | callq __lll_mutex_lock_wait |
da49194d UD |
105 | #if MUTEX != 0 |
106 | subq $MUTEX, %rdi | |
107 | #endif | |
108 | jmp 2b | |
109 | ||
110 | 3: | |
111 | #if MUTEX != 0 | |
112 | addq $MUTEX, %rdi | |
113 | #endif | |
92ed3daf | 114 | callq __lll_mutex_unlock_wake |
da49194d UD |
115 | jmp 4b |
116 | ||
117 | 7: | |
118 | #if MUTEX != 0 | |
119 | addq $MUTEX, %rdi | |
120 | #endif | |
92ed3daf | 121 | callq __lll_mutex_unlock_wake |
da49194d UD |
122 | jmp 8b |
123 | ||
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 |