Fix completely broken implementation.
[kopensolaris-gnu/glibc.git] / 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 SYS_futex               240
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         pushl   %ebx
42         pushl   %esi
43         pushl   %edi
44
45         movl    16(%esp), %edi
46
47         /* Get the lock.  */
48         movl    $1, %eax
49         LOCK
50 #if MUTEX == 0
51         xaddl   %eax, (%edi)
52 #else
53         xaddl   %eax, MUTEX(%edi)
54 #endif
55         testl   %eax, %eax
56         jne     1f
57
58 2:      cmpl    $0, WRITER(%edi)
59         jne     5f
60         decl    NR_READERS(%edi)
61         jnz     6f
62
63 5:      movl    $0, WRITER(%edi)
64
65         movl    $1, %ecx
66         leal    WRITERS_WAKEUP(%edi), %ebx
67         movl    %ecx, %edx
68         cmpl    $0, WRITERS_QUEUED(%edi)
69         jne     0f
70
71         /* If also no readers waiting nothing to do.  */
72         cmpl    $0, READERS_QUEUED(%edi)
73         je      6f
74
75         movl    $0x7fffffff, %edx
76         leal    READERS_WAKEUP(%edi), %ebx
77
78 0:      incl    (%ebx)
79         xorl    %esi, %esi
80         movl    $SYS_futex, %eax
81         ENTER_KERNEL
82
83 6:      LOCK
84 #if MUTEX == 0
85         decl    (%edi)
86 #else
87         decl    MUTEX(%edi)
88 #endif
89         jne     3f
90
91 4:      xorl    %eax, %eax
92         popl    %edi
93         popl    %esi
94         popl    %ebx
95         ret
96
97 1:
98 #if MUTEX == 0
99         movl    %edi, %ecx
100 #else
101         leal    MUTEX(%edx), %ecx
102 #endif
103         call    __lll_mutex_lock_wait
104         jmp     2b
105
106 3:
107 #if MUTEX == 0
108         movl    %edi, %eax
109 #else
110         leal    MUTEX(%edx), %eax
111 #endif
112         call    __lll_mutex_unlock_wake
113         jmp     4b
114
115         .size   __pthread_rwlock_unlock,.-__pthread_rwlock_unlock
116
117         .globl  pthread_rwlock_unlock
118 pthread_rwlock_unlock = __pthread_rwlock_unlock
119
120         .globl  __pthread_rwlock_unlock_internal
121 __pthread_rwlock_unlock_internal = __pthread_rwlock_unlock