about summary refs log tree commit diff
path: root/nptl
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2002-12-18 10:56:40 +0000
committerUlrich Drepper <drepper@redhat.com>2002-12-18 10:56:40 +0000
commitd7913e0e256e842a3ff43b1a0854b351f585645d (patch)
tree12410015ce1a133eb10783ed89d6cd85b30c6272 /nptl
parent6ed5da8f484ccafb6e1b131514d8c01efc5affbc (diff)
downloadglibc-d7913e0e256e842a3ff43b1a0854b351f585645d.tar.gz
glibc-d7913e0e256e842a3ff43b1a0854b351f585645d.tar.xz
glibc-d7913e0e256e842a3ff43b1a0854b351f585645d.zip
Update.
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.
Diffstat (limited to 'nptl')
-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"