Use ENTER_KERNEL instead of int $0x80.
[kopensolaris-gnu/glibc.git] / nptl / sysdeps / unix / sysv / linux / i386 / lowlevelsem.h
1 /* Copyright (C) 2002 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 #ifndef _LOWLEVELSEM_H
21 #define _LOWLEVELSEM_H  1
22
23 #ifndef LOCK
24 # ifdef UP
25 #  define LOCK  /* nothing */
26 # else
27 #  define LOCK "lock;"
28 # endif
29 #endif
30
31 #define SYS_futex               240
32
33
34 #define lll_sem_wait(sem) \
35   ({ int result, ignore1, ignore2;                                            \
36      __asm __volatile ("1:\tincl 8(%4)\n\t"                                   \
37                        LOCK "incl (%4)\n\t"                                   \
38                        "jng 2f\n"                                             \
39                        ".subsection 1\n"                                      \
40                        "2:\tmovl %4, %%eax\n\t"                               \
41                        "call __lll_unlock_wake\n\t"                           \
42                        "jmp 3f\n\t"                                           \
43                        ".previous\n"                                          \
44                        "3:\tpushl %%ebx\n\t"                                  \
45                        "movl %%esi, %%ecx\n\t"                                \
46                        "movl %%esi, %%edx\n\t"                                \
47                        "leal 4(%4), %%ebx\n\t"                                \
48                        "movl %5, %%eax\n\t"                                   \
49                        "int $0x80\n\t"                                        \
50                        "movl %%eax, %%edx\n\t"                                \
51                        "popl %%ebx\n\t"                                       \
52                        "orl $-1, %%eax\n\t"                                   \
53                        LOCK "xaddl %%eax, (%4)\n\t"                           \
54                        "jne 4f\n\t"                                           \
55                        ".subsection 1\n"                                      \
56                        "4:\tmovl %4, %%ecx\n\t"                               \
57                        "call __lll_lock_wait\n\t"                             \
58                        "jmp 5f\n\t"                                           \
59                        ".previous\n"                                          \
60                        "5:\tdecl 8(%4)\n\t"                                   \
61                        "xorl %0, %0\n\t"                                      \
62                        "cmpl $0, 4(%4)\n\t"                                   \
63                        "jne,pt 6f\n\t"                                        \
64                        "cmpl %7, %%edx\n\t"                                   \
65                        "jne,pn 1b\n\t"                                        \
66                        "addl %8, %0\n\t" /* Shorter than movl %7, %0 */       \
67                        "6:"                                                   \
68                        : "=a" (result), "=c" (ignore1), "=d" (ignore2),       \
69                          "=m" (*sem)                                          \
70                        : "D" (sem), "i" (SYS_futex), "S" (0),                 \
71                          "i" (-EINTR), "i" (EINTR));                          \
72      result; })
73
74
75 extern int __lll_sem_timedwait (struct sem *sem, const struct timespec *ts)
76      __attribute__ ((regparm (2))) attribute_hidden;
77 #define lll_sem_timedwait(sem, timeout) \
78   __lll_sem_timedwait (sem, timeout)
79
80
81 #define lll_sem_post(sem) \
82   (void) ({ int ignore1, ignore2, ignore3;                                    \
83             __asm __volatile ("movl $1, %%eax\n\t"                            \
84                               LOCK                                            \
85                               "xaddl %%eax, (%4)\n\t"                         \
86                               "pushl %%esi\n\t"                               \
87                               "pushl %%ebx\n\t"                               \
88                               "movl %4, %%ebx\n\t"                            \
89                               "leal 1(%%eax), %%edx\n\t"                      \
90                               "xorl %%esi, %%esi\n\t"                         \
91                               "movl %5, %%eax\n\t"                            \
92                               /* movl $FUTEX_WAKE, %ecx */                    \
93                               "movl $1, %%ecx\n\t"                            \
94                               "int $0x80\n\t"                                 \
95                               "popl %%ebx\n\t"                                \
96                               "popl %%esi"                                    \
97                               : "=&a" (ignore1), "=c" (ignore2),              \
98                                 "=m" (*sem), "=d" (ignore3)                   \
99                               : "r" (sem), "i" (SYS_futex)); })
100
101 #endif  /* lowlevelsem.h */