diff options
-rw-r--r-- | nptl/ChangeLog | 11 | ||||
-rw-r--r-- | nptl/Makefile | 3 | ||||
-rw-r--r-- | nptl/sysdeps/pthread/bits/stdio-lock.h | 86 | ||||
-rw-r--r-- | nptl/sysdeps/unix/sysv/linux/i386/i486/libc-lowlevellock.S | 10 | ||||
-rw-r--r-- | nptl/sysdeps/unix/sysv/linux/i386/i486/libc-lowlevelmutex.S | 180 | ||||
-rw-r--r-- | nptl/sysdeps/unix/sysv/linux/i386/i586/libc-lowlevelmutex.S | 1 | ||||
-rw-r--r-- | nptl/sysdeps/unix/sysv/linux/i386/i686/libc-lowlevelmutex.S | 1 |
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" |