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.
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.
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.
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
20 #ifndef _LOWLEVELSEM_H
21 #define _LOWLEVELSEM_H 1
23 #include <dl-sysdep.h>
28 # define LOCK /* nothing */
37 #ifdef I386_USE_SYSENTER
39 # define LLL_SEM_ENTER_KERNEL(arg) "call *%%gs:%P" #arg "\n\t"
41 # define LLL_SEM_ENTER_KERNEL(arg) "call *_dl_sysinfo\n\t"
44 # define LLL_SEM_ENTER_KERNEL(arg) "int $0x80\n\t"
47 #define lll_sem_wait(sem) \
48 ({ int result, ignore1, ignore2; \
49 __asm __volatile ("1:\tincl 8(%4)\n\t" \
50 LOCK "incl (%4)\n\t" \
53 "2:\tmovl %4, %%eax\n\t" \
54 "call __lll_unlock_wake\n\t" \
57 "3:\tpushl %%ebx\n\t" \
58 "movl %%esi, %%ecx\n\t" \
59 "movl %%esi, %%edx\n\t" \
60 "leal 4(%4), %%ebx\n\t" \
61 "movl %5, %%eax\n\t" \
62 LLL_SEM_ENTER_KERNEL (9) \
63 "movl %%eax, %%edx\n\t" \
65 "orl $-1, %%eax\n\t" \
66 LOCK "xaddl %%eax, (%4)\n\t" \
69 "4:\tmovl %4, %%ecx\n\t" \
70 "call __lll_lock_wait\n\t" \
73 "5:\tdecl 8(%4)\n\t" \
75 "cmpl $0, 4(%4)\n\t" \
77 "cmpl %7, %%edx\n\t" \
79 "addl %8, %0\n\t" /* Shorter than movl %7, %0 */ \
81 : "=a" (result), "=c" (ignore1), "=d" (ignore2), \
83 : "D" (sem), "i" (SYS_futex), "S" (0), \
84 "i" (-EINTR), "i" (EINTR), \
85 "i" (offsetof (tcbhead_t, sysinfo))); \
89 extern int __lll_sem_timedwait (struct sem *sem, const struct timespec *ts)
90 __attribute__ ((regparm (2))) attribute_hidden;
91 #define lll_sem_timedwait(sem, timeout) \
92 __lll_sem_timedwait (sem, timeout)
95 #define lll_sem_post(sem) \
96 (void) ({ int ignore1, ignore2, ignore3; \
97 __asm __volatile ("movl $1, %%eax\n\t" \
99 "xaddl %%eax, (%4)\n\t" \
102 "movl %4, %%ebx\n\t" \
103 "leal 1(%%eax), %%edx\n\t" \
104 "xorl %%esi, %%esi\n\t" \
105 "movl %5, %%eax\n\t" \
106 /* movl $FUTEX_WAKE, %ecx */ \
107 "movl $1, %%ecx\n\t" \
108 LLL_SEM_ENTER_KERNEL (6) \
111 : "=&a" (ignore1), "=c" (ignore2), \
112 "=m" (*sem), "=d" (ignore3) \
113 : "r" (sem), "i" (SYS_futex), \
114 "i" (offsetof (tcbhead_t, sysinfo))); })
116 #endif /* lowlevelsem.h */