aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--nptl/ChangeLog11
-rw-r--r--nptl/Makefile3
-rw-r--r--nptl/sysdeps/pthread/bits/stdio-lock.h86
-rw-r--r--nptl/sysdeps/unix/sysv/linux/i386/i486/libc-lowlevellock.S10
-rw-r--r--nptl/sysdeps/unix/sysv/linux/i386/i486/libc-lowlevelmutex.S180
-rw-r--r--nptl/sysdeps/unix/sysv/linux/i386/i586/libc-lowlevelmutex.S1
-rw-r--r--nptl/sysdeps/unix/sysv/linux/i386/i686/libc-lowlevelmutex.S1
7 files changed, 281 insertions, 11 deletions
diff --git a/nptl/ChangeLog b/nptl/ChangeLog
index ea32d2aabb..c8819b243e 100644
--- a/nptl/ChangeLog
+++ b/nptl/ChangeLog
@@ -1,3 +1,14 @@
+2002-12-18 Ulrich Drepper <drepper@redhat.com>
+
+ * sysdeps/pthread/bits/stdio-lock.h: New file.
+ * sysdeps/unix/sysv/linux/i386/i486/libc-lowlevelmutex.S: New file.
+ * sysdeps/unix/sysv/linux/i386/i586/libc-lowlevelmutex.S: New file.
+ * sysdeps/unix/sysv/linux/i386/i686/libc-lowlevelmutex.S: New file.
+ * Makefile (routines): Add libc-lowlevelmutex.
+
+ * sysdeps/unix/sysv/linux/i386/i486/libc-lowlevellock.S: Remove
+ __i686.get_pc_thunk.dx.
+
2002-12-17 Jakub Jelinek <jakub@redhat.com>
* Makefile (libpthread-shared-only-routines): Add pt-allocrtsig.
diff --git a/nptl/Makefile b/nptl/Makefile
index 6b09f08f6a..5c8c4c6a74 100644
--- a/nptl/Makefile
+++ b/nptl/Makefile
@@ -28,7 +28,8 @@ headers := pthread.h semaphore.h
extra-libs := libpthread
extra-libs-others := $(extra-libs)
-routines = alloca_cutoff forward libc-lowlevellock libc-cancellation
+routines = alloca_cutoff forward libc-lowlevellock libc-lowlevelmutex \
+ libc-cancellation
shared-only-routines = forward
libpthread-routines = init events \
diff --git a/nptl/sysdeps/pthread/bits/stdio-lock.h b/nptl/sysdeps/pthread/bits/stdio-lock.h
new file mode 100644
index 0000000000..ea622e4142
--- /dev/null
+++ b/nptl/sysdeps/pthread/bits/stdio-lock.h
@@ -0,0 +1,86 @@
+/* Thread package specific definitions of stream lock type. Generic version.
+ Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _BITS_STDIO_LOCK_H
+#define _BITS_STDIO_LOCK_H 1
+
+#include <bits/libc-lock.h>
+#include <lowlevellock.h>
+
+
+typedef struct { int lock; int cnt; void *owner; } _IO_lock_t;
+
+#define _IO_lock_initializer { LLL_MUTEX_LOCK_INITIALIZER, 0, NULL }
+
+#define _IO_lock_init(_name) \
+ ((_name) = (_IO_lock_t) _IO_lock_initializer , 0)
+
+#define _IO_lock_fini(_name) \
+ ((void) 0)
+
+#define _IO_lock_lock(_name) \
+ do { \
+ void *__self = THREAD_SELF; \
+ if ((_name).owner != __self) \
+ { \
+ lll_mutex_lock ((_name).lock); \
+ (_name).owner = __self; \
+ } \
+ ++(_name).cnt; \
+ } while (0)
+
+#define _IO_lock_trylock(_name) \
+ ({ \
+ int __result = 0; \
+ void *__self = THREAD_SELF; \
+ if ((_name).owner != __self) \
+ { \
+ if (lll_mutex_trylock ((_name).lock) == 0) \
+ { \
+ (_name).owner = __self; \
+ (_name).cnt = 1; \
+ } \
+ else \
+ __result = EBUSY; \
+ } \
+ else \
+ ++(_name).cnt; \
+ __result; \
+ })
+
+#define _IO_lock_unlock(_name) \
+ do { \
+ if (--(_name).cnt == 0) \
+ { \
+ (_name).owner = NULL; \
+ lll_mutex_unlock ((_name).lock); \
+ } \
+ } while (0)
+
+
+
+#define _IO_cleanup_region_start(_fct, _fp) \
+ __libc_cleanup_region_start (((_fp)->_flags & _IO_USER_LOCK) == 0, _fct, _fp)
+#define _IO_cleanup_region_start_noarg(_fct) \
+ __libc_cleanup_region_start (1, _fct, NULL)
+#define _IO_cleanup_region_end(_doit) \
+ __libc_cleanup_region_end (_doit)
+
+
+#endif /* bits/stdio-lock.h */
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/i486/libc-lowlevellock.S b/nptl/sysdeps/unix/sysv/linux/i386/i486/libc-lowlevellock.S
index 27275e3158..334866db6b 100644
--- a/nptl/sysdeps/unix/sysv/linux/i386/i486/libc-lowlevellock.S
+++ b/nptl/sysdeps/unix/sysv/linux/i386/i486/libc-lowlevellock.S
@@ -183,13 +183,3 @@ __lll_timedwait_tid:
6: movl $ETIMEDOUT, %eax
jmp 3b
.size __lll_timedwait_tid,.-__lll_timedwait_tid
-
-
- .section .gnu.linkonce.t.__i686.get_pc_thunk.dx,"ax",@progbits
- .globl __i686.get_pc_thunk.dx
- .hidden __i686.get_pc_thunk.dx
- .type __i686.get_pc_thunk.dx,@function
-__i686.get_pc_thunk.dx:
- movl (%esp), %edx
- ret
- .size __i686.get_pc_thunk.dx,.-__i686.get_pc_thunk.dx
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/i486/libc-lowlevelmutex.S b/nptl/sysdeps/unix/sysv/linux/i386/i486/libc-lowlevelmutex.S
new file mode 100644
index 0000000000..dac8f4a884
--- /dev/null
+++ b/nptl/sysdeps/unix/sysv/linux/i386/i486/libc-lowlevelmutex.S
@@ -0,0 +1,180 @@
+/* Copyright (C) 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ .text
+
+#define SYS_gettimeofday __NR_gettimeofday
+#define SYS_futex 240
+#define FUTEX_WAIT 0
+#define FUTEX_WAKE 1
+
+#define EWOULDBLOCK 11
+#define EINVAL 22
+#define ETIMEDOUT 110
+
+
+ .globl __lll_mutex_lock_wait
+ .type __lll_mutex_lock_wait,@function
+ .hidden __lll_mutex_lock_wait
+ .align 16
+__lll_mutex_lock_wait:
+ pushl %esi
+ pushl %ebx
+ pushl %edx
+
+ movl %ecx, %ebx
+ xorl %esi, %esi /* No timeout. */
+ xorl %ecx, %ecx /* movl $FUTEX_WAIT, %ecx */
+1:
+ leal 1(%eax), %edx /* account for the preceeded xadd. */
+ movl $SYS_futex, %eax
+ int $0x80
+
+ movl $1, %eax
+#ifndef UP
+ cmpl $0, %gs:MULTIPLE_THREADS_OFFSET
+ je,pt 0f
+ lock
+0:
+#endif
+ xaddl %eax, (%ebx)
+ testl %eax, %eax
+ jne 1b
+
+ movl $2, (%ebx)
+
+ popl %edx
+ popl %ebx
+ popl %esi
+ ret
+ .size __lll_mutex_lock_wait,.-__lll_mutex_lock_wait
+
+
+ .globl __lll_mutex_timedlock_wait
+ .type __lll_mutex_timedlock_wait,@function
+ .hidden __lll_mutex_timedlock_wait
+ .align 16
+__lll_mutex_timedlock_wait:
+ /* Check for a valid timeout value. */
+ cmpl $1000000000, 4(%edx)
+ jae 3f
+
+ pushl %edi
+ pushl %esi
+ pushl %ebx
+ pushl %ebp
+
+ /* Stack frame for the timespec and timeval structs. */
+ subl $8, %esp
+
+ movl %ecx, %ebp
+ movl %edx, %edi
+ leal 1(%eax), %esi
+
+ /* Get current time. */
+1:
+ movl %esp, %ebx
+ xorl %ecx, %ecx
+ movl $SYS_gettimeofday, %eax
+ int $0x80
+
+ /* Compute relative timeout. */
+ movl 4(%esp), %eax
+ movl $1000, %edx
+ mul %edx /* Milli seconds to nano seconds. */
+ movl (%edi), %ecx
+ movl 4(%edi), %edx
+ subl (%esp), %ecx
+ subl %eax, %edx
+ jns 4f
+ addl $1000000000, %edx
+ decl %ecx
+4: testl %ecx, %ecx
+ js 5f /* Time is already up. */
+
+ /* Futex call. */
+ movl %ecx, (%esp) /* Store relative timeout. */
+ movl %edx, 4(%esp)
+ movl %esi, %edx
+ movl %esp, %esi
+ xorl %ecx, %ecx /* movl $FUTEX_WAIT, %ecx */
+ movl %ebp, %ebx
+ movl $SYS_futex, %eax
+ int $0x80
+
+ movl $1, %esi
+#ifndef UP
+ cmpl $0, %gs:MULTIPLE_THREADS_OFFSET
+ je,pt 0f
+ lock
+0:
+#endif
+ xaddl %esi, (%ebx)
+ testl %esi, %esi
+ jne 7f
+
+ movl $2, (%ebx)
+ xorl %eax, %eax
+
+6: addl $8, %esp
+ popl %ebp
+ popl %ebx
+ popl %esi
+ popl %edi
+ ret
+
+ /* Check whether the time expired. */
+7: cmpl $-ETIMEDOUT, %eax
+ je 5f
+ jmp 1b
+
+3: movl $EINVAL, %eax
+ ret
+
+5: movl $ETIMEDOUT, %eax
+ jmp 6b
+ .size __lll_mutex_timedlock_wait,.-__lll_mutex_timedlock_wait
+
+
+ .globl __lll_mutex_unlock_wake
+ .type __lll_mutex_unlock_wake,@function
+ .hidden __lll_mutex_unlock_wake
+ .align 16
+__lll_mutex_unlock_wake:
+ pushl %esi
+ pushl %ebx
+ pushl %ecx
+ pushl %edx
+
+ movl $FUTEX_WAKE, %ecx
+ movl %eax, %ebx
+ xorl %esi, %esi
+ movl $0, (%ebx)
+ movl $1, %edx /* Wake one thread. */
+ movl $SYS_futex, %eax
+ int $0x80
+
+ popl %edx
+ popl %ecx
+ popl %ebx
+ popl %esi
+ ret
+ .size __lll_mutex_unlock_wake,.-__lll_mutex_unlock_wake
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/i586/libc-lowlevelmutex.S b/nptl/sysdeps/unix/sysv/linux/i386/i586/libc-lowlevelmutex.S
new file mode 100644
index 0000000000..7c24ed1d3c
--- /dev/null
+++ b/nptl/sysdeps/unix/sysv/linux/i386/i586/libc-lowlevelmutex.S
@@ -0,0 +1 @@
+#include "../i486/libc-lowlevelmutex.S"
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/i686/libc-lowlevelmutex.S b/nptl/sysdeps/unix/sysv/linux/i386/i686/libc-lowlevelmutex.S
new file mode 100644
index 0000000000..7c24ed1d3c
--- /dev/null
+++ b/nptl/sysdeps/unix/sysv/linux/i386/i686/libc-lowlevelmutex.S
@@ -0,0 +1 @@
+#include "../i486/libc-lowlevelmutex.S"