(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_cond_signal.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 <shlib-compat.h>
22 #include <lowlevelcond.h>
23
24 #ifdef UP
25 # define LOCK
26 #else
27 # define LOCK lock
28 #endif
29
30 #define SYS_futex               240
31 #define FUTEX_WAIT              0
32 #define FUTEX_WAKE              1
33
34
35         .text
36
37         /* int pthread_cond_signal (pthread_cond_t *cond) */
38         .globl  __pthread_cond_signal
39         .type   __pthread_cond_signal, @function
40         .align  16
41 __pthread_cond_signal:
42
43         pushl   %ebx
44
45         movl    8(%esp), %ebx
46
47         /* Get internal lock.  */
48         movl    $1, %eax
49         LOCK
50 #if cond_lock == 0
51         xaddl   %eax, (%ebx)
52 #else
53         xaddl   %eax, cond_lock(%ebx)
54 #endif
55         testl   %eax, %eax
56         jne     1f
57
58 2:      addl    $wakeup_seq, %ebx
59         movl    total_seq+4-wakeup_seq(%ebx), %eax
60         movl    total_seq-wakeup_seq(%ebx), %ecx
61         cmpl    4(%ebx), %eax
62         ja      3f
63         jb      4f
64         cmpl    (%ebx), %ecx
65         jbe     4f
66
67         /* Bump the wakeup number.  */
68 3:      addl    $1, (%ebx)
69         adcl    $0, 4(%ebx)
70
71         /* Wake up one thread.  */
72         movl    $FUTEX_WAKE, %ecx
73         movl    $SYS_futex, %eax
74         movl    %ecx, %edx      /* movl $1, %edx */
75         ENTER_KERNEL
76
77         /* Unlock.  */
78 4:      LOCK
79         decl    cond_lock-wakeup_seq(%ebx)
80         jne     5f
81
82 6:      xorl    %eax, %eax
83         popl    %ebx
84         ret
85
86         /* Initial locking failed.  */
87 1:
88 #if cond_lock == 0
89         movl    %ebx, %ecx
90 #else
91         leal    cond_lock(%ebx), %ecx
92 #endif
93         call    __lll_mutex_lock_wait
94         jmp     2b
95
96         /* Unlock in loop requires waekup.  */
97 5:
98         leal    cond_lock-wakeup_seq(%ebx), %eax
99         call    __lll_mutex_unlock_wake
100         jmp     6b
101         .size   __pthread_cond_signal, .-__pthread_cond_signal
102 versioned_symbol (libpthread, __pthread_cond_signal, pthread_cond_signal,
103                   GLIBC_2_3_2)