(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_rdlock.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_rdlock
41         .type   __pthread_rwlock_rdlock,@function
42         .align  16
43 __pthread_rwlock_rdlock:
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, WRITERS_QUEUED(%ebx)
65         je      5f
66         cmpl    $0, FLAGS(%ebx)
67         je      5f
68
69 3:      incl    READERS_QUEUED(%ebx)
70         je      4f
71
72         movl    READERS_WAKEUP(%ebx), %edx
73
74         LOCK
75 #if MUTEX == 0
76         decl    (%ebx)
77 #else
78         decl    MUTEX(%ebx)
79 #endif
80         jne     10f
81
82 11:     addl    $READERS_WAKEUP-MUTEX, %ebx
83         movl    %esi, %ecx      /* movl $FUTEX_WAIT, %ecx */
84         movl    $SYS_futex, %eax
85         ENTER_KERNEL
86
87         subl    $READERS_WAKEUP-MUTEX, %ebx
88
89         /* Reget the lock.  */
90         movl    $1, %eax
91         LOCK
92 #if MUTEX == 0
93         xaddl   %eax, (%ebx)
94 #else
95         xaddl   %eax, MUTEX(%ebx)
96 #endif
97         testl   %eax, %eax
98         jne     12f
99
100 13:     decl    READERS_QUEUED(%ebx)
101         jmp     2b
102
103 5:      xorl    %ecx, %ecx
104         incl    NR_READERS(%ebx)
105         je      8f
106 9:      LOCK
107 #if MUTEX == 0
108         decl    (%ebx)
109 #else
110         decl    MUTEX(%ebx)
111 #endif
112         jne     6f
113 7:
114
115         movl    %ecx, %eax
116         popl    %ebx
117         popl    %esi
118         ret
119
120 1:
121 #if MUTEX == 0
122         movl    %ebx, %ecx
123 #else
124         leal    MUTEX(%ebx), %ecx
125 #endif
126         call    __lll_mutex_lock_wait
127         jmp     2b
128
129 14:     cmpl    %gs:8, %eax
130         jne     3b
131         /* Deadlock detected.  */
132         movl    $EDEADLK, %ecx
133         jmp     9b
134
135 6:
136 #if MUTEX == 0
137         movl    %ebx, %eax
138 #else
139         leal    MUTEX(%ebx), %eax
140 #endif
141         call    __lll_mutex_unlock_wake
142         jmp     7b
143
144         /* Overflow.  */
145 8:      decl    NR_READERS(%ebx)
146         movl    $EAGAIN, %ecx
147         jmp     9b
148
149         /* Overflow.  */
150 4:      decl    READERS_QUEUED(%ebx)
151         movl    $EAGAIN, %ecx
152         jmp     9b
153
154 10:
155 #if MUTEX == 0
156         movl    %ebx, %eax
157 #else
158         leal    MUTEX(%ebx), %eax
159 #endif
160         call    __lll_mutex_unlock_wake
161         jmp     11b
162
163 12:
164 #if MUTEX == 0
165         movl    %ebx, %ecx
166 #else
167         leal    MUTEX(%ebx), %ecx
168 #endif
169         call    __lll_mutex_lock_wait
170         jmp     13b
171         .size   __pthread_rwlock_rdlock,.-__pthread_rwlock_rdlock
172
173         .globl  pthread_rwlock_rdlock
174 pthread_rwlock_rdlock = __pthread_rwlock_rdlock
175
176         .globl  __pthread_rwlock_rdlock_internal
177 __pthread_rwlock_rdlock_internal = __pthread_rwlock_rdlock