(pthread_barrier_wait): Don't save, load, and restore %esi for last thread.
[kopensolaris-gnu/glibc.git] / nptl / sysdeps / unix / sysv / linux / i386 / i486 / pthread_rwlock_wrlock.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 #define EAGAIN          11
29 #define EDEADLK         35
30
31 #ifndef UP
32 # define LOCK lock
33 #else
34 # define LOCK
35 #endif
36
37
38         .text
39
40         .globl  __pthread_rwlock_wrlock
41         .type   __pthread_rwlock_wrlock,@function
42         .align  16
43 __pthread_rwlock_wrlock:
44         pushl   %esi
45         pushl   %ebx
46
47         xorl    %esi, %esi
48         movl    12(%esp), %ebx
49
50         /* Get the lock.  */
51         movl    $1, %eax
52         LOCK
53 #if MUTEX == 0
54         xaddl   %eax, (%ebx)
55 #else
56         xaddl   %eax, MUTEX(%ebx)
57 #endif
58         testl   %eax, %eax
59         jne     1f
60
61 2:      movl    WRITER(%ebx), %eax
62         testl   %eax, %eax
63         jne     14f
64         cmp     $0, NR_READERS(%ebx)
65         je      5f
66
67 3:      incl    WRITERS_QUEUED(%ebx)
68         je      4f
69
70         movl    WRITERS_WAKEUP(%ebx), %edx
71
72         LOCK
73 #if MUTEX == 0
74         decl    (%ebx)
75 #else
76         decl    MUTEX(%ebx)
77 #endif
78         jne     10f
79
80 11:     addl    $WRITERS_WAKEUP-MUTEX, %ebx
81         movl    %esi, %ecx      /* movl $FUTEX_WAIT, %ecx */
82         movl    $SYS_futex, %eax
83         ENTER_KERNEL
84
85         subl    $WRITERS_WAKEUP-MUTEX, %ebx
86
87         /* Reget the lock.  */
88         movl    $1, %eax
89         LOCK
90 #if MUTEX == 0
91         xaddl   %eax, (%ebx)
92 #else
93         xaddl   %eax, MUTEX(%ebx)
94 #endif
95         testl   %eax, %eax
96         jne     12f
97
98 13:     decl    WRITERS_QUEUED(%ebx)
99         jmp     2b
100
101 5:      xorl    %ecx, %ecx
102         movl    %gs:8, %eax
103         movl    %eax, WRITER(%ebx)
104 9:      LOCK
105 #if MUTEX == 0
106         decl    (%ebx)
107 #else
108         decl    MUTEX(%ebx)
109 #endif
110         jne     6f
111 7:
112
113         movl    %ecx, %eax
114         popl    %ebx
115         popl    %esi
116         ret
117
118 1:
119 #if MUTEX == 0
120         movl    %ebx, %ecx
121 #else
122         leal    MUTEX(%ebx), %ecx
123 #endif
124         call    __lll_mutex_lock_wait
125         jmp     2b
126
127 14:     cmpl    %gs:8, %eax
128         jne     3b
129         movl    $EDEADLK, %ecx
130         jmp     9b
131
132 6:
133 #if MUTEX == 0
134         movl    %ebx, %eax
135 #else
136         leal    MUTEX(%ebx), %eax
137 #endif
138         call    __lll_mutex_unlock_wake
139         jmp     7b
140
141 4:      decl    WRITERS_QUEUED(%ebx)
142         movl    $EAGAIN, %ecx
143         jmp     9b
144
145 10:
146 #if MUTEX == 0
147         movl    %ebx, %eax
148 #else
149         leal    MUTEX(%ebx), %eax
150 #endif
151         call    __lll_mutex_unlock_wake
152         jmp     11b
153
154 12:
155 #if MUTEX == 0
156         movl    %ebx, %ecx
157 #else
158         leal    MUTEX(%ebx), %ecx
159 #endif
160         call    __lll_mutex_lock_wait
161         jmp     13b
162         .size   __pthread_rwlock_wrlock,.-__pthread_rwlock_wrlock
163
164         .globl  pthread_rwlock_wrlock
165 pthread_rwlock_wrlock = __pthread_rwlock_wrlock
166
167         .globl  __pthread_rwlock_wrlock_internal
168 __pthread_rwlock_wrlock_internal = __pthread_rwlock_wrlock