(__pthread_rwlock_unlock): Don't save, load, and restore %esi.
[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   %edi
43
44         movl    12(%esp), %edi
45
46         /* Get the lock.  */
47         movl    $1, %eax
48         LOCK
49 #if MUTEX == 0
50         xaddl   %eax, (%edi)
51 #else
52         xaddl   %eax, MUTEX(%edi)
53 #endif
54         testl   %eax, %eax
55         jne     1f
56
57 2:      cmpl    $0, WRITER(%edi)
58         jne     5f
59         decl    NR_READERS(%edi)
60         jnz     6f
61
62 5:      movl    $0, WRITER(%edi)
63
64         movl    $1, %ecx
65         leal    WRITERS_WAKEUP(%edi), %ebx
66         movl    %ecx, %edx
67         cmpl    $0, WRITERS_QUEUED(%edi)
68         jne     0f
69
70         /* If also no readers waiting nothing to do.  */
71         cmpl    $0, READERS_QUEUED(%edi)
72         je      6f
73
74         movl    $0x7fffffff, %edx
75         leal    READERS_WAKEUP(%edi), %ebx
76
77 0:      incl    (%ebx)
78         LOCK
79 #if MUTEX == 0
80         decl    (%edi)
81 #else
82         decl    MUTEX(%edi)
83 #endif
84         jne     7f
85
86 8:      movl    $SYS_futex, %eax
87         ENTER_KERNEL
88
89         xorl    %eax, %eax
90         popl    %edi
91         popl    %ebx
92         ret
93
94         .align  16
95 6:      LOCK
96 #if MUTEX == 0
97         decl    (%edi)
98 #else
99         decl    MUTEX(%edi)
100 #endif
101         jne     3f
102
103 4:      xorl    %eax, %eax
104         popl    %edi
105         popl    %ebx
106         ret
107
108 1:
109 #if MUTEX == 0
110         movl    %edi, %ecx
111 #else
112         leal    MUTEX(%edx), %ecx
113 #endif
114         call    __lll_mutex_lock_wait
115         jmp     2b
116
117 3:
118 #if MUTEX == 0
119         movl    %edi, %eax
120 #else
121         leal    MUTEX(%edx), %eax
122 #endif
123         call    __lll_mutex_unlock_wake
124         jmp     4b
125
126 7:
127 #if MUTEX == 0
128         movl    %edi, %eax
129 #else
130         leal    MUTEX(%edx), %eax
131 #endif
132         call    __lll_mutex_unlock_wake
133         jmp     8b
134
135         .size   __pthread_rwlock_unlock,.-__pthread_rwlock_unlock
136
137         .globl  pthread_rwlock_unlock
138 pthread_rwlock_unlock = __pthread_rwlock_unlock
139
140         .globl  __pthread_rwlock_unlock_internal
141 __pthread_rwlock_unlock_internal = __pthread_rwlock_unlock