pthread_rwlock_unlock implementation for Linux/i486.
[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         xorl    %esi, %esi
46         xorl    %edx, %edx
47         movl    16(%esp), %edi
48
49         /* Get the lock.  */
50         movl    $1, %eax
51         LOCK
52 #if MUTEX == 0
53         xaddl   %eax, (%edi)
54 #else
55         xaddl   %eax, MUTEX(%edi)
56 #endif
57         testl   %eax, %eax
58         jne     1f
59
60 2:      cmpl    $0, WRITER(%edi)
61         jne     5f
62         decl    NR_READERS(%edi)
63         jnz     6f
64
65 5:      movl    $0, WRITER(%edi)
66
67         movl    $0x7fffffff, %edx
68         leal    READERS_WAKEUP(%edi), %ebx
69         movl    $1, %ecx
70         leal    WRITERS_WAKEUP(%edi), %eax
71         cmpl    $0, WRITERS_QUEUED(%edi)
72 #ifdef HAVE_CMOV
73         cmovnel %ecx, %edx
74         cmovnel %eax, %ebx
75 #else
76         je      0f
77         movl    %ecx, %edx
78         movl    %eax, %ebx
79 0:
80 #endif
81         movl    $SYS_futex, %eax
82         ENTER_KERNEL
83
84 6:      LOCK
85 #if MUTEX == 0
86         decl    (%edi)
87 #else
88         decl    MUTEX(%edi)
89 #endif
90         jne     3f
91
92 4:      xorl    %eax, %eax
93         popl    %edi
94         popl    %esi
95         popl    %ebx
96         ret
97
98 1:      movl    %edi, %ecx
99         call    __lll_mutex_lock_wait
100         jmp     2b
101
102 3:      movl    %edi, %eax
103         call    __lll_mutex_unlock_wake
104         jmp     4b
105
106         .size   __pthread_rwlock_unlock,.-__pthread_rwlock_unlock
107
108         .globl  pthread_rwlock_unlock
109 pthread_rwlock_unlock = __pthread_rwlock_unlock
110
111         .globl  __pthread_rwlock_unlock_internal
112 __pthread_rwlock_unlock_internal = __pthread_rwlock_unlock