OSDN Git Service

Merge commit 'origin/master' into nptl
[uclinux-h8/uClibc.git] / libpthread / nptl / sysdeps / unix / sysv / linux / i386 / i486 / pthread_rwlock_unlock.S
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
24 #define FUTEX_WAIT              0
25 #define FUTEX_WAKE              1
26
27 #ifndef UP
28 # define LOCK lock
29 #else
30 # define LOCK
31 #endif
32
33
34         .text
35
36         .globl  __pthread_rwlock_unlock
37         .type   __pthread_rwlock_unlock,@function
38         .align  16
39 __pthread_rwlock_unlock:
40         pushl   %ebx
41         pushl   %edi
42
43         movl    12(%esp), %edi
44
45         /* Get the lock.  */
46         movl    $1, %edx
47         xorl    %eax, %eax
48         LOCK
49 #if MUTEX == 0
50         cmpxchgl %edx, (%edi)
51 #else
52         cmpxchgl %edx, MUTEX(%edi)
53 #endif
54         jnz     1f
55
56 2:      cmpl    $0, WRITER(%edi)
57         jne     5f
58         subl    $1, NR_READERS(%edi)
59         jnz     6f
60
61 5:      movl    $0, WRITER(%edi)
62
63         movl    $1, %ecx
64         leal    WRITERS_WAKEUP(%edi), %ebx
65         movl    %ecx, %edx
66         cmpl    $0, WRITERS_QUEUED(%edi)
67         jne     0f
68
69         /* If also no readers waiting nothing to do.  */
70         cmpl    $0, READERS_QUEUED(%edi)
71         je      6f
72
73         movl    $0x7fffffff, %edx
74         leal    READERS_WAKEUP(%edi), %ebx
75
76 0:      addl    $1, (%ebx)
77         LOCK
78 #if MUTEX == 0
79         subl    $1, (%edi)
80 #else
81         subl    $1, MUTEX(%edi)
82 #endif
83         jne     7f
84
85 8:      movl    $SYS_futex, %eax
86         ENTER_KERNEL
87
88         xorl    %eax, %eax
89         popl    %edi
90         popl    %ebx
91         ret
92
93         .align  16
94 6:      LOCK
95 #if MUTEX == 0
96         subl    $1, (%edi)
97 #else
98         subl    $1, MUTEX(%edi)
99 #endif
100         jne     3f
101
102 4:      xorl    %eax, %eax
103         popl    %edi
104         popl    %ebx
105         ret
106
107 1:
108 #if MUTEX == 0
109         movl    %edi, %ecx
110 #else
111         leal    MUTEX(%edx), %ecx
112 #endif
113         call    __lll_mutex_lock_wait
114         jmp     2b
115
116 3:
117 #if MUTEX == 0
118         movl    %edi, %eax
119 #else
120         leal    MUTEX(%edx), %eax
121 #endif
122         call    __lll_mutex_unlock_wake
123         jmp     4b
124
125 7:
126 #if MUTEX == 0
127         movl    %edi, %eax
128 #else
129         leal    MUTEX(%edx), %eax
130 #endif
131         call    __lll_mutex_unlock_wake
132         jmp     8b
133
134         .size   __pthread_rwlock_unlock,.-__pthread_rwlock_unlock
135
136         .globl  pthread_rwlock_unlock
137 pthread_rwlock_unlock = __pthread_rwlock_unlock
138
139         .globl  __pthread_rwlock_unlock_internal
140 __pthread_rwlock_unlock_internal = __pthread_rwlock_unlock