diff options
Diffstat (limited to 'libpthread/nptl/sysdeps/unix/sysv/linux/i386')
66 files changed, 5164 insertions, 0 deletions
| diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/Makefile b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/Makefile new file mode 100644 index 000000000..43a6fad84 --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/Makefile @@ -0,0 +1,13 @@ +# Makefile for uClibc NPTL +# +# Copyright (C) 2005 Steven J. Hill <sjhill@uclibc.org> +# +# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. +# + +top_srcdir=../../../../../../../ +top_builddir=../../../../../../../ +all: objs +include $(top_builddir)Rules.mak +include Makefile.arch +include $(top_srcdir)Makerules diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/Makefile.arch b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/Makefile.arch new file mode 100644 index 000000000..740ee7fcb --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/Makefile.arch @@ -0,0 +1,74 @@ +# Makefile for uClibc NPTL +# +# Copyright (C) 2006 Steven J. Hill <sjhill@uclibc.org> +# +# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. +# +LINUX_ARCH_DIR:=$(top_srcdir)libpthread/nptl/sysdeps/unix/sysv/linux/i386 +LINUX_ARCH_OUT:=$(top_builddir)libpthread/nptl/sysdeps/unix/sysv/linux/i386 + + +libpthread_SSRC = pt-vfork.S clone.S pthread_spin_unlock.S pthread_once.S +libpthread_CSRC = pthread_spin_init.c pt-__syscall_error.c + +libc_a_CSRC = fork.c +libc_a_SSRC = clone.S vfork.S + +libpthread_SSRC += i486/lowlevellock.S i486/pthread_barrier_wait.S i486/pthread_cond_signal.S i486/pthread_cond_broadcast.S \ +		   i486/sem_post.S i486/sem_timedwait.S \ +		   i486/sem_trywait.S i486/sem_wait.S i486/pthread_rwlock_rdlock.S i486/pthread_rwlock_wrlock.S \ +		   i486/pthread_rwlock_timedrdlock.S i486/pthread_rwlock_timedwrlock.S i486/pthread_rwlock_unlock.S +#i486/pthread_cond_timedwait.S i486/pthread_cond_wait.S + +libc_a_SSRC += i486/libc-lowlevellock.S + + +CFLAGS-OMIT-fork.c = -DNOT_IN_libc=1 -DIS_IN_libpthread=1 + +ifeq ($(UCLIBC_HAS_STDIO_FUTEXES),y) +CFLAGS-fork.c = -D__USE_STDIO_FUTEXES__ +endif + +ASFLAGS-pt-vfork.S = -DNOT_IN_libc=1 -DIS_IN_libpthread=1 -D_LIBC_REENTRANT -DUSE___THREAD +ASFLAGS-lowlevellock.S = -DNOT_IN_libc=1 -DIS_IN_libpthread=1 -D_LIBC_REENTRANT -DUSE___THREAD +ASFLAGS-pthread_once.S = -DNOT_IN_libc=1 -DIS_IN_libpthread=1 -D_LIBC_REENTRANT -DUSE___THREAD +ASFLAGS-pthread_spin_unlock.S = -DNOT_IN_libc=1 -DIS_IN_libpthread=1 -D_LIBC_REENTRANT -DUSE___THREAD + + +ASFLAGS-clone.S = -D_LIBC_REENTRANT +ASFLAGS-vfork.S = -D_LIBC_REENTRANT +ASFLAGS-libc-lowlevellock.S = -D_LIBC_REENTRANT + +ifeq ($(UCLIBC_HAS_THREADS_NATIVE),y) +#Needed to use the correct SYSCALL_ERROR_HANDLER +ASFLAGS-clone.S += -DUSE___THREAD +ASFLAGS-vfork.S += -DUSE___THREAD +endif + +CFLAGS += $(SSP_ALL_CFLAGS) +#CFLAGS:=$(CFLAGS:-O1=-O2) + +LINUX_ARCH_OBJ:=$(patsubst %.S,$(LINUX_ARCH_OUT)/%.o,$(libpthread_SSRC)) +LINUX_ARCH_OBJ+=$(patsubst %.c,$(LINUX_ARCH_OUT)/%.o,$(libpthread_CSRC)) + +ifeq ($(DOPIC),y) +libpthread-a-y += $(LINUX_ARCH_OBJ:.o=.os) +else +libpthread-a-y += $(LINUX_ARCH_OBJ) +endif +libpthread-so-y += $(LINUX_ARCH_OBJ:.o=.oS) + +libpthread-nomulti-y+=$(LINUX_ARCH_OBJS) + +LIBC_LINUX_ARCH_OBJ:=$(patsubst %.c,$(LINUX_ARCH_OUT)/%.o,$(libc_a_CSRC)) +LIBC_LINUX_ARCH_OBJ+=$(patsubst %.S,$(LINUX_ARCH_OUT)/%.o,$(libc_a_SSRC)) + +libc-static-y+=$(LIBC_LINUX_ARCH_OBJ) +libc-shared-y+=$(LIBC_LINUX_ARCH_OBJ:.o=.oS) + +libc-nomulti-y+=$(LIBC_LINUX_ARCH_OBJ) + +objclean-y+=nptl_linux_arch_clean + +nptl_linux_arch_clean: +	$(do_rm) $(addprefix $(LINUX_ARCH_OUT)/*., o os oS) diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/bits/pthreadtypes.h b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/bits/pthreadtypes.h new file mode 100644 index 000000000..0ec6e5534 --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/bits/pthreadtypes.h @@ -0,0 +1,170 @@ +/* Copyright (C) 2002, 2003, 2004 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_PTHREADTYPES_H +#define _BITS_PTHREADTYPES_H	1 + +#define __SIZEOF_PTHREAD_ATTR_T 36 +#define __SIZEOF_PTHREAD_MUTEX_T 24 +#define __SIZEOF_PTHREAD_MUTEXATTR_T 4 +#define __SIZEOF_PTHREAD_COND_T 48 +#define __SIZEOF_PTHREAD_COND_COMPAT_T 12 +#define __SIZEOF_PTHREAD_CONDATTR_T 4 +#define __SIZEOF_PTHREAD_RWLOCK_T 32 +#define __SIZEOF_PTHREAD_RWLOCKATTR_T 8 +#define __SIZEOF_PTHREAD_BARRIER_T 20 +#define __SIZEOF_PTHREAD_BARRIERATTR_T 4 + + +/* Thread identifiers.  The structure of the attribute type is not +   exposed on purpose.  */ +typedef unsigned long int pthread_t; + + +typedef union +{ +  char __size[__SIZEOF_PTHREAD_ATTR_T]; +  long int __align; +} pthread_attr_t; + + +typedef struct __pthread_internal_slist +{ +  struct __pthread_internal_slist *__next; +} __pthread_slist_t; + + +/* Data structures for mutex handling.  The structure of the attribute +   type is not exposed on purpose.  */ +typedef union +{ +  struct __pthread_mutex_s +  { +    int __lock; +    unsigned int __count; +    int __owner; +    /* KIND must stay at this position in the structure to maintain +       binary compatibility.  */ +    int __kind; +    unsigned int __nusers; +    __extension__ union +    { +      int __spins; +      __pthread_slist_t __list; +    }; +  } __data; +  char __size[__SIZEOF_PTHREAD_MUTEX_T]; +  long int __align; +} pthread_mutex_t; + +typedef union +{ +  char __size[__SIZEOF_PTHREAD_MUTEXATTR_T]; +  long int __align; +} pthread_mutexattr_t; + + +/* Data structure for conditional variable handling.  The structure of +   the attribute type is not exposed on purpose.  */ +typedef union +{ +  struct +  { +    int __lock; +    unsigned int __futex; +    __extension__ unsigned long long int __total_seq; +    __extension__ unsigned long long int __wakeup_seq; +    __extension__ unsigned long long int __woken_seq; +    void *__mutex; +    unsigned int __nwaiters; +    unsigned int __broadcast_seq; +  } __data; +  char __size[__SIZEOF_PTHREAD_COND_T]; +  __extension__ long long int __align; +} pthread_cond_t; + +typedef union +{ +  char __size[__SIZEOF_PTHREAD_CONDATTR_T]; +  long int __align; +} pthread_condattr_t; + + +/* Keys for thread-specific data */ +typedef unsigned int pthread_key_t; + + +/* Once-only execution */ +typedef int pthread_once_t; + + +#if defined __USE_UNIX98 || defined __USE_XOPEN2K +/* Data structure for read-write lock variable handling.  The +   structure of the attribute type is not exposed on purpose.  */ +typedef union +{ +  struct +  { +    int __lock; +    unsigned int __nr_readers; +    unsigned int __readers_wakeup; +    unsigned int __writer_wakeup; +    unsigned int __nr_readers_queued; +    unsigned int __nr_writers_queued; +    /* FLAGS must stay at this position in the structure to maintain +       binary compatibility.  */ +    unsigned int __flags; +    int __writer; +  } __data; +  char __size[__SIZEOF_PTHREAD_RWLOCK_T]; +  long int __align; +} pthread_rwlock_t; + +typedef union +{ +  char __size[__SIZEOF_PTHREAD_RWLOCKATTR_T]; +  long int __align; +} pthread_rwlockattr_t; +#endif + + +#ifdef __USE_XOPEN2K +/* POSIX spinlock data type.  */ +typedef volatile int pthread_spinlock_t; + + +/* POSIX barriers data type.  The structure of the type is +   deliberately not exposed.  */ +typedef union +{ +  char __size[__SIZEOF_PTHREAD_BARRIER_T]; +  long int __align; +} pthread_barrier_t; + +typedef union +{ +  char __size[__SIZEOF_PTHREAD_BARRIERATTR_T]; +  int __align; +} pthread_barrierattr_t; +#endif + + +/* Extra attributes for the cleanup functions.  */ +#define __cleanup_fct_attribute __attribute ((regparm (1))) + +#endif	/* bits/pthreadtypes.h */ diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/bits/semaphore.h b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/bits/semaphore.h new file mode 100644 index 000000000..e6c5d845c --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/bits/semaphore.h @@ -0,0 +1,39 @@ +/* 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.  */ + +#ifndef _SEMAPHORE_H +# error "Never use <bits/semaphore.h> directly; include <semaphore.h> instead." +#endif + + +#define __SIZEOF_SEM_T	16 + + +/* Value returned if `sem_open' failed.  */ +#define SEM_FAILED      ((sem_t *) 0) + +/* Maximum value the semaphore can have.  */ +#define SEM_VALUE_MAX   (2147483647) + + +typedef union +{ +  char __size[__SIZEOF_SEM_T]; +  long int __align; +} sem_t; diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/clone.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/clone.S new file mode 100644 index 000000000..9c7c46467 --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/clone.S @@ -0,0 +1,2 @@ +#define RESET_PID +#include <libc/sysdeps/linux/i386/clone.S> diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/createthread.c b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/createthread.c new file mode 100644 index 000000000..35719be96 --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/createthread.c @@ -0,0 +1,49 @@ +/* Copyright (C) 2002, 2003 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.  */ + +/* The "thread register" gets initialized from a segment descriptor. +   Initialize such a descriptor first.  */ +#define PREPARE_CREATE \ +  union user_desc_init desc;						      \ +									      \ +  /* Describe the thread-local storage segment.  */			      \ +									      \ +  /* The 'entry_number' field.  The first three bits of the segment	      \ +     register value select the GDT, ignore them.  We get the index	      \ +     from the value of the %gs register in the current thread.  */	      \ +  desc.vals[0] = TLS_GET_GS () >> 3;					      \ +  /* The 'base_addr' field.  Pointer to the TCB.  */			      \ +  desc.vals[1] = (unsigned long int) pd;				      \ +  /* The 'limit' field.  We use 4GB which is 0xfffff pages.  */		      \ +  desc.vals[2] = 0xfffff;						      \ +  /* Collapsed value of the bitfield:					      \ +       .seg_32bit = 1							      \ +       .contents = 0							      \ +       .read_exec_only = 0						      \ +       .limit_in_pages = 1						      \ +       .seg_not_present = 0						      \ +       .useable = 1 */							      \ +  desc.vals[3] = 0x51 + +/* Value passed to 'clone' for initialization of the thread register.  */ +#define TLS_VALUE &desc.desc + + +/* Get the real implementation.  */ +#include <sysdeps/pthread/createthread.c> diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/fork.c b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/fork.c new file mode 100644 index 000000000..b874538b3 --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/fork.c @@ -0,0 +1,31 @@ +/* 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 <sched.h> +#include <signal.h> +#include <stdio.h> +#include <sysdep.h> +#include <tls.h> + +#define ARCH_FORK() \ +  INLINE_SYSCALL (clone, 5,						      \ +		  CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID | SIGCHLD, 0,     \ +		  NULL, NULL, &THREAD_SELF->tid) + +#include "../fork.c" diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/libc-lowlevellock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/libc-lowlevellock.S new file mode 100644 index 000000000..223b11108 --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/libc-lowlevellock.S @@ -0,0 +1,30 @@ +/* Copyright (C) 2002, 2003 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.  */ + +/* In libc.so we do not unconditionally use the lock prefix.  Only if +   the application is using threads.  */ +#ifndef UP +# define LOCK \ +	cmpl	$0, %gs:MULTIPLE_THREADS_OFFSET; 			      \ +	je,pt	0f;							      \ +	lock;								      \ +0: +#endif + +#include "lowlevellock.S" diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/lowlevellock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/lowlevellock.S new file mode 100644 index 000000000..955e119ab --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/lowlevellock.S @@ -0,0 +1,283 @@ +/* Copyright (C) 2002, 2003, 2004 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> +#include <pthread-errnos.h> + +	.text + +#ifndef LOCK +# ifdef UP +#  define LOCK +# else +#  define LOCK lock +# endif +#endif + +#define FUTEX_WAIT		0 +#define FUTEX_WAKE		1 + + +	.globl	__lll_mutex_lock_wait +	.type	__lll_mutex_lock_wait,@function +	.hidden	__lll_mutex_lock_wait +	.align	16 +__lll_mutex_lock_wait: +	pushl	%edx +	pushl	%ebx +	pushl	%esi + +	movl	$2, %edx +	movl	%ecx, %ebx +	xorl	%esi, %esi	/* No timeout.  */ +	xorl	%ecx, %ecx	/* movl $FUTEX_WAIT, %ecx */ + +	cmpl	%edx, %eax	/* NB:	 %edx == 2 */ +	jne 2f + +1:	movl	$SYS_futex, %eax +	ENTER_KERNEL + +2:	movl	%edx, %eax +	xchgl	%eax, (%ebx)	/* NB:	 lock is implied */ + +	testl	%eax, %eax +	jnz,pn	1b + +	popl	%esi +	popl	%ebx +	popl	%edx +	ret +	.size	__lll_mutex_lock_wait,.-__lll_mutex_lock_wait + + +#ifdef NOT_IN_libc +	.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 + +1: +	/* Get current time.  */ +	movl	%esp, %ebx +	xorl	%ecx, %ecx +	movl	$SYS_gettimeofday, %eax +	ENTER_KERNEL + +	/* 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 +	subl	$1, %ecx +4:	testl	%ecx, %ecx +	js	5f		/* Time is already up.  */ + +	/* Store relative timeout.  */ +	movl	%ecx, (%esp) +	movl	%edx, 4(%esp) + +	movl	%ebp, %ebx + +	movl	$1, %eax +	movl	$2, %edx +	LOCK +	cmpxchgl %edx, (%ebx) + +	testl	%eax, %eax +	je	8f + +	/* Futex call.  */ +	movl	%esp, %esi +	xorl	%ecx, %ecx	/* movl $FUTEX_WAIT, %ecx */ +	movl	$SYS_futex, %eax +	ENTER_KERNEL +	movl	%eax, %ecx + +8:				/* NB: %edx == 2 */ +	xorl	%eax, %eax +	LOCK +	cmpxchgl %edx, (%ebx) + +	jnz	7f + +6:	addl	$8, %esp +	popl	%ebp +	popl	%ebx +	popl	%esi +	popl	%edi +	ret + +	/* Check whether the time expired.  */ +7:	cmpl	$-ETIMEDOUT, %ecx +	je	5f + +	/* Make sure the current holder knows we are going to sleep.  */ +	movl	%edx, %eax +	xchgl	%eax, (%ebx) +	testl	%eax, %eax +	jz	6b +	jmp	1b + +3:	movl	$EINVAL, %eax +	ret + +5:	movl	$ETIMEDOUT, %eax +	jmp	6b +	.size	__lll_mutex_timedlock_wait,.-__lll_mutex_timedlock_wait +#endif + + +#ifdef NOT_IN_libc +	.globl	lll_unlock_wake_cb +	.type	lll_unlock_wake_cb,@function +	.hidden	lll_unlock_wake_cb +	.align	16 +lll_unlock_wake_cb: +	pushl	%ebx +	pushl	%ecx +	pushl	%edx + +	movl	20(%esp), %ebx +	LOCK +	subl	$1, (%ebx) +	je	1f + +	movl	$FUTEX_WAKE, %ecx +	movl	$1, %edx	/* Wake one thread.  */ +	movl	$SYS_futex, %eax +	movl	$0, (%ebx) +	ENTER_KERNEL + +1:	popl	%edx +	popl	%ecx +	popl	%ebx +	ret +	.size	lll_unlock_wake_cb,.-lll_unlock_wake_cb +#endif + + +	.globl	__lll_mutex_unlock_wake +	.type	__lll_mutex_unlock_wake,@function +	.hidden	__lll_mutex_unlock_wake +	.align	16 +__lll_mutex_unlock_wake: +	pushl	%ebx +	pushl	%ecx +	pushl	%edx + +	movl	%eax, %ebx +	movl	$0, (%eax) +	movl	$FUTEX_WAKE, %ecx +	movl	$1, %edx	/* Wake one thread.  */ +	movl	$SYS_futex, %eax +	ENTER_KERNEL + +	popl	%edx +	popl	%ecx +	popl	%ebx +	ret +	.size	__lll_mutex_unlock_wake,.-__lll_mutex_unlock_wake + + +#ifdef NOT_IN_libc +	.globl	__lll_timedwait_tid +	.type	__lll_timedwait_tid,@function +	.hidden	__lll_timedwait_tid +	.align	16 +__lll_timedwait_tid: +	pushl	%edi +	pushl	%esi +	pushl	%ebx +	pushl	%ebp + +	movl	%eax, %ebp +	movl	%edx, %edi +	subl	$8, %esp + +	/* Get current time.  */ +2:	movl	%esp, %ebx +	xorl	%ecx, %ecx +	movl	$SYS_gettimeofday, %eax +	ENTER_KERNEL + +	/* 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	5f +	addl	$1000000000, %edx +	subl	$1, %ecx +5:	testl	%ecx, %ecx +	js	6f		/* Time is already up.  */ + +	movl	%ecx, (%esp)	/* Store relative timeout.  */ +	movl	%edx, 4(%esp) + +	movl	(%ebp), %edx +	testl	%edx, %edx +	jz	4f + +	movl	%esp, %esi +	xorl	%ecx, %ecx	/* movl $FUTEX_WAIT, %ecx */ +	movl	%ebp, %ebx +	movl	$SYS_futex, %eax +	ENTER_KERNEL + +	cmpl	$0, (%ebx) +	jne	1f +4:	xorl	%eax, %eax + +3:	addl	$8, %esp +	popl	%ebp +	popl	%ebx +	popl	%esi +	popl	%edi +	ret + +1:	cmpl	$-ETIMEDOUT, %eax +	jne	2b +6:	movl	$ETIMEDOUT, %eax +	jmp	3b +	.size	__lll_timedwait_tid,.-__lll_timedwait_tid +#endif diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_barrier_wait.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_barrier_wait.S new file mode 100644 index 000000000..2af9e38cd --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_barrier_wait.S @@ -0,0 +1,162 @@ +/* Copyright (C) 2002, 2003, 2004 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> +#include <lowlevelbarrier.h> + +#define FUTEX_WAIT	0 +#define FUTEX_WAKE	1 + +#ifndef UP +# define LOCK lock +#else +# define LOCK +#endif + + +	.text + +	.globl	pthread_barrier_wait +	.type	pthread_barrier_wait,@function +	.align	16 +pthread_barrier_wait: +	pushl	%ebx + +	movl	8(%esp), %ebx + +	/* Get the mutex.  */ +	movl	$1, %edx +	xorl	%eax, %eax +	LOCK +	cmpxchgl %edx, MUTEX(%ebx) +	jnz	1f + +	/* One less waiter.  If this was the last one needed wake +	   everybody.  */ +2:	subl	$1, LEFT(%ebx) +	je	3f + +	/* There are more threads to come.  */ +	pushl	%esi + +#if CURR_EVENT == 0 +	movl	(%ebx), %edx +#else +	movl	CURR_EVENT(%ebx), %edx +#endif + +	/* Release the mutex.  */ +	LOCK +	subl	$1, MUTEX(%ebx) +	jne	6f + +	/* Wait for the remaining threads.  The call will return immediately +	   if the CURR_EVENT memory has meanwhile been changed.  */ +7:	xorl	%ecx, %ecx		/* movl $FUTEX_WAIT, %ecx */ +	xorl	%esi, %esi +8:	movl	$SYS_futex, %eax +	ENTER_KERNEL + +	/* Don't return on spurious wakeups.  The syscall does not change +	   any register except %eax so there is no need to reload any of +	   them.  */ +#if CURR_EVENT == 0 +	cmpl	%edx, (%ebx) +#else +	cmpl	%edx, CURR_EVENT(%ebx) +#endif +	je,pn	8b + +	/* Increment LEFT.  If this brings the count back to the +	   initial count unlock the object.  */ +	movl	$1, %edx +	movl	INIT_COUNT(%ebx), %ecx +	LOCK +	xaddl	%edx, LEFT(%ebx) +	subl	$1, %ecx +	cmpl	%ecx, %edx +	jne,pt	10f + +	/* Release the mutex.  We cannot release the lock before +	   waking the waiting threads since otherwise a new thread might +	   arrive and gets waken up, too.  */ +	LOCK +	subl	$1, MUTEX(%ebx) +	jne	9f + +	/* Note: %esi is still zero.  */ +10:	movl	%esi, %eax		/* != PTHREAD_BARRIER_SERIAL_THREAD */ + +	popl	%esi +	popl	%ebx +	ret + +	/* The necessary number of threads arrived.  */ +3: +#if CURR_EVENT == 0 +	addl	$1, (%ebx) +#else +	addl	$1, CURR_EVENT(%ebx) +#endif + +	/* Wake up all waiters.  The count is a signed number in the kernel +	   so 0x7fffffff is the highest value.  */ +	movl	$0x7fffffff, %edx +	movl	$FUTEX_WAKE, %ecx +	movl	$SYS_futex, %eax +	ENTER_KERNEL + +	/* Increment LEFT.  If this brings the count back to the +	   initial count unlock the object.  */ +	movl	$1, %edx +	movl	INIT_COUNT(%ebx), %ecx +	LOCK +	xaddl	%edx, LEFT(%ebx) +	subl	$1, %ecx +	cmpl	%ecx, %edx +	jne,pt	5f + +	/* Release the mutex.  We cannot release the lock before +	   waking the waiting threads since otherwise a new thread might +	   arrive and gets waken up, too.  */ +	LOCK +	subl	$1, MUTEX(%ebx) +	jne	4f + +5:	orl	$-1, %eax		/* == PTHREAD_BARRIER_SERIAL_THREAD */ + +	popl	%ebx +	ret + +1:	leal	MUTEX(%ebx), %ecx +	call	__lll_mutex_lock_wait +	jmp	2b + +4:	leal	MUTEX(%ebx), %eax +	call	__lll_mutex_unlock_wake +	jmp	5b + +6:	leal	MUTEX(%ebx), %eax +	call	__lll_mutex_unlock_wake +	jmp	7b + +9:	leal	MUTEX(%ebx), %eax +	call	__lll_mutex_unlock_wake +	jmp	10b +	.size	pthread_barrier_wait,.-pthread_barrier_wait diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_broadcast.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_broadcast.S new file mode 100644 index 000000000..6e8ffe6f6 --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_broadcast.S @@ -0,0 +1,161 @@ +/* Copyright (C) 2002, 2003, 2004 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> +#include <lowlevelcond.h> +#include <bits/kernel-features.h> + +#ifdef UP +# define LOCK +#else +# define LOCK lock +#endif + +#define FUTEX_WAIT		0 +#define FUTEX_WAKE		1 +#define FUTEX_REQUEUE		3 +#define FUTEX_CMP_REQUEUE	4 + +#define EINVAL			22 + + +	.text + +	/* int pthread_cond_broadcast (pthread_cond_t *cond) */ +	.globl	__pthread_cond_broadcast +	.type	__pthread_cond_broadcast, @function +	.align	16 +__pthread_cond_broadcast: + +	pushl	%ebx +	pushl	%esi +	pushl	%edi +	pushl	%ebp + +	movl	20(%esp), %ebx + +	/* Get internal lock.  */ +	movl	$1, %edx +	xorl	%eax, %eax +	LOCK +#if cond_lock == 0 +	cmpxchgl %edx, (%ebx) +#else +	cmpxchgl %edx, cond_lock(%ebx) +#endif +	jnz	1f + +2:	addl	$cond_futex, %ebx +	movl	total_seq+4-cond_futex(%ebx), %eax +	movl	total_seq-cond_futex(%ebx), %ebp +	cmpl	wakeup_seq+4-cond_futex(%ebx), %eax +	ja	3f +	jb	4f +	cmpl	wakeup_seq-cond_futex(%ebx), %ebp +	jna	4f + +	/* Cause all currently waiting threads to recognize they are +	   woken up.  */ +3:	movl	%ebp, wakeup_seq-cond_futex(%ebx) +	movl	%eax, wakeup_seq-cond_futex+4(%ebx) +	movl	%ebp, woken_seq-cond_futex(%ebx) +	movl	%eax, woken_seq-cond_futex+4(%ebx) +	addl	%ebp, %ebp +	addl	$1, broadcast_seq-cond_futex(%ebx) +	movl	%ebp, (%ebx) + +	/* Get the address of the mutex used.  */ +	movl	dep_mutex-cond_futex(%ebx), %edi + +	/* Unlock.  */ +	LOCK +	subl	$1, cond_lock-cond_futex(%ebx) +	jne	7f + +	/* Don't use requeue for pshared condvars.  */ +8:	cmpl	$-1, %edi +	je	9f + +	/* Wake up all threads.  */ +	movl	$FUTEX_CMP_REQUEUE, %ecx +	movl	$SYS_futex, %eax +	movl	$0x7fffffff, %esi +	movl	$1, %edx +	/* Get the address of the futex involved.  */ +# if MUTEX_FUTEX != 0 +	addl	$MUTEX_FUTEX, %edi +# endif +/* FIXME: Until Ingo fixes 4G/4G vDSO, 6 arg syscalls are broken for sysenter. +	ENTER_KERNEL  */ +	int	$0x80 + +	/* For any kind of error, which mainly is EAGAIN, we try again +	   with WAKE.  The general test also covers running on old +	   kernels.  */ +	cmpl	$0xfffff001, %eax +	jae	9f + +10:	xorl	%eax, %eax +	popl	%ebp +	popl	%edi +	popl	%esi +	popl	%ebx +	ret + +	.align	16 +	/* Unlock.  */ +4:	LOCK +	subl	$1, cond_lock-cond_futex(%ebx) +	jne	5f + +6:	xorl	%eax, %eax +	popl	%ebp +	popl	%edi +	popl	%esi +	popl	%ebx +	ret + +	/* Initial locking failed.  */ +1: +#if cond_lock == 0 +	movl	%ebx, %ecx +#else +	leal	cond_lock(%ebx), %ecx +#endif +	call	__lll_mutex_lock_wait +	jmp	2b + +	/* Unlock in loop requires waekup.  */ +5:	leal	cond_lock-cond_futex(%ebx), %eax +	call	__lll_mutex_unlock_wake +	jmp	6b + +	/* Unlock in loop requires waekup.  */ +7:	leal	cond_lock-cond_futex(%ebx), %eax +	call	__lll_mutex_unlock_wake +	jmp	8b + +9:	/* The futex requeue functionality is not available.  */ +	movl	$0x7fffffff, %edx +	movl	$FUTEX_WAKE, %ecx +	movl	$SYS_futex, %eax +	ENTER_KERNEL +	jmp	10b +	.size	__pthread_cond_broadcast, .-__pthread_cond_broadcast +weak_alias(__pthread_cond_broadcast, pthread_cond_broadcast) diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_signal.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_signal.S new file mode 100644 index 000000000..ec8217987 --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_signal.S @@ -0,0 +1,111 @@ +/* Copyright (C) 2002, 2003, 2004 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> +#include <lowlevelcond.h> +#include <bits/kernel-features.h> + +#ifdef UP +# define LOCK +#else +# define LOCK lock +#endif + +#define FUTEX_WAIT		0 +#define FUTEX_WAKE		1 +#define FUTEX_REQUEUE		3 + +#define EINVAL			22 + + +	.text + +	/* int pthread_cond_signal (pthread_cond_t *cond) */ +	.globl	__pthread_cond_signal +	.type	__pthread_cond_signal, @function +	.align	16 +__pthread_cond_signal: + +	pushl	%ebx +	pushl	%edi + +	movl	12(%esp), %edi + +	/* Get internal lock.  */ +	movl	$1, %edx +	xorl	%eax, %eax +	LOCK +#if cond_lock == 0 +	cmpxchgl %edx, (%edi) +#else +	cmpxchgl %edx, cond_lock(%edi) +#endif +	jnz	1f + +2:	leal	cond_futex(%edi), %ebx +	movl	total_seq+4(%edi), %eax +	movl	total_seq(%edi), %ecx +	cmpl	wakeup_seq+4(%edi), %eax +#if cond_lock != 0 +	/* Must use leal to preserve the flags.  */ +	leal	cond_lock(%edi), %edi +#endif +	ja	3f +	jb	4f +	cmpl	wakeup_seq-cond_futex(%ebx), %ecx +	jbe	4f + +	/* Bump the wakeup number.  */ +3:	addl	$1, wakeup_seq-cond_futex(%ebx) +	adcl	$0, wakeup_seq-cond_futex+4(%ebx) +	addl	$1, (%ebx) + +	/* Wake up one thread.  */ +	movl	$FUTEX_WAKE, %ecx +	movl	$SYS_futex, %eax +	movl	$1, %edx +	ENTER_KERNEL + +	/* Unlock.  Note that at this point %edi always points to +	   cond_lock.  */ +4:	LOCK +	subl	$1, (%edi) +	jne	5f + +6:	xorl	%eax, %eax +	popl	%edi +	popl	%ebx +	ret + +	/* Initial locking failed.  */ +1: +#if cond_lock == 0 +	movl	%edi, %ecx +#else +	leal	cond_lock(%edi), %ecx +#endif +	call	__lll_mutex_lock_wait +	jmp	2b + +	/* Unlock in loop requires wakeup.  */ +5:	movl	%edi, %eax +	call	__lll_mutex_unlock_wake +	jmp	6b +	.size	__pthread_cond_signal, .-__pthread_cond_signal +weak_alias(__pthread_cond_signal, pthread_cond_signal) diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S new file mode 100644 index 000000000..b8f0d2e4b --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S @@ -0,0 +1,465 @@ +/* Copyright (C) 2002, 2003, 2004 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> +#include <lowlevelcond.h> +#include <pthread-errnos.h> + +#ifdef UP +# define LOCK +#else +# define LOCK lock +#endif + +#define FUTEX_WAIT		0 +#define FUTEX_WAKE		1 + + +	.text + +/* int pthread_cond_timedwait (pthread_cond_t *cond, pthread_mutex_t *mutex, +			       const struct timespec *abstime)  */ +	.globl	__pthread_cond_timedwait +	.type	__pthread_cond_timedwait, @function +	.align	16 +__pthread_cond_timedwait: +.LSTARTCODE: +	pushl	%ebp +.Lpush_ebp: +	pushl	%edi +.Lpush_edi: +	pushl	%esi +.Lpush_esi: +	pushl	%ebx +.Lpush_ebx: + +	movl	20(%esp), %ebx +	movl	28(%esp), %ebp + +	cmpl	$1000000000, 4(%ebp) +	movl	$EINVAL, %eax +	jae	18f + +	/* Get internal lock.  */ +	movl	$1, %edx +	xorl	%eax, %eax +	LOCK +#if cond_lock == 0 +	cmpxchgl %edx, (%ebx) +#else +	cmpxchgl %edx, cond_lock(%ebx) +#endif +	jnz	1f + +	/* Store the reference to the mutex.  If there is already a +	   different value in there this is a bad user bug.  */ +2:	cmpl	$-1, dep_mutex(%ebx) +	movl	24(%esp), %eax +	je	17f +	movl	%eax, dep_mutex(%ebx) + +	/* Unlock the mutex.  */ +17:	xorl	%edx, %edx +	call	__pthread_mutex_unlock_usercnt + +	testl	%eax, %eax +	jne	16f + +	addl	$1, total_seq(%ebx) +	adcl	$0, total_seq+4(%ebx) +	addl	$1, cond_futex(%ebx) +	addl	$(1 << clock_bits), cond_nwaiters(%ebx) + +#define FRAME_SIZE 24 +	subl	$FRAME_SIZE, %esp +.Lsubl: + +	/* Get and store current wakeup_seq value.  */ +	movl	wakeup_seq(%ebx), %edi +	movl	wakeup_seq+4(%ebx), %edx +	movl	broadcast_seq(%ebx), %eax +	movl	%edi, 12(%esp) +	movl	%edx, 16(%esp) +	movl	%eax, 20(%esp) + +	/* Get the current time.  */ +8:	movl	%ebx, %edx +#ifdef __NR_clock_gettime +	/* Get the clock number.  */ +	movl	cond_nwaiters(%ebx), %ebx +	andl	$((1 << clock_bits) - 1), %ebx +	/* Only clocks 0 and 1 are allowed so far.  Both are handled in the +	   kernel.  */ +	leal	4(%esp), %ecx +	movl	$__NR_clock_gettime, %eax +	ENTER_KERNEL +# ifndef __ASSUME_POSIX_TIMERS +	cmpl	$-ENOSYS, %eax +	je	19f +# endif +	movl	%edx, %ebx + +	/* Compute relative timeout.  */ +	movl	(%ebp), %ecx +	movl	4(%ebp), %edx +	subl	4(%esp), %ecx +	subl	8(%esp), %edx +#else +	/* Get the current time.  */ +	leal	4(%esp), %ebx +	xorl	%ecx, %ecx +	movl	$SYS_gettimeofday, %eax +	ENTER_KERNEL +	movl	%edx, %ebx + +	/* Compute relative timeout.  */ +	movl	8(%esp), %eax +	movl	$1000, %edx +	mul	%edx		/* Milli seconds to nano seconds.  */ +	movl	(%ebp), %ecx +	movl	4(%ebp), %edx +	subl	4(%esp), %ecx +	subl	%eax, %edx +#endif +	jns	12f +	addl	$1000000000, %edx +	subl	$1, %ecx +12:	testl	%ecx, %ecx +	movl	$-ETIMEDOUT, %esi +	js	6f + +	/* Store relative timeout.  */ +21:	movl	%ecx, 4(%esp) +	movl	%edx, 8(%esp) + +	movl	cond_futex(%ebx), %edi + +	/* Unlock.  */ +	LOCK +#if cond_lock == 0 +	subl	$1, (%ebx) +#else +	subl	$1, cond_lock(%ebx) +#endif +	jne	3f + +.LcleanupSTART: +4:	call	__pthread_enable_asynccancel +	movl	%eax, (%esp) + +	leal	4(%esp), %esi +	xorl	%ecx, %ecx	/* movl $FUTEX_WAIT, %ecx */ +	movl	%edi, %edx +	addl	$cond_futex, %ebx +.Ladd_cond_futex: +	movl	$SYS_futex, %eax +	ENTER_KERNEL +	subl	$cond_futex, %ebx +.Lsub_cond_futex: +	movl	%eax, %esi + +	movl	(%esp), %eax +	call	__pthread_disable_asynccancel +.LcleanupEND: + +	/* Lock.  */ +	movl	$1, %edx +	xorl	%eax, %eax +	LOCK +#if cond_lock == 0 +	cmpxchgl %edx, (%ebx) +#else +	cmpxchgl %edx, cond_lock(%ebx) +#endif +	jnz	5f + +6:	movl	broadcast_seq(%ebx), %eax +	cmpl	20(%esp), %eax +	jne	23f + +	movl	woken_seq(%ebx), %eax +	movl	woken_seq+4(%ebx), %ecx + +	movl	wakeup_seq(%ebx), %edi +	movl	wakeup_seq+4(%ebx), %edx + +	cmpl	16(%esp), %edx +	jne	7f +	cmpl	12(%esp), %edi +	je	15f + +7:	cmpl	%ecx, %edx +	jne	9f +	cmp	%eax, %edi +	jne	9f + +15:	cmpl	$-ETIMEDOUT, %esi +	jne	8b + +	addl	$1, wakeup_seq(%ebx) +	adcl	$0, wakeup_seq+4(%ebx) +	addl	$1, cond_futex(%ebx) +	movl	$ETIMEDOUT, %esi +	jmp	14f + +23:	xorl	%esi, %esi +	jmp	24f + +9:	xorl	%esi, %esi +14:	addl	$1, woken_seq(%ebx) +	adcl	$0, woken_seq+4(%ebx) + +24:	subl	$(1 << clock_bits), cond_nwaiters(%ebx) + +	/* Wake up a thread which wants to destroy the condvar object.  */ +	movl	total_seq(%ebx), %eax +	andl	total_seq+4(%ebx), %eax +	cmpl	$0xffffffff, %eax +	jne	25f +	movl	cond_nwaiters(%ebx), %eax +	andl	$~((1 << clock_bits) - 1), %eax +	jne	25f + +	addl	$cond_nwaiters, %ebx +	movl	$SYS_futex, %eax +	movl	$FUTEX_WAKE, %ecx +	movl	$1, %edx +	ENTER_KERNEL +	subl	$cond_nwaiters, %ebx + +25:	LOCK +#if cond_lock == 0 +	subl	$1, (%ebx) +#else +	subl	$1, cond_lock(%ebx) +#endif +	jne	10f + +	/* Remove cancellation handler.  */ +11:	movl	24+FRAME_SIZE(%esp), %eax +	call	__pthread_mutex_cond_lock +	addl	$FRAME_SIZE, %esp +.Laddl: + +	/* We return the result of the mutex_lock operation if it failed.  */ +	testl	%eax, %eax +#ifdef HAVE_CMOV +	cmovel	%esi, %eax +#else +	jne	22f +	movl	%esi, %eax +22: +#endif + +18:	popl	%ebx +.Lpop_ebx: +	popl	%esi +.Lpop_esi: +	popl	%edi +.Lpop_edi: +	popl	%ebp +.Lpop_ebp: + +	ret + +	/* Initial locking failed.  */ +1: +.LSbl1: +#if cond_lock == 0 +	movl	%ebx, %ecx +#else +	leal	cond_lock(%ebx), %ecx +#endif +	call	__lll_mutex_lock_wait +	jmp	2b + +	/* Unlock in loop requires wakeup.  */ +3: +.LSbl2: +#if cond_lock == 0 +	movl	%ebx, %eax +#else +	leal	cond_lock(%ebx), %eax +#endif +	call	__lll_mutex_unlock_wake +	jmp	4b + +	/* Locking in loop failed.  */ +5: +#if cond_lock == 0 +	movl	%ebx, %ecx +#else +	leal	cond_lock(%ebx), %ecx +#endif +	call	__lll_mutex_lock_wait +	jmp	6b + +	/* Unlock after loop requires wakeup.  */ +10: +#if cond_lock == 0 +	movl	%ebx, %eax +#else +	leal	cond_lock(%ebx), %eax +#endif +	call	__lll_mutex_unlock_wake +	jmp	11b + +	/* The initial unlocking of the mutex failed.  */ +16: +.LSbl3: +	LOCK +#if cond_lock == 0 +	subl	$1, (%ebx) +#else +	subl	$1, cond_lock(%ebx) +#endif +	jne	18b + +	movl	%eax, %esi +#if cond_lock == 0 +	movl	%ebx, %eax +#else +	leal	cond_lock(%ebx), %eax +#endif +	call	__lll_mutex_unlock_wake + +	movl	%esi, %eax +	jmp	18b + +#if defined __NR_clock_gettime && !defined __ASSUME_POSIX_TIMERS +	/* clock_gettime not available.  */ +.LSbl4: +19:	leal	4(%esp), %ebx +	xorl	%ecx, %ecx +	movl	$SYS_gettimeofday, %eax +	ENTER_KERNEL +	movl	%edx, %ebx + +	/* Compute relative timeout.  */ +	movl	8(%esp), %eax +	movl	$1000, %edx +	mul	%edx		/* Milli seconds to nano seconds.  */ +	movl	(%ebp), %ecx +	movl	4(%ebp), %edx +	subl	4(%esp), %ecx +	subl	%eax, %edx +	jns	20f +	addl	$1000000000, %edx +	subl	$1, %ecx +20:	testl	%ecx, %ecx +	movl	$-ETIMEDOUT, %esi +	js	6b +	jmp	21b +#endif +	.size	__pthread_cond_timedwait, .-__pthread_cond_timedwait +weak_alias(__pthread_cond_timedwait, pthread_cond_timedwait) + + +	.type	__condvar_tw_cleanup2, @function +__condvar_tw_cleanup2: +	subl	$cond_futex, %ebx +.LSbl5: +	.size	__condvar_tw_cleanup2, .-__condvar_tw_cleanup2 +	.type	__condvar_tw_cleanup, @function +__condvar_tw_cleanup: +	movl	%eax, %esi + +	/* Get internal lock.  */ +	movl	$1, %edx +	xorl	%eax, %eax +	LOCK +#if cond_lock == 0 +	cmpxchgl %edx, (%ebx) +#else +	cmpxchgl %edx, cond_lock(%ebx) +#endif +	jz	1f + +#if cond_lock == 0 +	movl	%ebx, %ecx +#else +	leal	cond_lock(%ebx), %ecx +#endif +	call	__lll_mutex_lock_wait + +1:	movl	broadcast_seq(%ebx), %eax +	cmpl	20(%esp), %eax +	jne	3f + +	addl	$1, wakeup_seq(%ebx) +	adcl	$0, wakeup_seq+4(%ebx) + +	addl	$1, cond_futex(%ebx) + +	addl	$1, woken_seq(%ebx) +	adcl	$0, woken_seq+4(%ebx) + +3:	subl	$(1 << clock_bits), cond_nwaiters(%ebx) + +	/* Wake up a thread which wants to destroy the condvar object.  */ +	xorl	%edi, %edi +	movl	total_seq(%ebx), %eax +	andl	total_seq+4(%ebx), %eax +	cmpl	$0xffffffff, %eax +	jne	4f +	movl	cond_nwaiters(%ebx), %eax +	andl	$~((1 << clock_bits) - 1), %eax +	jne	4f + +	addl	$cond_nwaiters, %ebx +	movl	$SYS_futex, %eax +	movl	$FUTEX_WAKE, %ecx +	movl	$1, %edx +	ENTER_KERNEL +	subl	$cond_nwaiters, %ebx +	movl	$1, %edi + +4:	LOCK +#if cond_lock == 0 +	subl	$1, (%ebx) +#else +	subl	$1, cond_lock(%ebx) +#endif +	je	2f + +#if cond_lock == 0 +	movl	%ebx, %eax +#else +	leal	cond_lock(%ebx), %eax +#endif +	call	__lll_mutex_unlock_wake + +	/* Wake up all waiters to make sure no signal gets lost.  */ +2:	testl	%edi, %edi +	jnz	5f +	addl	$cond_futex, %ebx +	movl	$FUTEX_WAKE, %ecx +	movl	$SYS_futex, %eax +	movl	$0x7fffffff, %edx +	ENTER_KERNEL + +5:	movl	24+FRAME_SIZE(%esp), %eax +	call	__pthread_mutex_cond_lock + +	movl	%esi, (%esp) +.LcallUR: +	call	_Unwind_Resume +	hlt +.LENDCODE: +	.size	__condvar_tw_cleanup, .-__condvar_tw_cleanup diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S new file mode 100644 index 000000000..377a7340f --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S @@ -0,0 +1,357 @@ +/* Copyright (C) 2002, 2003, 2004 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> +#include <lowlevelcond.h> +#include <tcb-offsets.h> + +#ifdef UP +# define LOCK +#else +# define LOCK lock +#endif + +#define FUTEX_WAIT		0 +#define FUTEX_WAKE		1 + + +	.text + +/* int pthread_cond_wait (pthread_cond_t *cond, pthread_mutex_t *mutex)  */ +	.globl	__pthread_cond_wait +	.type	__pthread_cond_wait, @function +	.align	16 +__pthread_cond_wait: +.LSTARTCODE: + +	pushl	%edi +.Lpush_edi: +	pushl	%esi +.Lpush_esi: +	pushl	%ebx +.Lpush_ebx: + +	xorl	%esi, %esi +	movl	16(%esp), %ebx + +	/* Get internal lock.  */ +	movl	$1, %edx +	xorl	%eax, %eax +	LOCK +#if cond_lock == 0 +	cmpxchgl %edx, (%ebx) +#else +	cmpxchgl %edx, cond_lock(%ebx) +#endif +	jnz	1f + +	/* Store the reference to the mutex.  If there is already a +	   different value in there this is a bad user bug.  */ +2:	cmpl	$-1, dep_mutex(%ebx) +	movl	20(%esp), %eax +	je	15f +	movl	%eax, dep_mutex(%ebx) + +	/* Unlock the mutex.  */ +15:	xorl	%edx, %edx +	call	__pthread_mutex_unlock_usercnt + +	testl	%eax, %eax +	jne	12f + +	addl	$1, total_seq(%ebx) +	adcl	$0, total_seq+4(%ebx) +	addl	$1, cond_futex(%ebx) +	addl	$(1 << clock_bits), cond_nwaiters(%ebx) + +#define FRAME_SIZE 16 +	subl	$FRAME_SIZE, %esp +.Lsubl: + +	/* Get and store current wakeup_seq value.  */ +	movl	wakeup_seq(%ebx), %edi +	movl	wakeup_seq+4(%ebx), %edx +	movl	broadcast_seq(%ebx), %eax +	movl	%edi, 4(%esp) +	movl	%edx, 8(%esp) +	movl	%eax, 12(%esp) + +8:	movl	cond_futex(%ebx), %edi + +	/* Unlock.  */ +	LOCK +#if cond_lock == 0 +	subl	$1, (%ebx) +#else +	subl	$1, cond_lock(%ebx) +#endif +	jne	3f + +.LcleanupSTART: +4:	call	__pthread_enable_asynccancel +	movl	%eax, (%esp) + +	movl	%esi, %ecx	/* movl $FUTEX_WAIT, %ecx */ +	movl	%edi, %edx +	addl	$cond_futex, %ebx +.Ladd_cond_futex: +	movl	$SYS_futex, %eax +	ENTER_KERNEL +	subl	$cond_futex, %ebx +.Lsub_cond_futex: + +	movl	(%esp), %eax +	call	__pthread_disable_asynccancel +.LcleanupEND: + +	/* Lock.  */ +	movl	$1, %edx +	xorl	%eax, %eax +	LOCK +#if cond_lock == 0 +	cmpxchgl %edx, (%ebx) +#else +	cmpxchgl %edx, cond_lock(%ebx) +#endif +	jnz	5f + +6:	movl	broadcast_seq(%ebx), %eax +	cmpl	12(%esp), %eax +	jne	16f + +	movl	woken_seq(%ebx), %eax +	movl	woken_seq+4(%ebx), %ecx + +	movl	wakeup_seq(%ebx), %edi +	movl	wakeup_seq+4(%ebx), %edx + +	cmpl	8(%esp), %edx +	jne	7f +	cmpl	4(%esp), %edi +	je	8b + +7:	cmpl	%ecx, %edx +	jne	9f +	cmp	%eax, %edi +	je	8b + +9:	addl	$1, woken_seq(%ebx) +	adcl	$0, woken_seq+4(%ebx) + +	/* Unlock */ +16:	subl	$(1 << clock_bits), cond_nwaiters(%ebx) + +	/* Wake up a thread which wants to destroy the condvar object.  */ +	movl	total_seq(%ebx), %eax +	andl	total_seq+4(%ebx), %eax +	cmpl	$0xffffffff, %eax +	jne	17f +	movl	cond_nwaiters(%ebx), %eax +	andl	$~((1 << clock_bits) - 1), %eax +	jne	17f + +	addl	$cond_nwaiters, %ebx +	movl	$SYS_futex, %eax +	movl	$FUTEX_WAKE, %ecx +	movl	$1, %edx +	ENTER_KERNEL +	subl	$cond_nwaiters, %ebx + +17:	LOCK +#if cond_lock == 0 +	subl	$1, (%ebx) +#else +	subl	$1, cond_lock(%ebx) +#endif +	jne	10f + +11:	movl	20+FRAME_SIZE(%esp), %eax +	call	__pthread_mutex_cond_lock +	addl	$FRAME_SIZE, %esp +.Laddl: + +14:	popl	%ebx +.Lpop_ebx: +	popl	%esi +.Lpop_esi: +	popl	%edi +.Lpop_edi: + +	/* We return the result of the mutex_lock operation.  */ +	ret + +	/* Initial locking failed.  */ +1: +.LSbl1: +#if cond_lock == 0 +	movl	%ebx, %ecx +#else +	leal	cond_lock(%ebx), %ecx +#endif +	call	__lll_mutex_lock_wait +	jmp	2b + +	/* Unlock in loop requires waekup.  */ +3: +.LSbl2: +#if cond_lock == 0 +	movl	%ebx, %eax +#else +	leal	cond_lock(%ebx), %eax +#endif +	call	__lll_mutex_unlock_wake +	jmp	4b + +	/* Locking in loop failed.  */ +5: +#if cond_lock == 0 +	movl	%ebx, %ecx +#else +	leal	cond_lock(%ebx), %ecx +#endif +	call	__lll_mutex_lock_wait +	jmp	6b + +	/* Unlock after loop requires wakeup.  */ +10: +#if cond_lock == 0 +	movl	%ebx, %eax +#else +	leal	cond_lock(%ebx), %eax +#endif +	call	__lll_mutex_unlock_wake +	jmp	11b + +	/* The initial unlocking of the mutex failed.  */ +12: +.LSbl3: +	LOCK +#if cond_lock == 0 +	subl	$1, (%ebx) +#else +	subl	$1, cond_lock(%ebx) +#endif +	jne	14b + +	movl	%eax, %esi +#if cond_lock == 0 +	movl	%ebx, %eax +#else +	leal	cond_lock(%ebx), %eax +#endif +	call	__lll_mutex_unlock_wake + +	movl	%esi, %eax +	jmp	14b +	.size	__pthread_cond_wait, .-__pthread_cond_wait +weak_alias(__pthread_cond_wait, pthread_cond_wait) + + +	.type	__condvar_w_cleanup2, @function +__condvar_w_cleanup2: +	subl	$cond_futex, %ebx +	.size	__condvar_w_cleanup2, .-__condvar_w_cleanup2 +.LSbl4: +	.type	__condvar_w_cleanup, @function +__condvar_w_cleanup: +	movl	%eax, %esi + +	/* Get internal lock.  */ +	movl	$1, %edx +	xorl	%eax, %eax +	LOCK +#if cond_lock == 0 +	cmpxchgl %edx, (%ebx) +#else +	cmpxchgl %edx, cond_lock(%ebx) +#endif +	jz	1f + +#if cond_lock == 0 +	movl	%ebx, %ecx +#else +	leal	cond_lock(%ebx), %ecx +#endif +	call	__lll_mutex_lock_wait + +1:	movl	broadcast_seq(%ebx), %eax +	cmpl	12(%esp), %eax +	jne	3f + +	addl	$1, wakeup_seq(%ebx) +	adcl	$0, wakeup_seq+4(%ebx) + +	addl	$1, cond_futex(%ebx) + +	addl	$1, woken_seq(%ebx) +	adcl	$0, woken_seq+4(%ebx) + +3:	subl	$(1 << clock_bits), cond_nwaiters(%ebx) + +	/* Wake up a thread which wants to destroy the condvar object.  */ +	xorl	%edi, %edi +	movl	total_seq(%ebx), %eax +	andl	total_seq+4(%ebx), %eax +	cmpl	$0xffffffff, %eax +	jne	4f +	movl	cond_nwaiters(%ebx), %eax +	andl	$~((1 << clock_bits) - 1), %eax +	jne	4f + +	addl	$cond_nwaiters, %ebx +	movl	$SYS_futex, %eax +	movl	$FUTEX_WAKE, %ecx +	movl	$1, %edx +	ENTER_KERNEL +	subl	$cond_nwaiters, %ebx +	movl	$1, %edi + +4:	LOCK +#if cond_lock == 0 +	subl	$1, (%ebx) +#else +	subl	$1, cond_lock(%ebx) +#endif +	je	2f + +#if cond_lock == 0 +	movl	%ebx, %eax +#else +	leal	cond_lock(%ebx), %eax +#endif +	call	__lll_mutex_unlock_wake + +	/* Wake up all waiters to make sure no signal gets lost.  */ +2:	testl	%edi, %edi +	jnz	5f +	addl	$cond_futex, %ebx +	movl	$FUTEX_WAKE, %ecx +	movl	$SYS_futex, %eax +	movl	$0x7fffffff, %edx +	ENTER_KERNEL + +5:	movl	20+FRAME_SIZE(%esp), %eax +	call	__pthread_mutex_cond_lock + +	movl	%esi, (%esp) +.LcallUR: +	call	_Unwind_Resume +	hlt +.LENDCODE: +	.size	__condvar_w_cleanup, .-__condvar_w_cleanup diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_rdlock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_rdlock.S new file mode 100644 index 000000000..aec79f07e --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_rdlock.S @@ -0,0 +1,175 @@ +/* Copyright (C) 2002, 2003 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> +#include <lowlevelrwlock.h> +#include <pthread-errnos.h> +#include <tcb-offsets.h> + + +#define FUTEX_WAIT		0 +#define FUTEX_WAKE		1 + +#ifndef UP +# define LOCK lock +#else +# define LOCK +#endif + + +	.text + +	.globl	__pthread_rwlock_rdlock +	.type	__pthread_rwlock_rdlock,@function +	.align	16 +__pthread_rwlock_rdlock: +	pushl	%esi +	pushl	%ebx + +	xorl	%esi, %esi +	movl	12(%esp), %ebx + +	/* Get the lock.  */ +	movl	$1, %edx +	xorl	%eax, %eax +	LOCK +#if MUTEX == 0 +	cmpxchgl %edx, (%ebx) +#else +	cmpxchgl %edx, MUTEX(%ebx) +#endif +	jnz	1f + +2:	movl	WRITER(%ebx), %eax +	testl	%eax, %eax +	jne	14f +	cmpl	$0, WRITERS_QUEUED(%ebx) +	je	5f +	cmpl	$0, FLAGS(%ebx) +	je	5f + +3:	addl	$1, READERS_QUEUED(%ebx) +	je	4f + +	movl	READERS_WAKEUP(%ebx), %edx + +	LOCK +#if MUTEX == 0 +	subl	$1, (%ebx) +#else +	subl	$1, MUTEX(%ebx) +#endif +	jne	10f + +11:	addl	$READERS_WAKEUP, %ebx +	movl	%esi, %ecx	/* movl $FUTEX_WAIT, %ecx */ +	movl	$SYS_futex, %eax +	ENTER_KERNEL + +	subl	$READERS_WAKEUP, %ebx + +	/* Reget the lock.  */ +	movl	$1, %edx +	xorl	%eax, %eax +	LOCK +#if MUTEX == 0 +	cmpxchgl %edx, (%ebx) +#else +	cmpxchgl %edx, MUTEX(%ebx) +#endif +	jnz	12f + +13:	subl	$1, READERS_QUEUED(%ebx) +	jmp	2b + +5:	xorl	%ecx, %ecx +	addl	$1, NR_READERS(%ebx) +	je	8f +9:	LOCK +#if MUTEX == 0 +	subl	$1, (%ebx) +#else +	subl	$1, MUTEX(%ebx) +#endif +	jne	6f +7: + +	movl	%ecx, %eax +	popl	%ebx +	popl	%esi +	ret + +1: +#if MUTEX == 0 +	movl	%ebx, %ecx +#else +	leal	MUTEX(%ebx), %ecx +#endif +	call	__lll_mutex_lock_wait +	jmp	2b + +14:	cmpl	%gs:TID, %eax +	jne	3b +	/* Deadlock detected.  */ +	movl	$EDEADLK, %ecx +	jmp	9b + +6: +#if MUTEX == 0 +	movl	%ebx, %eax +#else +	leal	MUTEX(%ebx), %eax +#endif +	call	__lll_mutex_unlock_wake +	jmp	7b + +	/* Overflow.  */ +8:	subl	$1, NR_READERS(%ebx) +	movl	$EAGAIN, %ecx +	jmp	9b + +	/* Overflow.  */ +4:	subl	$1, READERS_QUEUED(%ebx) +	movl	$EAGAIN, %ecx +	jmp	9b + +10: +#if MUTEX == 0 +	movl	%ebx, %eax +#else +	leal	MUTEX(%ebx), %eax +#endif +	call	__lll_mutex_unlock_wake +	jmp	11b + +12: +#if MUTEX == 0 +	movl	%ebx, %ecx +#else +	leal	MUTEX(%ebx), %ecx +#endif +	call	__lll_mutex_lock_wait +	jmp	13b +	.size	__pthread_rwlock_rdlock,.-__pthread_rwlock_rdlock + +	.globl	pthread_rwlock_rdlock +pthread_rwlock_rdlock = __pthread_rwlock_rdlock + +	.globl	__pthread_rwlock_rdlock_internal +__pthread_rwlock_rdlock_internal = __pthread_rwlock_rdlock diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedrdlock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedrdlock.S new file mode 100644 index 000000000..3717d7ef5 --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedrdlock.S @@ -0,0 +1,214 @@ +/* Copyright (C) 2002, 2003 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> +#include <lowlevelrwlock.h> +#include <pthread-errnos.h> +#include <tcb-offsets.h> + + +#define FUTEX_WAIT		0 +#define FUTEX_WAKE		1 + +#ifndef UP +# define LOCK lock +#else +# define LOCK +#endif + + +	.text + +	.globl	pthread_rwlock_timedrdlock +	.type	pthread_rwlock_timedrdlock,@function +	.align	16 +pthread_rwlock_timedrdlock: +	pushl	%esi +	pushl	%edi +	pushl	%ebx +	pushl	%ebp +	subl	$8, %esp + +	movl	28(%esp), %ebp +	movl	32(%esp), %edi + +	/* Get the lock.  */ +	movl	$1, %edx +	xorl	%eax, %eax +	LOCK +#if MUTEX == 0 +	cmpxchgl %edx, (%ebp) +#else +	cmpxchgl %edx, MUTEX(%ebp) +#endif +	jnz	1f + +2:	movl	WRITER(%ebp), %eax +	testl	%eax, %eax +	jne	14f +	cmpl	$0, WRITERS_QUEUED(%ebp) +	je	5f +	cmpl	$0, FLAGS(%ebp) +	je	5f + +	/* Check the value of the timeout parameter.  */ +3:	cmpl	$1000000000, 4(%edi) +	jae	19f + +	addl	$1, READERS_QUEUED(%ebp) +	je	4f + +	movl	READERS_WAKEUP(%ebp), %esi + +	LOCK +#if MUTEX == 0 +	subl	$1, (%ebp) +#else +	subl	$1, MUTEX(%ebp) +#endif +	jne	10f + +	/* Get current time.  */ +11:	movl	%esp, %ebx +	xorl	%ecx, %ecx +	movl	$SYS_gettimeofday, %eax +	ENTER_KERNEL + +	/* 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	15f +	addl	$1000000000, %edx +	subl	$1, %ecx +15:	testl	%ecx, %ecx +	js	16f		/* Time is already up.  */ + +	/* Futex call.  */ +	movl	%ecx, (%esp)	/* Store relative timeout.  */ +	movl	%edx, 4(%esp) +	movl	%esi, %edx +	xorl	%ecx, %ecx	/* movl $FUTEX_WAIT, %ecx */ +	movl	%esp, %esi +	leal	READERS_WAKEUP(%ebp), %ebx +	movl	$SYS_futex, %eax +	ENTER_KERNEL +	movl	%eax, %ecx +17: + +	/* Reget the lock.  */ +	movl	$1, %edx +	xorl	%eax, %eax +	LOCK +#if MUTEX == 0 +	cmpxchgl %edx, (%ebp) +#else +	cmpxchgl %edx, MUTEX(%ebp) +#endif +	jnz	12f + +13:	subl	$1, READERS_QUEUED(%ebp) +	cmpl	$-ETIMEDOUT, %ecx +	jne	2b + +18:	movl	$ETIMEDOUT, %ecx +	jmp	9f + + +5:	xorl	%ecx, %ecx +	addl	$1, NR_READERS(%ebp) +	je	8f +9:	LOCK +#if MUTEX == 0 +	subl	$1, (%ebp) +#else +	subl	$1, MUTEX(%ebp) +#endif +	jne	6f + +7:	movl	%ecx, %eax + +	addl	$8, %esp +	popl	%ebp +	popl	%ebx +	popl	%edi +	popl	%esi +	ret + +1: +#if MUTEX == 0 +	movl	%ebp, %ecx +#else +	leal	MUTEX(%ebp), %ecx +#endif +	call	__lll_mutex_lock_wait +	jmp	2b + +14:	cmpl	%gs:TID, %eax +	jne	3b +	movl	$EDEADLK, %ecx +	jmp	9b + +6: +#if MUTEX == 0 +	movl	%ebp, %eax +#else +	leal	MUTEX(%ebp), %eax +#endif +	call	__lll_mutex_unlock_wake +	jmp	7b + +	/* Overflow.  */ +8:	subl	$1, NR_READERS(%ebp) +	movl	$EAGAIN, %ecx +	jmp	9b + +	/* Overflow.  */ +4:	subl	$1, READERS_QUEUED(%ebp) +	movl	$EAGAIN, %ecx +	jmp	9b + +10: +#if MUTEX == 0 +	movl	%ebp, %eax +#else +	leal	MUTEX(%ebp), %eax +#endif +	call	__lll_mutex_unlock_wake +	jmp	11b + +12: +#if MUTEX == 0 +	movl	%ebp, %ecx +#else +	leal	MUTEX(%ebp), %ecx +#endif +	call	__lll_mutex_lock_wait +	jmp	13b + +16:	movl	$-ETIMEDOUT, %ecx +	jmp	17b + +19:	movl	$EINVAL, %ecx +	jmp	9b +	.size	pthread_rwlock_timedrdlock,.-pthread_rwlock_timedrdlock diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedwrlock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedwrlock.S new file mode 100644 index 000000000..09c9e30ca --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedwrlock.S @@ -0,0 +1,207 @@ +/* Copyright (C) 2002, 2003 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> +#include <lowlevelrwlock.h> +#include <pthread-errnos.h> +#include <tcb-offsets.h> + + +#define FUTEX_WAIT		0 +#define FUTEX_WAKE		1 + +#ifndef UP +# define LOCK lock +#else +# define LOCK +#endif + + +	.text + +	.globl	pthread_rwlock_timedwrlock +	.type	pthread_rwlock_timedwrlock,@function +	.align	16 +pthread_rwlock_timedwrlock: +	pushl	%esi +	pushl	%edi +	pushl	%ebx +	pushl	%ebp +	subl	$8, %esp + +	movl	28(%esp), %ebp +	movl	32(%esp), %edi + +	/* Get the lock.  */ +	movl	$1, %edx +	xorl	%eax, %eax +	LOCK +#if MUTEX == 0 +	cmpxchgl %edx, (%ebp) +#else +	cmpxchgl %edx, MUTEX(%ebp) +#endif +	jnz	1f + +2:	movl	WRITER(%ebp), %eax +	testl	%eax, %eax +	jne	14f +	cmpl	$0, NR_READERS(%ebp) +	je	5f + +	/* Check the value of the timeout parameter.  */ +3:	cmpl	$1000000000, 4(%edi) +	jae	19f + +	addl	$1, WRITERS_QUEUED(%ebp) +	je	4f + +	movl	WRITERS_WAKEUP(%ebp), %esi + +	LOCK +#if MUTEX == 0 +	subl	$1, (%ebp) +#else +	subl	$1, MUTEX(%ebp) +#endif +	jne	10f + +	/* Get current time.  */ +11:	movl	%esp, %ebx +	xorl	%ecx, %ecx +	movl	$SYS_gettimeofday, %eax +	ENTER_KERNEL + +	/* 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	15f +	addl	$1000000000, %edx +	subl	$1, %ecx +15:	testl	%ecx, %ecx +	js	16f		/* Time is already up.  */ + +	/* Futex call.  */ +	movl	%ecx, (%esp)	/* Store relative timeout.  */ +	movl	%edx, 4(%esp) +	movl	%esi, %edx +	xorl	%ecx, %ecx	/* movl $FUTEX_WAIT, %ecx */ +	movl	%esp, %esi +	leal	WRITERS_WAKEUP(%ebp), %ebx +	movl	$SYS_futex, %eax +	ENTER_KERNEL +	movl	%eax, %ecx +17: + +	/* Reget the lock.  */ +	movl	$1, %edx +	xorl	%eax, %eax +	LOCK +#if MUTEX == 0 +	cmpxchgl %edx, (%ebp) +#else +	cmpxchgl %edx, MUTEX(%ebp) +#endif +	jnz	12f + +13:	subl	$1, WRITERS_QUEUED(%ebp) +	cmpl	$-ETIMEDOUT, %ecx +	jne	2b + +18:	movl	$ETIMEDOUT, %ecx +	jmp	9f + + +5:	xorl	%ecx, %ecx +	movl	%gs:TID, %eax +	movl	%eax, WRITER(%ebp) +9:	LOCK +#if MUTEX == 0 +	subl	$1, (%ebp) +#else +	subl	$1, MUTEX(%ebp) +#endif +	jne	6f + +7:	movl	%ecx, %eax + +	addl	$8, %esp +	popl	%ebp +	popl	%ebx +	popl	%edi +	popl	%esi +	ret + +1: +#if MUTEX == 0 +	movl	%ebp, %ecx +#else +	leal	MUTEX(%ebp), %ecx +#endif +	call	__lll_mutex_lock_wait +	jmp	2b + +14:	cmpl	%gs:TID, %eax +	jne	3b +20:	movl	$EDEADLK, %ecx +	jmp	9b + +6: +#if MUTEX == 0 +	movl	%ebp, %eax +#else +	leal	MUTEX(%ebp), %eax +#endif +	call	__lll_mutex_unlock_wake +	jmp	7b + +	/* Overflow.  */ +4:	subl	$1, WRITERS_QUEUED(%ebp) +	movl	$EAGAIN, %ecx +	jmp	9b + +10: +#if MUTEX == 0 +	movl	%ebp, %eax +#else +	leal	MUTEX(%ebp), %eax +#endif +	call	__lll_mutex_unlock_wake +	jmp	11b + +12: +#if MUTEX == 0 +	movl	%ebp, %ecx +#else +	leal	MUTEX(%ebp), %ecx +#endif +	call	__lll_mutex_lock_wait +	jmp	13b + +16:	movl	$-ETIMEDOUT, %ecx +	jmp	17b + +19:	movl	$EINVAL, %ecx +	jmp	9b +	.size	pthread_rwlock_timedwrlock,.-pthread_rwlock_timedwrlock diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_unlock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_unlock.S new file mode 100644 index 000000000..597c82fa8 --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_unlock.S @@ -0,0 +1,140 @@ +/* Copyright (C) 2002, 2003 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> +#include <lowlevelrwlock.h> + + +#define FUTEX_WAIT		0 +#define FUTEX_WAKE		1 + +#ifndef UP +# define LOCK lock +#else +# define LOCK +#endif + + +	.text + +	.globl	__pthread_rwlock_unlock +	.type	__pthread_rwlock_unlock,@function +	.align	16 +__pthread_rwlock_unlock: +	pushl	%ebx +	pushl	%edi + +	movl	12(%esp), %edi + +	/* Get the lock.  */ +	movl	$1, %edx +	xorl	%eax, %eax +	LOCK +#if MUTEX == 0 +	cmpxchgl %edx, (%edi) +#else +	cmpxchgl %edx, MUTEX(%edi) +#endif +	jnz	1f + +2:	cmpl	$0, WRITER(%edi) +	jne	5f +	subl	$1, NR_READERS(%edi) +	jnz	6f + +5:	movl	$0, WRITER(%edi) + +	movl	$1, %ecx +	leal	WRITERS_WAKEUP(%edi), %ebx +	movl	%ecx, %edx +	cmpl	$0, WRITERS_QUEUED(%edi) +	jne	0f + +	/* If also no readers waiting nothing to do.  */ +	cmpl	$0, READERS_QUEUED(%edi) +	je	6f + +	movl	$0x7fffffff, %edx +	leal	READERS_WAKEUP(%edi), %ebx + +0:	addl	$1, (%ebx) +	LOCK +#if MUTEX == 0 +	subl	$1, (%edi) +#else +	subl	$1, MUTEX(%edi) +#endif +	jne	7f + +8:	movl	$SYS_futex, %eax +	ENTER_KERNEL + +	xorl	%eax, %eax +	popl	%edi +	popl	%ebx +	ret + +	.align	16 +6:	LOCK +#if MUTEX == 0 +	subl	$1, (%edi) +#else +	subl	$1, MUTEX(%edi) +#endif +	jne	3f + +4:	xorl	%eax, %eax +	popl	%edi +	popl	%ebx +	ret + +1: +#if MUTEX == 0 +	movl	%edi, %ecx +#else +	leal	MUTEX(%edx), %ecx +#endif +	call	__lll_mutex_lock_wait +	jmp	2b + +3: +#if MUTEX == 0 +	movl	%edi, %eax +#else +	leal	MUTEX(%edx), %eax +#endif +	call	__lll_mutex_unlock_wake +	jmp	4b + +7: +#if MUTEX == 0 +	movl	%edi, %eax +#else +	leal	MUTEX(%edx), %eax +#endif +	call	__lll_mutex_unlock_wake +	jmp	8b + +	.size	__pthread_rwlock_unlock,.-__pthread_rwlock_unlock + +	.globl	pthread_rwlock_unlock +pthread_rwlock_unlock = __pthread_rwlock_unlock + +	.globl	__pthread_rwlock_unlock_internal +__pthread_rwlock_unlock_internal = __pthread_rwlock_unlock diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_wrlock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_wrlock.S new file mode 100644 index 000000000..bb384a267 --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_wrlock.S @@ -0,0 +1,165 @@ +/* Copyright (C) 2002, 2003 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> +#include <lowlevelrwlock.h> +#include <pthread-errnos.h> +#include <tcb-offsets.h> + +#define FUTEX_WAIT		0 +#define FUTEX_WAKE		1 + +#ifndef UP +# define LOCK lock +#else +# define LOCK +#endif + + +	.text + +	.globl	__pthread_rwlock_wrlock +	.type	__pthread_rwlock_wrlock,@function +	.align	16 +__pthread_rwlock_wrlock: +	pushl	%esi +	pushl	%ebx + +	xorl	%esi, %esi +	movl	12(%esp), %ebx + +	/* Get the lock.  */ +	movl	$1, %edx +	xorl	%eax, %eax +	LOCK +#if MUTEX == 0 +	cmpxchgl %edx, (%ebx) +#else +	cmpxchgl %edx, MUTEX(%ebx) +#endif +	jnz	1f + +2:	movl	WRITER(%ebx), %eax +	testl	%eax, %eax +	jne	14f +	cmpl	$0, NR_READERS(%ebx) +	je	5f + +3:	addl	$1, WRITERS_QUEUED(%ebx) +	je	4f + +	movl	WRITERS_WAKEUP(%ebx), %edx + +	LOCK +#if MUTEX == 0 +	subl	$1, (%ebx) +#else +	subl	$1, MUTEX(%ebx) +#endif +	jne	10f + +11:	addl	$WRITERS_WAKEUP, %ebx +	movl	%esi, %ecx	/* movl $FUTEX_WAIT, %ecx */ +	movl	$SYS_futex, %eax +	ENTER_KERNEL + +	subl	$WRITERS_WAKEUP, %ebx + +	/* Reget the lock.  */ +	movl	$1, %edx +	xorl	%eax, %eax +	LOCK +#if MUTEX == 0 +	cmpxchgl %edx, (%ebx) +#else +	cmpxchgl %edx, MUTEX(%ebx) +#endif +	jnz	12f + +13:	subl	$1, WRITERS_QUEUED(%ebx) +	jmp	2b + +5:	xorl	%ecx, %ecx +	movl	%gs:TID, %eax +	movl	%eax, WRITER(%ebx) +9:	LOCK +#if MUTEX == 0 +	subl	$1, (%ebx) +#else +	subl	$1, MUTEX(%ebx) +#endif +	jne	6f +7: + +	movl	%ecx, %eax +	popl	%ebx +	popl	%esi +	ret + +1: +#if MUTEX == 0 +	movl	%ebx, %ecx +#else +	leal	MUTEX(%ebx), %ecx +#endif +	call	__lll_mutex_lock_wait +	jmp	2b + +14:	cmpl	%gs:TID	, %eax +	jne	3b +	movl	$EDEADLK, %ecx +	jmp	9b + +6: +#if MUTEX == 0 +	movl	%ebx, %eax +#else +	leal	MUTEX(%ebx), %eax +#endif +	call	__lll_mutex_unlock_wake +	jmp	7b + +4:	subl	$1, WRITERS_QUEUED(%ebx) +	movl	$EAGAIN, %ecx +	jmp	9b + +10: +#if MUTEX == 0 +	movl	%ebx, %eax +#else +	leal	MUTEX(%ebx), %eax +#endif +	call	__lll_mutex_unlock_wake +	jmp	11b + +12: +#if MUTEX == 0 +	movl	%ebx, %ecx +#else +	leal	MUTEX(%ebx), %ecx +#endif +	call	__lll_mutex_lock_wait +	jmp	13b +	.size	__pthread_rwlock_wrlock,.-__pthread_rwlock_wrlock + +	.globl	pthread_rwlock_wrlock +pthread_rwlock_wrlock = __pthread_rwlock_wrlock + +	.globl	__pthread_rwlock_wrlock_internal +__pthread_rwlock_wrlock_internal = __pthread_rwlock_wrlock diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_post.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_post.S new file mode 100644 index 000000000..a0dc39c8f --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_post.S @@ -0,0 +1,96 @@ +/* Copyright (C) 2002, 2003, 2005 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> +#include <pthread-errnos.h> +#include <tls.h> + +#ifndef UP +# define LOCK lock +#else +# define +#endif + +#define FUTEX_WAKE		1 + + +	.text + +	.globl	__new_sem_post +	.type	__new_sem_post,@function +	.align	16 +__new_sem_post: +	pushl	%ebx + +	movl	8(%esp), %ebx +	movl	$1, %edx +	LOCK +	xaddl	%edx, (%ebx) + +	movl	$SYS_futex, %eax +	movl	$FUTEX_WAKE, %ecx +	addl	$1, %edx +	ENTER_KERNEL + +	testl	%eax, %eax +	js	1f + +	xorl	%eax, %eax +	popl	%ebx +	ret + +1: +#ifdef __PIC__ +	call	__x86.get_pc_thunk.bx +#else +	movl	$4f, %ebx +4: +#endif +	addl	$_GLOBAL_OFFSET_TABLE_, %ebx +#if USE___THREAD +# ifdef NO_TLS_DIRECT_SEG_REFS +	movl	errno@gotntpoff(%ebx), %edx +	addl	%gs:0, %edx +	movl	$EINVAL, (%edx) +# else +	movl	errno@gotntpoff(%ebx), %edx +	movl	$EINVAL, %gs:(%edx) +# endif +#else +	call	__errno_location@plt +	movl	$EINVAL, (%eax) +#endif + +	orl	$-1, %eax +	popl	%ebx +	ret +	.size	__new_sem_post,.-__new_sem_post +weak_alias(__new_sem_post, sem_post) + + +#ifdef __PIC__ +	.section .gnu.linkonce.t.__x86.get_pc_thunk.bx,"ax",@progbits +	.globl	__x86.get_pc_thunk.bx +	.hidden	__x86.get_pc_thunk.bx +	.type	__x86.get_pc_thunk.bx,@function +__x86.get_pc_thunk.bx: +	movl (%esp), %ebx; +	ret +	.size	__x86.get_pc_thunk.bx,.-__x86.get_pc_thunk.bx +#endif diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_timedwait.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_timedwait.S new file mode 100644 index 000000000..972b49fac --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_timedwait.S @@ -0,0 +1,193 @@ +/* Copyright (C) 2002, 2003, 2004, 2005 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> +#include <pthread-errnos.h> +#include <tcb-offsets.h> + +#ifndef UP +# define LOCK lock +#else +# define +#endif + +#define FUTEX_WAKE		1 + + +	.text + +	.globl	sem_timedwait +	.type	sem_timedwait,@function +	.align	16 +	cfi_startproc +sem_timedwait: +	/* First check for cancellation.  */ +	movl	%gs:CANCELHANDLING, %eax +	andl	$0xfffffff9, %eax +	cmpl	$8, %eax +	je	10f + +	movl	4(%esp), %ecx + +	movl	(%ecx), %eax +2:	testl	%eax, %eax +	je,pn	1f + +	leal	-1(%eax), %edx +	LOCK +	cmpxchgl %edx, (%ecx) +	jne,pn	2b + +	xorl	%eax, %eax +	ret + +	/* Check whether the timeout value is valid.  */ +1:	pushl	%esi +	cfi_adjust_cfa_offset(4) +	pushl	%edi +	cfi_adjust_cfa_offset(4) +	pushl	%ebx +	cfi_adjust_cfa_offset(4) +	subl	$12, %esp +	cfi_adjust_cfa_offset(12) + +	movl	32(%esp), %edi +	cfi_offset(7, -12)		/* %edi */ + +	/* Check for invalid nanosecond field.  */ +	cmpl	$1000000000, 4(%edi) +	movl	$EINVAL, %esi +	cfi_offset(6, -8)		/* %esi */ +	jae	6f + +	cfi_offset(3, -16)		/* %ebx */ +7:	call	__pthread_enable_asynccancel +	movl	%eax, 8(%esp) + +	xorl	%ecx, %ecx +	movl	%esp, %ebx +	movl	%ecx, %edx +	movl	$SYS_gettimeofday, %eax +	ENTER_KERNEL + +	/* 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	5f +	addl	$1000000000, %edx +	subl	$1, %ecx +5:	testl	%ecx, %ecx +	movl	$ETIMEDOUT, %esi +	js	6f		/* Time is already up.  */ + +	movl	%ecx, (%esp)	/* Store relative timeout.  */ +	movl	%edx, 4(%esp) +	movl	28(%esp), %ebx +	xorl	%ecx, %ecx +	movl	%esp, %esi +	movl	$SYS_futex, %eax +	xorl	%edx, %edx +	ENTER_KERNEL +	movl	%eax, %esi + +	movl	8(%esp), %eax +	call	__pthread_disable_asynccancel + +	testl	%esi, %esi +	je,pt	9f +	cmpl	$-EWOULDBLOCK, %esi +	jne	3f + +9:	movl	(%ebx), %eax +8:	testl	%eax, %eax +	je	7b + +	leal	-1(%eax), %ecx +	LOCK +	cmpxchgl %ecx, (%ebx) +	jne,pn	8b + +	addl	$12, %esp +	cfi_adjust_cfa_offset(-12) +	xorl	%eax, %eax +	popl	%ebx +	cfi_adjust_cfa_offset(-4) +	cfi_restore(3) +	popl	%edi +	cfi_adjust_cfa_offset(-4) +	cfi_restore(7) +	popl	%esi +	cfi_adjust_cfa_offset(-4) +	cfi_restore(6) +	ret + +	cfi_adjust_cfa_offset(24) +	cfi_offset(6, -8)		/* %esi */ +	cfi_offset(7, -12)	 	/* %edi */ +	cfi_offset(3, -16)		/* %ebx */ +3:	negl	%esi +6: +#ifdef __PIC__ +	call	__x86.get_pc_thunk.bx +#else +	movl	$4f, %ebx +4: +#endif +	addl	$_GLOBAL_OFFSET_TABLE_, %ebx +#if USE___THREAD +# ifdef NO_TLS_DIRECT_SEG_REFS +	movl	errno@gotntpoff(%ebx), %edx +	addl	%gs:0, %edx +	movl	%esi, (%edx) +# else +	movl	errno@gotntpoff(%ebx), %edx +	movl	%esi, %gs:(%edx) +# endif +#else +	call	__errno_location@plt +	movl	%esi, (%eax) +#endif + +	addl	$12, %esp +	cfi_adjust_cfa_offset(-12) +	orl	$-1, %eax +	popl	%ebx +	cfi_adjust_cfa_offset(-4) +	cfi_restore(3) +	popl	%edi +	cfi_adjust_cfa_offset(-4) +	cfi_restore(7) +	popl	%esi +	cfi_adjust_cfa_offset(-4) +	cfi_restore(6) +	ret + +10:	/* Canceled.  */ +	movl	$0xffffffff, %gs:RESULT +	LOCK +	orl	$0x10, %gs:CANCELHANDLING +	movl	%gs:CLEANUP_JMP_BUF, %eax +	jmp	HIDDEN_JUMPTARGET (__pthread_unwind) +	cfi_endproc +	.size	sem_timedwait,.-sem_timedwait diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_trywait.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_trywait.S new file mode 100644 index 000000000..7db64820f --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_trywait.S @@ -0,0 +1,85 @@ +/* Copyright (C) 2002, 2003, 2005 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> +#include <pthread-errnos.h> +#include <tls.h> + +#ifndef UP +# define LOCK lock +#else +# define +#endif + +	.text + +	.globl	__new_sem_trywait +	.type	__new_sem_trywait,@function +	.align	16 +__new_sem_trywait: +	movl	4(%esp), %ecx + +	movl	(%ecx), %eax +2:	testl	%eax, %eax +	jz	1f + +	leal	-1(%eax), %edx +	LOCK +	cmpxchgl %edx, (%ecx) +	jne,pn	2b +	xorl	%eax, %eax +	ret + +1: +#ifdef __PIC__ +	call	__x86.get_pc_thunk.cx +#else +	movl	$3f, %ecx +3: +#endif +	addl	$_GLOBAL_OFFSET_TABLE_, %ecx +#if USE___THREAD +# ifdef NO_TLS_DIRECT_SEG_REFS +	movl	errno@gotntpoff(%ecx), %edx +	addl	%gs:0, %edx +	movl	$EAGAIN, (%edx) +# else +	movl	errno@gotntpoff(%ecx), %edx +	movl	$EAGAIN, %gs:(%edx) +# endif +#else +	call	__errno_location@plt +	movl	$EAGAIN, (%eax) +#endif +	orl	$-1, %eax +	ret +	.size	__new_sem_trywait,.-__new_sem_trywait +weak_alias(__new_sem_trywait, sem_trywait) + + +#ifdef __PIC__ +	.section .gnu.linkonce.t.__x86.get_pc_thunk.cx,"ax",@progbits +	.globl	__x86.get_pc_thunk.cx +	.hidden	__x86.get_pc_thunk.cx +	.type	__x86.get_pc_thunk.cx,@function +__x86.get_pc_thunk.cx: +	movl (%esp), %ecx; +	ret +	.size	__x86.get_pc_thunk.cx,.-__x86.get_pc_thunk.cx +#endif diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_wait.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_wait.S new file mode 100644 index 000000000..c3e6cbce6 --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_wait.S @@ -0,0 +1,134 @@ +/* Copyright (C) 2002, 2003, 2005 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> +#include <pthread-errnos.h> +#include <tcb-offsets.h> +#include <tls.h> + +#ifndef UP +# define LOCK lock +#else +# define +#endif + +#define FUTEX_WAKE		1 + + +	.text + +	.globl	__new_sem_wait +	.type	__new_sem_wait,@function +	.align	16 +	cfi_startproc +__new_sem_wait: +	/* First check for cancellation.  */ +	movl	%gs:CANCELHANDLING, %eax +	andl	$0xfffffff9, %eax +	cmpl	$8, %eax +	je	5f + +	pushl	%ebx +	cfi_adjust_cfa_offset(4) +	pushl	%esi +	cfi_adjust_cfa_offset(4) +	subl	$4, %esp +	cfi_adjust_cfa_offset(4) + +	movl	16(%esp), %ebx +	cfi_offset(3, -8)		/* %ebx */ + +	cfi_offset(6, -12)		/* %esi */ +3:	movl	(%ebx), %eax +2:	testl	%eax, %eax +	je,pn	1f + +	leal	-1(%eax), %edx +	LOCK +	cmpxchgl %edx, (%ebx) +	jne,pn	2b +	xorl	%eax, %eax + +	movl	4(%esp), %esi +	cfi_restore(6) +	movl	8(%esp), %ebx +	cfi_restore(3) +	addl	$12, %esp +	cfi_adjust_cfa_offset(-12) +	ret + +	cfi_adjust_cfa_offset(8) +	cfi_offset(3, -8)		/* %ebx */ +	cfi_offset(6, -12)		/* %esi */ +1:	call	__pthread_enable_asynccancel +	movl	%eax, (%esp) + +	xorl	%esi, %esi +	movl	$SYS_futex, %eax +	movl	%esi, %ecx +	movl	%esi, %edx +	ENTER_KERNEL +	movl	%eax, %esi + +	movl	(%esp), %eax +	call	__pthread_disable_asynccancel + +	testl	%esi, %esi +	je	3b +	cmpl	$-EWOULDBLOCK, %esi +	je	3b +	negl	%esi +#ifdef __PIC__ +	call	__x86.get_pc_thunk.bx +#else +	movl	$4f, %ebx +4: +#endif +	addl	$_GLOBAL_OFFSET_TABLE_, %ebx +#if USE___THREAD +# ifdef NO_TLS_DIRECT_SEG_REFS +	movl	errno@gotntpoff(%ebx), %edx +	addl	%gs:0, %edx +	movl	%esi, (%edx) +# else +	movl	errno@gotntpoff(%ebx), %edx +	movl	%esi, %gs:(%edx) +# endif +#else +	call	__errno_location@plt +	movl	%esi, (%eax) +#endif +	orl	$-1, %eax +	movl	4(%esp), %esi +	cfi_restore(6) +	movl	8(%esp), %ebx +	cfi_restore(3) +	addl	$12, %esp +	cfi_adjust_cfa_offset(-12) +	ret + +5:	/* Canceled.  */ +	movl	$0xffffffff, %gs:RESULT +	LOCK +	orl	$0x10, %gs:CANCELHANDLING +	movl	%gs:CLEANUP_JMP_BUF, %eax +	jmp	HIDDEN_JUMPTARGET (__pthread_unwind) +	cfi_endproc +	.size	__new_sem_wait,.-__new_sem_wait +weak_alias(__new_sem_wait, sem_wait) diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/libc-lowlevellock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/libc-lowlevellock.S new file mode 100644 index 000000000..f567c1d6d --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/libc-lowlevellock.S @@ -0,0 +1 @@ +#include "../i486/libc-lowlevellock.S" diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/lowlevellock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/lowlevellock.S new file mode 100644 index 000000000..e60dea89e --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/lowlevellock.S @@ -0,0 +1,20 @@ +/* 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 "../i486/lowlevellock.S" diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_barrier_wait.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_barrier_wait.S new file mode 100644 index 000000000..6d20b9a95 --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_barrier_wait.S @@ -0,0 +1,20 @@ +/* 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 "../i486/pthread_barrier_wait.S" diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_cond_broadcast.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_cond_broadcast.S new file mode 100644 index 000000000..5e1024eab --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_cond_broadcast.S @@ -0,0 +1,20 @@ +/* Copyright (C) 2003 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Ulrich Drepper <drepper@redhat.com>, 2003. + +   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 "../i486/pthread_cond_broadcast.S" diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_cond_signal.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_cond_signal.S new file mode 100644 index 000000000..da4e8cbab --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_cond_signal.S @@ -0,0 +1,20 @@ +/* Copyright (C) 2003 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Ulrich Drepper <drepper@redhat.com>, 2003. + +   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 "../i486/pthread_cond_signal.S" diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_cond_timedwait.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_cond_timedwait.S new file mode 100644 index 000000000..c0131555b --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_cond_timedwait.S @@ -0,0 +1,20 @@ +/* Copyright (C) 2003 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Ulrich Drepper <drepper@redhat.com>, 2003. + +   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 "../i486/pthread_cond_timedwait.S" diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_cond_wait.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_cond_wait.S new file mode 100644 index 000000000..9b57fbaca --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_cond_wait.S @@ -0,0 +1,20 @@ +/* Copyright (C) 2003 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Ulrich Drepper <drepper@redhat.com>, 2003. + +   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 "../i486/pthread_cond_wait.S" diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_rwlock_rdlock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_rwlock_rdlock.S new file mode 100644 index 000000000..da2bc4704 --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_rwlock_rdlock.S @@ -0,0 +1,20 @@ +/* Copyright (C) 2003 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Ulrich Drepper <drepper@redhat.com>, 2003. + +   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 "../i486/pthread_rwlock_rdlock.S" diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_rwlock_timedrdlock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_rwlock_timedrdlock.S new file mode 100644 index 000000000..0f2ec168b --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_rwlock_timedrdlock.S @@ -0,0 +1,20 @@ +/* Copyright (C) 2003 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Ulrich Drepper <drepper@redhat.com>, 2003. + +   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 "../i486/pthread_rwlock_timedrdlock.S" diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_rwlock_timedwrlock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_rwlock_timedwrlock.S new file mode 100644 index 000000000..26501590a --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_rwlock_timedwrlock.S @@ -0,0 +1,20 @@ +/* Copyright (C) 2003 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Ulrich Drepper <drepper@redhat.com>, 2003. + +   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 "../i486/pthread_rwlock_timedwrlock.S" diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_rwlock_unlock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_rwlock_unlock.S new file mode 100644 index 000000000..5515e4895 --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_rwlock_unlock.S @@ -0,0 +1,20 @@ +/* Copyright (C) 2003 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Ulrich Drepper <drepper@redhat.com>, 2003. + +   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 "../i486/pthread_rwlock_unlock.S" diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_rwlock_wrlock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_rwlock_wrlock.S new file mode 100644 index 000000000..04ac275f6 --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/pthread_rwlock_wrlock.S @@ -0,0 +1,20 @@ +/* Copyright (C) 2003 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Ulrich Drepper <drepper@redhat.com>, 2003. + +   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 "../i486/pthread_rwlock_wrlock.S" diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/sem_post.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/sem_post.S new file mode 100644 index 000000000..7317e1582 --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/sem_post.S @@ -0,0 +1,20 @@ +/* Copyright (C) 2003 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Ulrich Drepper <drepper@redhat.com>, 2003. + +   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 "../i486/sem_post.S" diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/sem_timedwait.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/sem_timedwait.S new file mode 100644 index 000000000..f34539d56 --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/sem_timedwait.S @@ -0,0 +1,20 @@ +/* Copyright (C) 2003 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Ulrich Drepper <drepper@redhat.com>, 2003. + +   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 "../i486/sem_timedwait.S" diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/sem_trywait.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/sem_trywait.S new file mode 100644 index 000000000..64145c2e3 --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/sem_trywait.S @@ -0,0 +1,20 @@ +/* Copyright (C) 2003 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Ulrich Drepper <drepper@redhat.com>, 2003. + +   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 "../i486/sem_trywait.S" diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/sem_wait.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/sem_wait.S new file mode 100644 index 000000000..b3d462125 --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i586/sem_wait.S @@ -0,0 +1,20 @@ +/* Copyright (C) 2003 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Ulrich Drepper <drepper@redhat.com>, 2003. + +   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 "../i486/sem_wait.S" diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/libc-lowlevellock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/libc-lowlevellock.S new file mode 100644 index 000000000..f567c1d6d --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/libc-lowlevellock.S @@ -0,0 +1 @@ +#include "../i486/libc-lowlevellock.S" diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/lowlevellock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/lowlevellock.S new file mode 100644 index 000000000..e60dea89e --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/lowlevellock.S @@ -0,0 +1,20 @@ +/* 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 "../i486/lowlevellock.S" diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_barrier_wait.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_barrier_wait.S new file mode 100644 index 000000000..6d20b9a95 --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_barrier_wait.S @@ -0,0 +1,20 @@ +/* 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 "../i486/pthread_barrier_wait.S" diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_cond_broadcast.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_cond_broadcast.S new file mode 100644 index 000000000..5e1024eab --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_cond_broadcast.S @@ -0,0 +1,20 @@ +/* Copyright (C) 2003 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Ulrich Drepper <drepper@redhat.com>, 2003. + +   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 "../i486/pthread_cond_broadcast.S" diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_cond_signal.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_cond_signal.S new file mode 100644 index 000000000..da4e8cbab --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_cond_signal.S @@ -0,0 +1,20 @@ +/* Copyright (C) 2003 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Ulrich Drepper <drepper@redhat.com>, 2003. + +   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 "../i486/pthread_cond_signal.S" diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_cond_timedwait.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_cond_timedwait.S new file mode 100644 index 000000000..07d481f37 --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_cond_timedwait.S @@ -0,0 +1,21 @@ +/* Copyright (C) 2003 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Ulrich Drepper <drepper@redhat.com>, 2003. + +   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.  */ + +#define HAVE_CMOV 1 +#include "../i486/pthread_cond_timedwait.S" diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_cond_wait.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_cond_wait.S new file mode 100644 index 000000000..9b57fbaca --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_cond_wait.S @@ -0,0 +1,20 @@ +/* Copyright (C) 2003 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Ulrich Drepper <drepper@redhat.com>, 2003. + +   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 "../i486/pthread_cond_wait.S" diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_rwlock_rdlock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_rwlock_rdlock.S new file mode 100644 index 000000000..da2bc4704 --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_rwlock_rdlock.S @@ -0,0 +1,20 @@ +/* Copyright (C) 2003 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Ulrich Drepper <drepper@redhat.com>, 2003. + +   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 "../i486/pthread_rwlock_rdlock.S" diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_rwlock_timedrdlock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_rwlock_timedrdlock.S new file mode 100644 index 000000000..0f2ec168b --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_rwlock_timedrdlock.S @@ -0,0 +1,20 @@ +/* Copyright (C) 2003 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Ulrich Drepper <drepper@redhat.com>, 2003. + +   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 "../i486/pthread_rwlock_timedrdlock.S" diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_rwlock_timedwrlock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_rwlock_timedwrlock.S new file mode 100644 index 000000000..26501590a --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_rwlock_timedwrlock.S @@ -0,0 +1,20 @@ +/* Copyright (C) 2003 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Ulrich Drepper <drepper@redhat.com>, 2003. + +   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 "../i486/pthread_rwlock_timedwrlock.S" diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_rwlock_unlock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_rwlock_unlock.S new file mode 100644 index 000000000..0894f0546 --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_rwlock_unlock.S @@ -0,0 +1,21 @@ +/* Copyright (C) 2003 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Ulrich Drepper <drepper@redhat.com>, 2003. + +   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.  */ + +#define HAVE_CMOV	1 +#include "../i486/pthread_rwlock_unlock.S" diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_rwlock_wrlock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_rwlock_wrlock.S new file mode 100644 index 000000000..04ac275f6 --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/pthread_rwlock_wrlock.S @@ -0,0 +1,20 @@ +/* Copyright (C) 2003 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Ulrich Drepper <drepper@redhat.com>, 2003. + +   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 "../i486/pthread_rwlock_wrlock.S" diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/sem_post.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/sem_post.S new file mode 100644 index 000000000..7317e1582 --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/sem_post.S @@ -0,0 +1,20 @@ +/* Copyright (C) 2003 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Ulrich Drepper <drepper@redhat.com>, 2003. + +   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 "../i486/sem_post.S" diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/sem_timedwait.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/sem_timedwait.S new file mode 100644 index 000000000..f34539d56 --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/sem_timedwait.S @@ -0,0 +1,20 @@ +/* Copyright (C) 2003 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Ulrich Drepper <drepper@redhat.com>, 2003. + +   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 "../i486/sem_timedwait.S" diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/sem_trywait.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/sem_trywait.S new file mode 100644 index 000000000..64145c2e3 --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/sem_trywait.S @@ -0,0 +1,20 @@ +/* Copyright (C) 2003 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Ulrich Drepper <drepper@redhat.com>, 2003. + +   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 "../i486/sem_trywait.S" diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/sem_wait.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/sem_wait.S new file mode 100644 index 000000000..b3d462125 --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i686/sem_wait.S @@ -0,0 +1,20 @@ +/* Copyright (C) 2003 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Ulrich Drepper <drepper@redhat.com>, 2003. + +   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 "../i486/sem_wait.S" diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/lowlevellock.h b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/lowlevellock.h new file mode 100644 index 000000000..97f3b09e2 --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/lowlevellock.h @@ -0,0 +1,365 @@ +/* Copyright (C) 2002, 2003, 2004 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.  */ + +#ifndef _LOWLEVELLOCK_H +#define _LOWLEVELLOCK_H	1 + +#include <time.h> +#include <sys/param.h> +#include <bits/pthreadtypes.h> +#include <atomic.h> +#include <sysdep.h> + +/* We have a separate internal lock implementation which is not tied +   to binary compatibility.  */ + +/* Type for lock object.  */ +typedef int lll_lock_t; + +/* Initializers for lock.  */ +#define LLL_LOCK_INITIALIZER		(0) +#define LLL_LOCK_INITIALIZER_LOCKED	(1) + +#include <tls.h> + +#ifndef LOCK_INSTR +# define LOCK_INSTR "lock;" +#endif + +#define FUTEX_WAIT		0 +#define FUTEX_WAKE		1 + + +/* Initializer for compatibility lock.  */ +#define LLL_MUTEX_LOCK_INITIALIZER		(0) +#define LLL_MUTEX_LOCK_INITIALIZER_LOCKED	(1) +#define LLL_MUTEX_LOCK_INITIALIZER_WAITERS	(2) + + +#ifdef __PIC__ +# define LLL_EBX_LOAD	"xchgl %2, %%ebx\n" +# define LLL_EBX_REG	"D" +#else +# define LLL_EBX_LOAD +# define LLL_EBX_REG	"b" +#endif + +#define LLL_ENTER_KERNEL	"int $0x80\n\t" + +/* Delay in spinlock loop.  */ +#define BUSY_WAIT_NOP          __asm__ ("rep; nop") + +#define lll_futex_wait(futex, val) \ +  lll_futex_timed_wait (futex, val, NULL) + +#define lll_futex_timed_wait(futex, val, timeout) \ +  ({									      \ +    int __ret;							      \ +    register __typeof (val) _val __asm__ ("edx") = (val);		      \ +    __asm__ __volatile (LLL_EBX_LOAD					      \ +		      LLL_ENTER_KERNEL					      \ +		      LLL_EBX_LOAD					      \ +		      : "=a" (__ret)					      \ +		      : "0" (SYS_futex), LLL_EBX_REG (futex), "S" (timeout),  \ +			"c" (FUTEX_WAIT), "d" (_val),			      \ +			"i" (offsetof (tcbhead_t, sysinfo)));		      \ +   __ret; }) + + +#define lll_futex_wake(futex, nr) \ +  ({									      \ +    int __ret;							      \ +    register __typeof (nr) _nr __asm__ ("edx") = (nr);			      \ +    __asm__ __volatile (LLL_EBX_LOAD					      \ +		      LLL_ENTER_KERNEL					      \ +		      LLL_EBX_LOAD					      \ +		      : "=a" (__ret)					      \ +		      : "0" (SYS_futex), LLL_EBX_REG (futex),		      \ +			"c" (FUTEX_WAKE), "d" (_nr),			      \ +			"i" (0) /* phony, to align next arg's number */,      \ +			"i" (offsetof (tcbhead_t, sysinfo)));		      \ +   __ret; }) + + +/* Does not preserve %eax and %ecx.  */ +extern int __lll_mutex_lock_wait (int val, int *__futex) +     __attribute ((regparm (2))) attribute_hidden; +/* Does not preserve %eax, %ecx, and %edx.  */ +extern int __lll_mutex_timedlock_wait (int val, int *__futex, +				       const struct timespec *abstime) +     __attribute ((regparm (3))) attribute_hidden; +/* Preserves all registers but %eax.  */ +extern int __lll_mutex_unlock_wake (int *__futex) +     __attribute ((regparm (1))) attribute_hidden; + + +/* NB: in the lll_mutex_trylock macro we simply return the value in %eax +   after the cmpxchg instruction.  In case the operation succeded this +   value is zero.  In case the operation failed, the cmpxchg instruction +   has loaded the current value of the memory work which is guaranteed +   to be nonzero.  */ +#define lll_mutex_trylock(futex) \ +  ({ int ret;								      \ +     __asm__ __volatile (LOCK_INSTR "cmpxchgl %2, %1"			      \ +		       : "=a" (ret), "=m" (futex)			      \ +		       : "r" (LLL_MUTEX_LOCK_INITIALIZER_LOCKED), "m" (futex),\ +			 "0" (LLL_MUTEX_LOCK_INITIALIZER)		      \ +		       : "memory");					      \ +     ret; }) + + +#define lll_mutex_cond_trylock(futex) \ +  ({ int ret;								      \ +     __asm__ __volatile (LOCK_INSTR "cmpxchgl %2, %1"			      \ +		       : "=a" (ret), "=m" (futex)			      \ +		       : "r" (LLL_MUTEX_LOCK_INITIALIZER_WAITERS),	      \ +			  "m" (futex), "0" (LLL_MUTEX_LOCK_INITIALIZER)	      \ +		       : "memory");					      \ +     ret; }) + + +#define lll_mutex_lock(futex) \ +  (void) ({ int ignore1, ignore2;					      \ +	    __asm__ __volatile (LOCK_INSTR "cmpxchgl %1, %2\n\t"	      \ +			      "jnz _L_mutex_lock_%=\n\t"		      \ +			      ".subsection 1\n\t"			      \ +			      ".type _L_mutex_lock_%=,@function\n"	      \ +			      "_L_mutex_lock_%=:\n\t"			      \ +			      "leal %2, %%ecx\n\t"			      \ +			      "call __lll_mutex_lock_wait\n\t"		      \ +			      "jmp 1f\n\t"				      \ +			      ".size _L_mutex_lock_%=,.-_L_mutex_lock_%=\n"   \ +			      ".previous\n"				      \ +			      "1:"					      \ +			      : "=a" (ignore1), "=c" (ignore2), "=m" (futex)  \ +			      : "0" (0), "1" (1), "m" (futex)		      \ +			      : "memory"); }) + + +/* Special version of lll_mutex_lock which causes the unlock function to +   always wakeup waiters.  */ +#define lll_mutex_cond_lock(futex) \ +  (void) ({ int ignore1, ignore2;					      \ +	    __asm__ __volatile (LOCK_INSTR "cmpxchgl %1, %2\n\t"	      \ +			      "jnz _L_mutex_cond_lock_%=\n\t"		      \ +			      ".subsection 1\n\t"			      \ +			      ".type _L_mutex_cond_lock_%=,@function\n"	      \ +			      "_L_mutex_cond_lock_%=:\n\t"		      \ +			      "leal %2, %%ecx\n\t"			      \ +			      "call __lll_mutex_lock_wait\n\t"		      \ +			      "jmp 1f\n\t"				      \ +			      ".size _L_mutex_cond_lock_%=,.-_L_mutex_cond_lock_%=\n"   \ +			      ".previous\n"				      \ +			      "1:"					      \ +			      : "=a" (ignore1), "=c" (ignore2), "=m" (futex)  \ +			      : "0" (0), "1" (2), "m" (futex)		      \ +			      : "memory"); }) + + +#define lll_mutex_timedlock(futex, timeout) \ +  ({ int _result, ignore1, ignore2;					      \ +     __asm__ __volatile (LOCK_INSTR "cmpxchgl %1, %3\n\t"		      \ +		       "jnz _L_mutex_timedlock_%=\n\t"			      \ +		       ".subsection 1\n\t"				      \ +		       ".type _L_mutex_timedlock_%=,@function\n"	      \ +		       "_L_mutex_timedlock_%=:\n\t"			      \ +		       "leal %3, %%ecx\n\t"				      \ +		       "movl %7, %%edx\n\t"				      \ +		       "call __lll_mutex_timedlock_wait\n\t"		      \ +		       "jmp 1f\n\t"					      \ +		       ".size _L_mutex_timedlock_%=,.-_L_mutex_timedlock_%=\n"\ +		       ".previous\n"					      \ +		       "1:"						      \ +		       : "=a" (_result), "=c" (ignore1), "=&d" (ignore2),      \ +			 "=m" (futex)					      \ +		       : "0" (0), "1" (1), "m" (futex), "m" (timeout)	      \ +		       : "memory");					      \ +     _result; }) + + +#define lll_mutex_unlock(futex) \ +  (void) ({ int ignore;							      \ +            __asm__ __volatile (LOCK_INSTR "subl $1,%0\n\t"		      \ +			      "jne _L_mutex_unlock_%=\n\t"		      \ +			      ".subsection 1\n\t"			      \ +			      ".type _L_mutex_unlock_%=,@function\n"	      \ +			      "_L_mutex_unlock_%=:\n\t"			      \ +			      "leal %0, %%eax\n\t"			      \ +			      "call __lll_mutex_unlock_wake\n\t"	      \ +			      "jmp 1f\n\t"				      \ +			      ".size _L_mutex_unlock_%=,.-_L_mutex_unlock_%=\n" \ +			      ".previous\n"				      \ +			      "1:"					      \ +			      : "=m" (futex), "=&a" (ignore)		      \ +			      : "m" (futex)				      \ +			      : "memory"); }) + + +#define lll_mutex_islocked(futex) \ +  (futex != 0) + + +extern int __lll_lock_wait (int val, int *__futex) +     __attribute ((regparm (2))) attribute_hidden; +extern int __lll_unlock_wake (int *__futex) +     __attribute ((regparm (1))) attribute_hidden; +extern int lll_unlock_wake_cb (int *__futex) attribute_hidden; + + +/* The states of a lock are: +    0  -  untaken +    1  -  taken by one user +    2  -  taken by more users */ + + +#if defined NOT_IN_libc +# define lll_trylock(futex) lll_mutex_trylock (futex) +# define lll_lock(futex) lll_mutex_lock (futex) +# define lll_unlock(futex) lll_mutex_unlock (futex) +#else +/* Special versions of the macros for use in libc itself.  They avoid +   the lock prefix when the thread library is not used. */ + + + +# define lll_trylock(futex) \ +  ({ unsigned char ret;							      \ +     __asm__ __volatile ("cmpl $0, %%gs:%P5\n\t"			      \ +		       "je,pt 0f\n\t"					      \ +		       "lock\n"						      \ +		       "0:\tcmpxchgl %2, %1; setne %0"			      \ +		       : "=a" (ret), "=m" (futex)			      \ +		       : "r" (LLL_MUTEX_LOCK_INITIALIZER_LOCKED), "m" (futex),\ +			 "0" (LLL_MUTEX_LOCK_INITIALIZER),		      \ +		         "i" (offsetof (tcbhead_t, multiple_threads))	      \ +		       : "memory");					      \ +     ret; }) + + +# define lll_lock(futex) \ +  (void) ({ int ignore1, ignore2;					      \ +	    __asm__ __volatile ("cmpl $0, %%gs:%P6\n\t"			      \ +			      "je,pt 0f\n\t"				      \ +			      "lock\n"					      \ +			      "0:\tcmpxchgl %1, %2\n\t"			      \ +			      "jnz _L_mutex_lock_%=\n\t"		      \ +			      ".subsection 1\n\t"			      \ +			      ".type _L_mutex_lock_%=,@function\n"	      \ +			      "_L_mutex_lock_%=:\n\t"			      \ +			      "leal %2, %%ecx\n\t"			      \ +			      "call __lll_mutex_lock_wait\n\t"		      \ +			      "jmp 1f\n\t"				      \ +			      ".size _L_mutex_lock_%=,.-_L_mutex_lock_%=\n"   \ +			      ".previous\n"				      \ +			      "1:"					      \ +			      : "=a" (ignore1), "=c" (ignore2), "=m" (futex)  \ +			      : "0" (0), "1" (1), "m" (futex),		      \ +		                "i" (offsetof (tcbhead_t, multiple_threads))  \ +			      : "memory"); }) + + +# define lll_unlock(futex) \ +  (void) ({ int ignore;							      \ +            __asm__ __volatile ("cmpl $0, %%gs:%P3\n\t"			      \ +			      "je,pt 0f\n\t"				      \ +			      "lock\n"					      \ +			      "0:\tsubl $1,%0\n\t"		      \ +			      "jne _L_mutex_unlock_%=\n\t"		      \ +			      ".subsection 1\n\t"			      \ +			      ".type _L_mutex_unlock_%=,@function\n"	      \ +			      "_L_mutex_unlock_%=:\n\t"			      \ +			      "leal %0, %%eax\n\t"			      \ +			      "call __lll_mutex_unlock_wake\n\t"	      \ +			      "jmp 1f\n\t"				      \ +			      ".size _L_mutex_unlock_%=,.-_L_mutex_unlock_%=\n" \ +			      ".previous\n"				      \ +			      "1:"					      \ +			      : "=m" (futex), "=&a" (ignore)		      \ +			      : "m" (futex),				      \ +				"i" (offsetof (tcbhead_t, multiple_threads))  \ +			      : "memory"); }) +#endif + + +#define lll_islocked(futex) \ +  (futex != LLL_LOCK_INITIALIZER) + + +/* The kernel notifies a process with uses CLONE_CLEARTID via futex +   wakeup when the clone terminates.  The memory location contains the +   thread ID while the clone is running and is reset to zero +   afterwards. + +   The macro parameter must not have any side effect.  */ +#define lll_wait_tid(tid) \ +  ({									      \ +    int __ret;								      \ +    register __typeof (tid) _tid __asm__ ("edx") = (tid);		      \ +    if (_tid != 0)							      \ +      __asm__ __volatile (LLL_EBX_LOAD					      \ +			"1:\tmovl %1, %%eax\n\t"			      \ +			LLL_ENTER_KERNEL				      \ +			"cmpl $0, (%%ebx)\n\t"				      \ +			"jne,pn 1b\n\t"					      \ +			LLL_EBX_LOAD					      \ +			: "=&a" (__ret)				              \ +			: "i" (SYS_futex), LLL_EBX_REG (&tid), "S" (0),	      \ +			  "c" (FUTEX_WAIT), "d" (_tid),			      \ +			  "i" (offsetof (tcbhead_t, sysinfo)));		      \ +   __ret; }) + +extern int __lll_timedwait_tid (int *tid, const struct timespec *abstime) +     __attribute__ ((regparm (2))) attribute_hidden; +#define lll_timedwait_tid(tid, abstime) \ +  ({									      \ +    int __result = 0;							      \ +    if (tid != 0)							      \ +      {									      \ +	if (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)	      \ +	  __result = EINVAL;						      \ +	else								      \ +	  __result = __lll_timedwait_tid (&tid, abstime);		      \ +      }									      \ +    __result; }) + + +/* Conditional variable handling.  */ + +extern void __lll_cond_wait (pthread_cond_t *cond) +     __attribute ((regparm (1))) attribute_hidden; +extern int __lll_cond_timedwait (pthread_cond_t *cond, +				 const struct timespec *abstime) +     __attribute ((regparm (2))) attribute_hidden; +extern void __lll_cond_wake (pthread_cond_t *cond) +     __attribute ((regparm (1))) attribute_hidden; +extern void __lll_cond_broadcast (pthread_cond_t *cond) +     __attribute ((regparm (1))) attribute_hidden; + + +#define lll_cond_wait(cond) \ +  __lll_cond_wait (cond) +#define lll_cond_timedwait(cond, abstime) \ +  __lll_cond_timedwait (cond, abstime) +#define lll_cond_wake(cond) \ +  __lll_cond_wake (cond) +#define lll_cond_broadcast(cond) \ +  __lll_cond_broadcast (cond) + + +#endif	/* lowlevellock.h */ diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/not-cancel.h b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/not-cancel.h new file mode 100644 index 000000000..5bdba3f51 --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/not-cancel.h @@ -0,0 +1,82 @@ +/* Uncancelable versions of cancelable interfaces.  Linux/NPTL version. +   Copyright (C) 2003 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Ulrich Drepper <drepper@redhat.com>, 2003. + +   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> + +#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt +extern int __open_nocancel (const char *, int, ...) attribute_hidden; +extern int __close_nocancel (int) attribute_hidden; +extern int __read_nocancel (int, void *, size_t) attribute_hidden; +extern int __write_nocancel (int, const void *, size_t) attribute_hidden; +extern pid_t __waitpid_nocancel (pid_t, int *, int) attribute_hidden; + +libc_hidden_proto(__open_nocancel) +libc_hidden_proto(__close_nocancel) +libc_hidden_proto(__read_nocancel) +libc_hidden_proto(__write_nocancel) +libc_hidden_proto(__waitpid_nocancel) + +#else +#define __open_nocancel(name, ...) open (name, __VA_ARGS__) +#define __close_nocancel(fd) close (fd) +#define __read_nocancel(fd, buf, len) read (fd, buf, len) +#define __write_nocancel(fd, buf, len) write (fd, buf, len) +#define __waitpid_nocancel(pid, stat_loc, options) \ +  waitpid (pid, stat_loc, options) +#endif + +/* Uncancelable open.  */ +#define open_not_cancel(name, flags, mode) \ +   __open_nocancel (name, flags, mode) +#define open_not_cancel_2(name, flags) \ +   __open_nocancel (name, flags) + +/* Uncancelable close.  */ +#define close_not_cancel(fd) \ +  __close_nocancel (fd) +#define close_not_cancel_no_status(fd) \ +  (void) ({ INTERNAL_SYSCALL_DECL (err);				      \ +	    INTERNAL_SYSCALL (close, err, 1, (fd)); }) + +/* Uncancelable read.  */ +#define read_not_cancel(fd, buf, n) \ +  __read_nocancel (fd, buf, n) + +/* Uncancelable write.  */ +#define write_not_cancel(fd, buf, n) \ +  __write_nocancel (fd, buf, n) + +/* Uncancelable writev.  */ +#define writev_not_cancel_no_status(fd, iov, n) \ +  (void) ({ INTERNAL_SYSCALL_DECL (err);				      \ +	    INTERNAL_SYSCALL (writev, err, 3, (fd), (iov), (n)); }) + +/* Uncancelable fcntl.  */ +#define fcntl_not_cancel(fd, cmd, val) \ +  __fcntl_nocancel (fd, cmd, val) + +/* Uncancelable waitpid.  */ +#ifdef __NR_waitpid +# define waitpid_not_cancel(pid, stat_loc, options) \ +  __waitpid_nocancel (pid, stat_loc, options) +#else +# define waitpid_not_cancel(pid, stat_loc, options) \ +  INLINE_SYSCALL (wait4, 4, pid, stat_loc, options, NULL) +#endif diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/pt-__syscall_error.c b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/pt-__syscall_error.c new file mode 100644 index 000000000..620640ad6 --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/pt-__syscall_error.c @@ -0,0 +1 @@ +#include <../../../../../../../libc/sysdeps/linux/i386/__syscall_error.c> diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/pt-vfork.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/pt-vfork.S new file mode 100644 index 000000000..939538927 --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/pt-vfork.S @@ -0,0 +1,36 @@ +/* Copyright (C) 1999, 2002, 2004 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Andreas Schwab <schwab@gnu.org>. + +   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 <tcb-offsets.h> + +/* Save the PID value.  */ +#define SAVE_PID \ +	movl	%gs:PID, %edx; 						      \ +	movl	%edx, %eax;						      \ +	negl	%eax;							      \ +	movl	%eax, %gs:PID + +/* Restore the old PID value in the parent.  */ +#define RESTORE_PID \ +	testl	%eax, %eax;						      \ +	je	1f;							      \ +	movl	%edx, %gs:PID;						      \ +1: + +#include <../../../../../../../libc/sysdeps/linux/i386/vfork.S> diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/pthread_once.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/pthread_once.S new file mode 100644 index 000000000..5ab2c5856 --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/pthread_once.S @@ -0,0 +1,181 @@ +/* Copyright (C) 2002, 2003 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 <unwindbuf.h> +#include <sysdep.h> + +#ifndef UP +# define LOCK lock +#else +# define LOCK +#endif + +#define FUTEX_WAKE	1 + +	.comm	__fork_generation, 4, 4 + +	.text + + +	.globl	__pthread_once +	.type	__pthread_once,@function +	.align	16 +	cfi_startproc +__pthread_once: +	movl	4(%esp), %ecx +	testl	$2, (%ecx) +	jz	1f +	xorl	%eax, %eax +	ret + +1:	pushl	%ebx +	cfi_adjust_cfa_offset (4) +	cfi_rel_offset (3, 0) +	pushl	%esi +	cfi_adjust_cfa_offset (4) +	cfi_rel_offset (6, 0) +	movl	%ecx, %ebx +	xorl	%esi, %esi + +	/* Not yet initialized or initialization in progress. +	   Get the fork generation counter now.  */ +6:	movl	(%ebx), %eax +#ifdef __PIC__ +	call	__x86.get_pc_thunk.cx +	addl	$_GLOBAL_OFFSET_TABLE_, %ecx +#endif + +5:	movl	%eax, %edx + +	testl	$2, %eax +	jnz	4f + +	andl	$3, %edx +#ifdef __PIC__ +	orl	__fork_generation@GOTOFF(%ecx), %edx +#else +	orl	__fork_generation, %edx +#endif +	orl	$1, %edx + +	LOCK +	cmpxchgl %edx, (%ebx) +	jnz	5b + +	/* Check whether another thread already runs the initializer.  */ +	testl	$1, %eax +	jz	3f	/* No -> do it.  */ + +	/* Check whether the initializer execution was interrupted +	   by a fork.  */ +	xorl	%edx, %eax +	testl	$0xfffffffc, %eax +	jnz	3f	/* Different for generation -> run initializer.  */ + +	/* Somebody else got here first.  Wait.  */ +	movl	%esi, %ecx		/* movl $FUTEX_WAIT, %ecx */ +	movl	$SYS_futex, %eax +	ENTER_KERNEL +	jmp	6b + +3:	/* Call the initializer function after setting up the +	   cancellation handler.  Note that it is not possible here +	   to use the unwind-based cleanup handling.  This would require +	   that the user-provided function and all the code it calls +	   is compiled with exceptions.  Unfortunately this cannot be +	   guaranteed.  */ +	subl	$UNWINDBUFSIZE+8, %esp +	cfi_adjust_cfa_offset (UNWINDBUFSIZE+8) +	movl	%ecx, %ebx		/* PIC register value.  */ + +	leal	8+UWJMPBUF(%esp), %eax +	movl	$0, 4(%esp) +	movl	%eax, (%esp) +	call	__sigsetjmp@PLT +	testl	%eax, %eax +	jne	7f + +	leal	8(%esp), %eax +	call	HIDDEN_JUMPTARGET(__pthread_register_cancel) + +	/* Call the user-provided initialization function.  */ +	call	*24+UNWINDBUFSIZE(%esp) + +	/* Pop the cleanup handler.  */ +	leal	8(%esp), %eax +	call	HIDDEN_JUMPTARGET(__pthread_unregister_cancel) +	addl	$UNWINDBUFSIZE+8, %esp +	cfi_adjust_cfa_offset (-UNWINDBUFSIZE-8) + +	/* Sucessful run of the initializer.  Signal that we are done.  */ +	movl	12(%esp), %ebx +	LOCK +	addl	$1, (%ebx) + +	/* Wake up all other threads.  */ +	movl	$0x7fffffff, %edx +	movl	$FUTEX_WAKE, %ecx +	movl	$SYS_futex, %eax +	ENTER_KERNEL + +4:	popl	%esi +	cfi_adjust_cfa_offset (-4) +	cfi_restore (6) +	popl	%ebx +	cfi_adjust_cfa_offset (-4) +	cfi_restore (3) +	xorl	%eax, %eax +	ret + +7:	/* __sigsetjmp returned for the second time.  */ +	movl	20+UNWINDBUFSIZE(%esp), %ebx +	cfi_adjust_cfa_offset (UNWINDBUFSIZE+16) +	cfi_offset (3, -8) +	cfi_offset (6, -12) +	movl	$0, (%ebx) + +	movl	$0x7fffffff, %edx +	movl	$FUTEX_WAKE, %ecx +	movl	$SYS_futex, %eax +	ENTER_KERNEL + +	leal	8(%esp), %eax +	call	HIDDEN_JUMPTARGET (__pthread_unwind_next) +	/* NOTREACHED */ +	hlt +	cfi_endproc +	.size	__pthread_once,.-__pthread_once + +	.globl	__pthread_once_internal +__pthread_once_internal = __pthread_once + +	.globl	pthread_once +pthread_once = __pthread_once + + +#ifdef __PIC__ +	.section .gnu.linkonce.t.__x86.get_pc_thunk.cx,"ax",@progbits +	.globl	__x86.get_pc_thunk.cx +	.hidden	__x86.get_pc_thunk.cx +	.type	__x86.get_pc_thunk.cx,@function +__x86.get_pc_thunk.cx: +	movl (%esp), %ecx; +	ret +	.size	__x86.get_pc_thunk.cx,.-__x86.get_pc_thunk.cx +#endif diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/pthread_spin_init.c b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/pthread_spin_init.c new file mode 100644 index 000000000..d36e5373d --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/pthread_spin_init.c @@ -0,0 +1 @@ +#include <sysdeps/i386/pthread_spin_init.c> diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/pthread_spin_unlock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/pthread_spin_unlock.S new file mode 100644 index 000000000..8bae0fd31 --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/pthread_spin_unlock.S @@ -0,0 +1 @@ +#include <sysdeps/i386/pthread_spin_unlock.S> diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/smp.h b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/smp.h new file mode 100644 index 000000000..2c0cbe99a --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/smp.h @@ -0,0 +1,24 @@ +/* Determine whether the host has multiple processors.  SH version. +   Copyright (C) 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 Library General Public License as +   published by the Free Software Foundation; either version 2 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 +   Library General Public License for more details. + +   You should have received a copy of the GNU Library General Public +   License along with the GNU C Library; see the file COPYING.LIB.  If not, +   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +   Boston, MA 02111-1307, USA.  */ + +static inline int +is_smp_system (void) +{ +  return 0; +} diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/sysdep-cancel.h b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/sysdep-cancel.h new file mode 100644 index 000000000..f32c5bd20 --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/sysdep-cancel.h @@ -0,0 +1,139 @@ +/* Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Jakub Jelinek <jakub@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> +#include <tls.h> +#ifndef __ASSEMBLER__ +# include <pthreadP.h> +#endif + +#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt + +# undef PSEUDO +# define PSEUDO(name, syscall_name, args)				      \ +  .text;								      \ +  ENTRY (name)								      \ +    cmpl $0, %gs:MULTIPLE_THREADS_OFFSET;				      \ +    jne L(pseudo_cancel);						      \ +  .type __##syscall_name##_nocancel,@function;				      \ +  .globl __##syscall_name##_nocancel;					      \ +  __##syscall_name##_nocancel:						      \ +    DO_CALL (syscall_name, args);					      \ +    cmpl $-4095, %eax;							      \ +    jae SYSCALL_ERROR_LABEL;						      \ +    ret;								      \ +  .size __##syscall_name##_nocancel,.-__##syscall_name##_nocancel;	      \ +  L(pseudo_cancel):							      \ +    CENABLE								      \ +    SAVE_OLDTYPE_##args							      \ +    PUSHCARGS_##args							      \ +    DOCARGS_##args							      \ +    movl $SYS_ify (syscall_name), %eax;					      \ +    ENTER_KERNEL;							      \ +    POPCARGS_##args;							      \ +    POPSTATE_##args							      \ +    cmpl $-4095, %eax;							      \ +    jae SYSCALL_ERROR_LABEL;						      \ +  L(pseudo_end): + +# define SAVE_OLDTYPE_0	movl %eax, %ecx; +# define SAVE_OLDTYPE_1	SAVE_OLDTYPE_0 +# define SAVE_OLDTYPE_2	pushl %eax; cfi_adjust_cfa_offset (4); +# define SAVE_OLDTYPE_3	SAVE_OLDTYPE_2 +# define SAVE_OLDTYPE_4	SAVE_OLDTYPE_2 +# define SAVE_OLDTYPE_5	SAVE_OLDTYPE_2 + +# define PUSHCARGS_0	/* No arguments to push.  */ +# define DOCARGS_0	/* No arguments to frob.  */ +# define POPCARGS_0	/* No arguments to pop.  */ +# define _PUSHCARGS_0	/* No arguments to push.  */ +# define _POPCARGS_0	/* No arguments to pop.  */ + +# define PUSHCARGS_1	movl %ebx, %edx; cfi_register (ebx, edx); PUSHCARGS_0 +# define DOCARGS_1	_DOARGS_1 (4) +# define POPCARGS_1	POPCARGS_0; movl %edx, %ebx; cfi_restore (ebx); +# define _PUSHCARGS_1	pushl %ebx; cfi_adjust_cfa_offset (4); \ +			cfi_rel_offset (ebx, 0); _PUSHCARGS_0 +# define _POPCARGS_1	_POPCARGS_0; popl %ebx; \ +			cfi_adjust_cfa_offset (-4); cfi_restore (ebx); + +# define PUSHCARGS_2	PUSHCARGS_1 +# define DOCARGS_2	_DOARGS_2 (12) +# define POPCARGS_2	POPCARGS_1 +# define _PUSHCARGS_2	_PUSHCARGS_1 +# define _POPCARGS_2	_POPCARGS_1 + +# define PUSHCARGS_3	_PUSHCARGS_2 +# define DOCARGS_3	_DOARGS_3 (20) +# define POPCARGS_3	_POPCARGS_3 +# define _PUSHCARGS_3	_PUSHCARGS_2 +# define _POPCARGS_3	_POPCARGS_2 + +# define PUSHCARGS_4	_PUSHCARGS_4 +# define DOCARGS_4	_DOARGS_4 (28) +# define POPCARGS_4	_POPCARGS_4 +# define _PUSHCARGS_4	pushl %esi; cfi_adjust_cfa_offset (4); \ +			cfi_rel_offset (esi, 0); _PUSHCARGS_3 +# define _POPCARGS_4	_POPCARGS_3; popl %esi; \ +			cfi_adjust_cfa_offset (-4); cfi_restore (esi); + +# define PUSHCARGS_5	_PUSHCARGS_5 +# define DOCARGS_5	_DOARGS_5 (36) +# define POPCARGS_5	_POPCARGS_5 +# define _PUSHCARGS_5	pushl %edi; cfi_adjust_cfa_offset (4); \ +			cfi_rel_offset (edi, 0); _PUSHCARGS_4 +# define _POPCARGS_5	_POPCARGS_4; popl %edi; \ +			cfi_adjust_cfa_offset (-4); cfi_restore (edi); + +# ifdef IS_IN_libpthread +#  define CENABLE	call __pthread_enable_asynccancel; +#  define CDISABLE	call __pthread_disable_asynccancel +# elif !defined NOT_IN_libc +#  define CENABLE	call __libc_enable_asynccancel; +#  define CDISABLE	call __libc_disable_asynccancel +# elif defined IS_IN_librt +#  define CENABLE	call __librt_enable_asynccancel; +#  define CDISABLE	call __librt_disable_asynccancel +# else +#  error Unsupported library +# endif +# define POPSTATE_0 \ + pushl %eax; cfi_adjust_cfa_offset (4); movl %ecx, %eax; \ + CDISABLE; popl %eax; cfi_adjust_cfa_offset (-4); +# define POPSTATE_1	POPSTATE_0 +# define POPSTATE_2	xchgl (%esp), %eax; CDISABLE; popl %eax; \ +			cfi_adjust_cfa_offset (-4); +# define POPSTATE_3	POPSTATE_2 +# define POPSTATE_4	POPSTATE_3 +# define POPSTATE_5	POPSTATE_4 + +# ifndef __ASSEMBLER__ +#  define SINGLE_THREAD_P \ +  __builtin_expect (THREAD_GETMEM (THREAD_SELF, \ +				   header.multiple_threads) == 0, 1) +# else +#  define SINGLE_THREAD_P cmpl $0, %gs:MULTIPLE_THREADS_OFFSET +# endif + +#elif !defined __ASSEMBLER__ + +# define SINGLE_THREAD_P (1) +# define NO_CANCELLATION 1 + +#endif diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/sysdep.h b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/sysdep.h new file mode 100644 index 000000000..674d5c699 --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/sysdep.h @@ -0,0 +1,336 @@ +/* Copyright (C) 1992,1993,1995-2000,2002-2006,2007 +	Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Ulrich Drepper, <drepper@gnu.org>, August 1995. + +   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 _LINUX_I386_SYSDEP_H +#define _LINUX_I386_SYSDEP_H 1 + +#include <sys/syscall.h> +#include <sysdeps/i386/sysdep.h> + +#ifndef offsetof +# define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) +#endif + +/* For Linux we can use the system call table in the header file +	/usr/include/asm/unistd.h +   of the kernel.  But these symbols do not follow the SYS_* syntax +   so we have to redefine the `SYS_ify' macro here.  */ +#undef SYS_ify +#define SYS_ify(syscall_name)	__NR_##syscall_name + +#if defined USE_DL_SYSINFO \ +    && (!defined NOT_IN_libc || defined IS_IN_libpthread) +# define I386_USE_SYSENTER	1 +#else +# undef I386_USE_SYSENTER +#endif + +#ifdef __ASSEMBLER__ + +/* Linux uses a negative return value to indicate syscall errors, +   unlike most Unices, which use the condition codes' carry flag. + +   Since version 2.1 the return value of a system call might be +   negative even if the call succeeded.  E.g., the `lseek' system call +   might return a large offset.  Therefore we must not anymore test +   for < 0, but test for a real error by making sure the value in %eax +   is a real error number.  Linus said he will make sure the no syscall +   returns a value in -1 .. -4095 as a valid result so we can savely +   test with -4095.  */ + +/* We don't want the label for the error handle to be global when we define +   it here.  */ +#ifdef __PIC__ +# define SYSCALL_ERROR_LABEL 0f +#else +# define SYSCALL_ERROR_LABEL syscall_error +#endif + +#undef	PSEUDO +#define	PSEUDO(name, syscall_name, args)				      \ +  .text;								      \ +  ENTRY (name)								      \ +    DO_CALL (syscall_name, args);					      \ +    cmpl $-4095, %eax;							      \ +    jae SYSCALL_ERROR_LABEL;						      \ +  L(pseudo_end): + +#undef	PSEUDO_END +#define	PSEUDO_END(name)						      \ +  SYSCALL_ERROR_HANDLER							      \ +  END (name) + +#undef	PSEUDO_NOERRNO +#define	PSEUDO_NOERRNO(name, syscall_name, args)			      \ +  .text;								      \ +  ENTRY (name)								      \ +    DO_CALL (syscall_name, args) + +#undef	PSEUDO_END_NOERRNO +#define	PSEUDO_END_NOERRNO(name)					      \ +  END (name) + +#define ret_NOERRNO ret + +/* The function has to return the error code.  */ +#undef	PSEUDO_ERRVAL +#define	PSEUDO_ERRVAL(name, syscall_name, args) \ +  .text;								      \ +  ENTRY (name)								      \ +    DO_CALL (syscall_name, args);					      \ +    negl %eax + +#undef	PSEUDO_END_ERRVAL +#define	PSEUDO_END_ERRVAL(name) \ +  END (name) + +#define ret_ERRVAL ret + +#ifndef __PIC__ +# define SYSCALL_ERROR_HANDLER	/* Nothing here; code in sysdep.S is used.  */ +#else + +# ifdef RTLD_PRIVATE_ERRNO +#  define SYSCALL_ERROR_HANDLER						      \ +0:SETUP_PIC_REG(cx);							      \ +  addl $_GLOBAL_OFFSET_TABLE_, %ecx;					      \ +  xorl %edx, %edx;							      \ +  subl %eax, %edx;							      \ +  movl %edx, rtld_errno@GOTOFF(%ecx);					      \ +  orl $-1, %eax;							      \ +  jmp L(pseudo_end); + +# elif defined _LIBC_REENTRANT + +#  if USE___THREAD +#   ifndef NOT_IN_libc +#    define SYSCALL_ERROR_ERRNO __libc_errno +#   else +#    define SYSCALL_ERROR_ERRNO errno +#   endif +#   define SYSCALL_ERROR_HANDLER					      \ +0:SETUP_PIC_REG (cx);							      \ +  addl $_GLOBAL_OFFSET_TABLE_, %ecx;					      \ +  movl SYSCALL_ERROR_ERRNO@GOTNTPOFF(%ecx), %ecx;			      \ +  xorl %edx, %edx;							      \ +  subl %eax, %edx;							      \ +  SYSCALL_ERROR_HANDLER_TLS_STORE (%edx, %ecx);				      \ +  orl $-1, %eax;							      \ +  jmp L(pseudo_end); +#   ifndef NO_TLS_DIRECT_SEG_REFS +#    define SYSCALL_ERROR_HANDLER_TLS_STORE(src, destoff)		      \ +  movl src, %gs:(destoff) +#   else +#    define SYSCALL_ERROR_HANDLER_TLS_STORE(src, destoff)		      \ +  addl %gs:0, destoff;							      \ +  movl src, (destoff) +#   endif +#  else +#   define SYSCALL_ERROR_HANDLER					      \ +0:pushl %ebx;								      \ +  cfi_adjust_cfa_offset (4);						      \ +  cfi_rel_offset (ebx, 0);						      \ +  SETUP_PIC_REG (bx);							      \ +  addl $_GLOBAL_OFFSET_TABLE_, %ebx;					      \ +  xorl %edx, %edx;							      \ +  subl %eax, %edx;							      \ +  pushl %edx;								      \ +  cfi_adjust_cfa_offset (4);						      \ +  call __errno_location@PLT;					              \ +  popl %ecx;								      \ +  cfi_adjust_cfa_offset (-4);						      \ +  popl %ebx;								      \ +  cfi_adjust_cfa_offset (-4);						      \ +  cfi_restore (ebx);							      \ +  movl %ecx, (%eax);							      \ +  orl $-1, %eax;							      \ +  jmp L(pseudo_end); +/* A quick note: it is assumed that the call to `__errno_location' does +   not modify the stack!  */ +#  endif +# else +/* Store (- %eax) into errno through the GOT.  */ +#  define SYSCALL_ERROR_HANDLER						      \ +0:SETUP_PIC_REG(cx);							      \ +  addl $_GLOBAL_OFFSET_TABLE_, %ecx;					      \ +  xorl %edx, %edx;							      \ +  subl %eax, %edx;							      \ +  movl errno@GOT(%ecx), %ecx;						      \ +  movl %edx, (%ecx);							      \ +  orl $-1, %eax;							      \ +  jmp L(pseudo_end); +# endif	/* _LIBC_REENTRANT */ +#endif	/* __PIC__ */ + + +/* The original calling convention for system calls on Linux/i386 is +   to use int $0x80.  */ +#ifdef I386_USE_SYSENTER +# ifdef SHARED +#  define ENTER_KERNEL call *%gs:SYSINFO_OFFSET +# else +#  define ENTER_KERNEL call *_dl_sysinfo +# endif +#else +# define ENTER_KERNEL int $0x80 +#endif + +/* Linux takes system call arguments in registers: + +	syscall number	%eax	     call-clobbered +	arg 1		%ebx	     call-saved +	arg 2		%ecx	     call-clobbered +	arg 3		%edx	     call-clobbered +	arg 4		%esi	     call-saved +	arg 5		%edi	     call-saved +	arg 6		%ebp	     call-saved + +   The stack layout upon entering the function is: + +	24(%esp)	Arg# 6 +	20(%esp)	Arg# 5 +	16(%esp)	Arg# 4 +	12(%esp)	Arg# 3 +	 8(%esp)	Arg# 2 +	 4(%esp)	Arg# 1 +	  (%esp)	Return address + +   (Of course a function with say 3 arguments does not have entries for +   arguments 4, 5, and 6.) + +   The following code tries hard to be optimal.  A general assumption +   (which is true according to the data books I have) is that + +	2 * xchg	is more expensive than	pushl + movl + popl + +   Beside this a neat trick is used.  The calling conventions for Linux +   tell that among the registers used for parameters %ecx and %edx need +   not be saved.  Beside this we may clobber this registers even when +   they are not used for parameter passing. + +   As a result one can see below that we save the content of the %ebx +   register in the %edx register when we have less than 3 arguments +   (2 * movl is less expensive than pushl + popl). + +   Second unlike for the other registers we don't save the content of +   %ecx and %edx when we have more than 1 and 2 registers resp. + +   The code below might look a bit long but we have to take care for +   the pipelined processors (i586).  Here the `pushl' and `popl' +   instructions are marked as NP (not pairable) but the exception is +   two consecutive of these instruction.  This gives no penalty on +   other processors though.  */ + +#undef	DO_CALL +#define DO_CALL(syscall_name, args)			      		      \ +    PUSHARGS_##args							      \ +    DOARGS_##args							      \ +    movl $SYS_ify (syscall_name), %eax;					      \ +    ENTER_KERNEL							      \ +    POPARGS_##args + +#define PUSHARGS_0	/* No arguments to push.  */ +#define	DOARGS_0	/* No arguments to frob.  */ +#define	POPARGS_0	/* No arguments to pop.  */ +#define	_PUSHARGS_0	/* No arguments to push.  */ +#define _DOARGS_0(n)	/* No arguments to frob.  */ +#define	_POPARGS_0	/* No arguments to pop.  */ + +#define PUSHARGS_1	movl %ebx, %edx; L(SAVEBX1): PUSHARGS_0 +#define	DOARGS_1	_DOARGS_1 (4) +#define	POPARGS_1	POPARGS_0; movl %edx, %ebx; L(RESTBX1): +#define	_PUSHARGS_1	pushl %ebx; cfi_adjust_cfa_offset (4); \ +			cfi_rel_offset (ebx, 0); L(PUSHBX1): _PUSHARGS_0 +#define _DOARGS_1(n)	movl n(%esp), %ebx; _DOARGS_0(n-4) +#define	_POPARGS_1	_POPARGS_0; popl %ebx; cfi_adjust_cfa_offset (-4); \ +			cfi_restore (ebx); L(POPBX1): + +#define PUSHARGS_2	PUSHARGS_1 +#define	DOARGS_2	_DOARGS_2 (8) +#define	POPARGS_2	POPARGS_1 +#define _PUSHARGS_2	_PUSHARGS_1 +#define	_DOARGS_2(n)	movl n(%esp), %ecx; _DOARGS_1 (n-4) +#define	_POPARGS_2	_POPARGS_1 + +#define PUSHARGS_3	_PUSHARGS_2 +#define DOARGS_3	_DOARGS_3 (16) +#define POPARGS_3	_POPARGS_3 +#define _PUSHARGS_3	_PUSHARGS_2 +#define _DOARGS_3(n)	movl n(%esp), %edx; _DOARGS_2 (n-4) +#define _POPARGS_3	_POPARGS_2 + +#define PUSHARGS_4	_PUSHARGS_4 +#define DOARGS_4	_DOARGS_4 (24) +#define POPARGS_4	_POPARGS_4 +#define _PUSHARGS_4	pushl %esi; cfi_adjust_cfa_offset (4); \ +			cfi_rel_offset (esi, 0); L(PUSHSI1): _PUSHARGS_3 +#define _DOARGS_4(n)	movl n(%esp), %esi; _DOARGS_3 (n-4) +#define _POPARGS_4	_POPARGS_3; popl %esi; cfi_adjust_cfa_offset (-4); \ +			cfi_restore (esi); L(POPSI1): + +#define PUSHARGS_5	_PUSHARGS_5 +#define DOARGS_5	_DOARGS_5 (32) +#define POPARGS_5	_POPARGS_5 +#define _PUSHARGS_5	pushl %edi; cfi_adjust_cfa_offset (4); \ +			cfi_rel_offset (edi, 0); L(PUSHDI1): _PUSHARGS_4 +#define _DOARGS_5(n)	movl n(%esp), %edi; _DOARGS_4 (n-4) +#define _POPARGS_5	_POPARGS_4; popl %edi; cfi_adjust_cfa_offset (-4); \ +			cfi_restore (edi); L(POPDI1): + +#define PUSHARGS_6	_PUSHARGS_6 +#define DOARGS_6	_DOARGS_6 (40) +#define POPARGS_6	_POPARGS_6 +#define _PUSHARGS_6	pushl %ebp; cfi_adjust_cfa_offset (4); \ +			cfi_rel_offset (ebp, 0); L(PUSHBP1): _PUSHARGS_5 +#define _DOARGS_6(n)	movl n(%esp), %ebp; _DOARGS_5 (n-4) +#define _POPARGS_6	_POPARGS_5; popl %ebp; cfi_adjust_cfa_offset (-4); \ +			cfi_restore (ebp); L(POPBP1): + +#endif	/* __ASSEMBLER__ */ + + +/* Pointer mangling support.  */ +#if defined NOT_IN_libc && defined IS_IN_rtld +/* We cannot use the thread descriptor because in ld.so we use setjmp +   earlier than the descriptor is initialized.  Using a global variable +   is too complicated here since we have no PC-relative addressing mode.  */ +#else +# ifdef __ASSEMBLER__ +#  define PTR_MANGLE(reg)	xorl %gs:POINTER_GUARD, reg;		      \ +				roll $9, reg +#  define PTR_DEMANGLE(reg)	rorl $9, reg;				      \ +				xorl %gs:POINTER_GUARD, reg +# else +#  define PTR_MANGLE(var)	asm ("xorl %%gs:%c2, %0\n"		      \ +				     "roll $9, %0"			      \ +				     : "=r" (var)			      \ +				     : "0" (var),			      \ +				       "i" (offsetof (tcbhead_t,	      \ +						      pointer_guard))) +#  define PTR_DEMANGLE(var)	asm ("rorl $9, %0\n"			      \ +				     "xorl %%gs:%c2, %0"		      \ +				     : "=r" (var)			      \ +				     : "0" (var),			      \ +				       "i" (offsetof (tcbhead_t,	      \ +						      pointer_guard))) +# endif +#endif + +#endif /* linux/i386/sysdep.h */ diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/vfork.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/vfork.S new file mode 100644 index 000000000..dc7fb2ec4 --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/vfork.S @@ -0,0 +1,38 @@ +/* Copyright (C) 1999, 2002, 2004 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.  */ + +#include <tcb-offsets.h> + +/* Save the PID value.  */ +#define SAVE_PID \ +	movl	%gs:PID, %edx; 						      \ +	movl	%edx, %eax;						      \ +	negl	%eax;							      \ +	jne	1f;							      \ +	movl	$0x80000000, %eax;					      \ +1:	movl	%eax, %gs:PID + +/* Restore the old PID value in the parent.  */ +#define RESTORE_PID \ +	testl	%eax, %eax;						      \ +	je	1f;							      \ +	movl	%edx, %gs:PID;						      \ +1: + + +#include <libc/sysdeps/linux/i386/vfork.S> | 
