* sysdeps/sparc/fpu/fraiseexcpt.c (__feraiseexcept): Fix raising

FE_UNDERFLOW on Niagara CPUs.
	* sysdeps/sparc/fpu/feholdexcpt.c (feholdexcept): Clear all
	exceptions.

	* sysdeps/unix/sysv/linux/sparc/internaltypes.h (sparc_new_sem,
	sparc_old_sem): New structs.
	* sysdeps/unix/sysv/linux/sparc/sparc32/sem_wait.c
	(__sem_wait_cleanup): New function.
	(__new_sem_wait): Use sparc_new_sem structure.  Bump and afterwards
	decrease nwaiters.  Register __sem_wait_cleanup as cleanup handler.
	Pass isem->private ^ FUTEX_PRIVATE_FLAG as last argument to
	lll_futex_wait.
	(__old_sem_wait): New function.
	* sysdeps/unix/sysv/linux/sparc/sparc32/sparcv9/sem_wait.c: Include
	nptl/sysdeps/unix/sysv/linux/sparc version.
	* sysdeps/unix/sysv/linux/sparc/sparc32/sparcv9/sem_timedwait.c:
	Likewise.
	* sysdeps/unix/sysv/linux/sparc/sparc32/sparcv9/sem_post.c: Likewise.
	* sysdeps/unix/sysv/linux/sparc/sparc32/sem_trywait.c
	(__new_sem_trywait): Use sparc_old_sem structure.
	* sysdeps/unix/sysv/linux/sparc/sparc32/sem_timedwait.c
	(sem_timedwait): Use sparc_new_sem structure.  Bump and afterwards
	decrease nwaiters.  Register __sem_wait_cleanup as cleanup handler.
	Pass isem->private ^ FUTEX_PRIVATE_FLAG as last argument to
	lll_futex_timed_wait.
	* sysdeps/unix/sysv/linux/sparc/sparc32/sem_post.c (__new_sem_post):
	Use sparc_new_sem structure.  Only wake if nwaiters > 0.  Pass
	isem->private ^ FUTEX_PRIVATE_FLAG as last argument to
	lll_futex_wake.
	(__old_sem_post): New function.
	* sysdeps/unix/sysv/linux/sparc/sem_wait.c: New file.
	* sysdeps/unix/sysv/linux/sparc/sem_init.c: New file.
	* sysdeps/unix/sysv/linux/sparc/sem_timedwait.c: New file.
	* sysdeps/unix/sysv/linux/sparc/sem_post.c: New file.
	* sysdeps/unix/sysv/linux/sparc/sparc32/sparcv9/sem_init.c: Remove.
	* sysdeps/unix/sysv/linux/sparc/sparc32/sem_init.c: Remove.
2007-08-15  Jakub Jelinek  <jakub@redhat.com>

	* sysdeps/sparc/fpu/fraiseexcpt.c (__feraiseexcept): Fix raising
	FE_UNDERFLOW on Niagara CPUs.

	* sysdeps/sparc/fpu/feholdexcpt.c (feholdexcept): Clear all
	exceptions.
This commit is contained in:
Jakub Jelinek 2007-08-15 20:47:43 +00:00
parent d13f4a4386
commit e4720b0e59
17 changed files with 641 additions and 97 deletions

View File

@ -1,3 +1,11 @@
2007-08-15 Jakub Jelinek <jakub@redhat.com>
* sysdeps/sparc/fpu/fraiseexcpt.c (__feraiseexcept): Fix raising
FE_UNDERFLOW on Niagara CPUs.
* sysdeps/sparc/fpu/feholdexcpt.c (feholdexcept): Clear all
exceptions.
2007-08-14 Jakub Jelinek <jakub@redhat.com>
* sysdeps/sparc/sparc32/dl-machine.h (elf_machine_runtime_setup): No

View File

@ -1,3 +1,38 @@
2007-08-15 Jakub Jelinek <jakub@redhat.com>
* sysdeps/unix/sysv/linux/sparc/internaltypes.h (sparc_new_sem,
sparc_old_sem): New structs.
* sysdeps/unix/sysv/linux/sparc/sparc32/sem_wait.c
(__sem_wait_cleanup): New function.
(__new_sem_wait): Use sparc_new_sem structure. Bump and afterwards
decrease nwaiters. Register __sem_wait_cleanup as cleanup handler.
Pass isem->private ^ FUTEX_PRIVATE_FLAG as last argument to
lll_futex_wait.
(__old_sem_wait): New function.
* sysdeps/unix/sysv/linux/sparc/sparc32/sparcv9/sem_wait.c: Include
nptl/sysdeps/unix/sysv/linux/sparc version.
* sysdeps/unix/sysv/linux/sparc/sparc32/sparcv9/sem_timedwait.c:
Likewise.
* sysdeps/unix/sysv/linux/sparc/sparc32/sparcv9/sem_post.c: Likewise.
* sysdeps/unix/sysv/linux/sparc/sparc32/sem_trywait.c
(__new_sem_trywait): Use sparc_old_sem structure.
* sysdeps/unix/sysv/linux/sparc/sparc32/sem_timedwait.c
(sem_timedwait): Use sparc_new_sem structure. Bump and afterwards
decrease nwaiters. Register __sem_wait_cleanup as cleanup handler.
Pass isem->private ^ FUTEX_PRIVATE_FLAG as last argument to
lll_futex_timed_wait.
* sysdeps/unix/sysv/linux/sparc/sparc32/sem_post.c (__new_sem_post):
Use sparc_new_sem structure. Only wake if nwaiters > 0. Pass
isem->private ^ FUTEX_PRIVATE_FLAG as last argument to
lll_futex_wake.
(__old_sem_post): New function.
* sysdeps/unix/sysv/linux/sparc/sem_wait.c: New file.
* sysdeps/unix/sysv/linux/sparc/sem_init.c: New file.
* sysdeps/unix/sysv/linux/sparc/sem_timedwait.c: New file.
* sysdeps/unix/sysv/linux/sparc/sem_post.c: New file.
* sysdeps/unix/sysv/linux/sparc/sparc32/sparcv9/sem_init.c: Remove.
* sysdeps/unix/sysv/linux/sparc/sparc32/sem_init.c: Remove.
2007-08-14 Kaz Kojima <kkojima@rr.iij4u.or.jp>
* sysdeps/unix/sysv/linux/sh/pthread_cond_broadcast.S

View File

@ -15,4 +15,20 @@ union sparc_pthread_barrier
} s;
};
struct sparc_new_sem
{
unsigned int value;
unsigned char lock;
unsigned char private;
unsigned char pad[2];
unsigned long int nwaiters;
};
struct sparc_old_sem
{
unsigned int value;
unsigned char lock;
unsigned char private;
};
#endif

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2002, 2006 Free Software Foundation, Inc.
/* Copyright (C) 2002, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
@ -18,16 +18,12 @@
02111-1307 USA. */
#include <errno.h>
#include <string.h>
#include <semaphore.h>
#include <lowlevellock.h>
#include <shlib-compat.h>
#include "semaphoreP.h"
struct sparc_sem
{
struct sem s;
unsigned char lock;
};
#include <kernel-features.h>
int
@ -44,20 +40,54 @@ __new_sem_init (sem, pshared, value)
}
/* Map to the internal type. */
struct sparc_sem *isem = (struct sparc_sem *) sem;
struct sparc_new_sem *isem = (struct sparc_new_sem *) sem;
/* Use the value the user provided. */
isem->s.count = value;
isem->lock = 0;
/* We can completely ignore the PSHARED parameter since inter-process
use needs no special preparation. */
/* Use the values the user provided. */
memset (isem, '\0', sizeof (*isem));
isem->value = value;
#ifdef __ASSUME_PRIVATE_FUTEX
isem->private = pshared ? 0 : FUTEX_PRIVATE_FLAG;
#else
isem->private = pshared ? 0 : THREAD_GETMEM (THREAD_SELF,
header.private_futex);
#endif
return 0;
}
versioned_symbol (libpthread, __new_sem_init, sem_init, GLIBC_2_1);
#if SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_1)
strong_alias (__new_sem_init, __old_sem_init)
int
attribute_compat_text_section
__old_sem_init (sem, pshared, value)
sem_t *sem;
int pshared;
unsigned int value;
{
/* Parameter sanity check. */
if (__builtin_expect (value > SEM_VALUE_MAX, 0))
{
__set_errno (EINVAL);
return -1;
}
/* Map to the internal type. */
struct sparc_old_sem *isem = (struct sparc_old_sem *) sem;
/* Use the value the user provided. */
memset (isem, '\0', sizeof (*isem));
isem->value = value;
#ifdef __ASSUME_PRIVATE_FUTEX
isem->private = pshared ? 0 : FUTEX_PRIVATE_FLAG;
#else
isem->private = pshared ? 0 : THREAD_GETMEM (THREAD_SELF,
header.private_futex);
#endif
return 0;
}
compat_symbol (libpthread, __old_sem_init, sem_init, GLIBC_2_0);
#endif

View File

@ -0,0 +1,69 @@
/* sem_post -- post to a POSIX semaphore. SPARC version.
Copyright (C) 2003, 2004, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Jakub Jelinek <jakub@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 <errno.h>
#include <sysdep.h>
#include <lowlevellock.h>
#include <internaltypes.h>
#include <semaphore.h>
#include <shlib-compat.h>
int
__new_sem_post (sem_t *sem)
{
struct sparc_new_sem *isem = (struct sparc_new_sem *) sem;
int nr = atomic_increment_val (&isem->value);
atomic_full_barrier ();
if (isem->nwaiters > 0)
{
int err = lll_futex_wake (&isem->value, 1,
isem->private ^ FUTEX_PRIVATE_FLAG);
if (__builtin_expect (err, 0) < 0)
{
__set_errno (-err);
return -1;
}
}
return 0;
}
versioned_symbol (libpthread, __new_sem_post, sem_post, GLIBC_2_1);
#if SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_1)
int
attribute_compat_text_section
__old_sem_post (sem_t *sem)
{
struct sparc_old_sem *isem = (struct sparc_old_sem *) sem;
int nr = atomic_increment_val (&isem->value);
int err = lll_futex_wake (&isem->value, 1,
isem->private ^ FUTEX_PRIVATE_FLAG);
if (__builtin_expect (err, 0) < 0)
{
__set_errno (-err);
return -1;
}
return 0;
}
compat_symbol (libpthread, __old_sem_post, sem_post, GLIBC_2_0);
#endif

View File

@ -0,0 +1,112 @@
/* sem_timedwait -- wait on a semaphore. Generic futex-using version.
Copyright (C) 2003, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Paul Mackerras <paulus@au.ibm.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 <errno.h>
#include <sysdep.h>
#include <lowlevellock.h>
#include <internaltypes.h>
#include <semaphore.h>
#include <pthreadP.h>
#include <shlib-compat.h>
extern void __sem_wait_cleanup (void *arg) attribute_hidden;
int
sem_timedwait (sem_t *sem, const struct timespec *abstime)
{
struct sparc_new_sem *isem = (struct sparc_new_sem *) sem;
int err;
if (atomic_decrement_if_positive (&isem->value) > 0)
return 0;
if (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)
{
__set_errno (EINVAL);
return -1;
}
atomic_increment (&isem->nwaiters);
pthread_cleanup_push (__sem_wait_cleanup, isem);
while (1)
{
struct timeval tv;
struct timespec rt;
int sec, nsec;
/* Get the current time. */
__gettimeofday (&tv, NULL);
/* Compute relative timeout. */
sec = abstime->tv_sec - tv.tv_sec;
nsec = abstime->tv_nsec - tv.tv_usec * 1000;
if (nsec < 0)
{
nsec += 1000000000;
--sec;
}
/* Already timed out? */
err = -ETIMEDOUT;
if (sec < 0)
{
__set_errno (ETIMEDOUT);
err = -1;
break;
}
/* Do wait. */
rt.tv_sec = sec;
rt.tv_nsec = nsec;
/* Enable asynchronous cancellation. Required by the standard. */
int oldtype = __pthread_enable_asynccancel ();
err = lll_futex_timed_wait (&isem->value, 0, &rt,
isem->private ^ FUTEX_PRIVATE_FLAG);
/* Disable asynchronous cancellation. */
__pthread_disable_asynccancel (oldtype);
if (err != 0 && err != -EWOULDBLOCK)
{
__set_errno (-err);
err = -1;
break;
}
if (atomic_decrement_if_positive (&isem->value) > 0)
{
err = 0;
break;
}
}
pthread_cleanup_pop (0);
atomic_decrement (&isem->nwaiters);
return err;
}

View File

@ -0,0 +1,117 @@
/* sem_wait -- wait on a semaphore. Generic futex-using version.
Copyright (C) 2003, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Paul Mackerras <paulus@au.ibm.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 <errno.h>
#include <sysdep.h>
#include <lowlevellock.h>
#include <internaltypes.h>
#include <semaphore.h>
#include <pthreadP.h>
#include <shlib-compat.h>
void
attribute_hidden
__sem_wait_cleanup (void *arg)
{
struct sparc_new_sem *isem = (struct sparc_new_sem *) arg;
atomic_decrement (&isem->nwaiters);
}
int
__new_sem_wait (sem_t *sem)
{
struct sparc_new_sem *isem = (struct sparc_new_sem *) sem;
int err;
if (atomic_decrement_if_positive (&isem->value) > 0)
return 0;
atomic_increment (&isem->nwaiters);
pthread_cleanup_push (__sem_wait_cleanup, isem);
while (1)
{
/* Enable asynchronous cancellation. Required by the standard. */
int oldtype = __pthread_enable_asynccancel ();
err = lll_futex_wait (&isem->value, 0,
isem->private ^ FUTEX_PRIVATE_FLAG);
/* Disable asynchronous cancellation. */
__pthread_disable_asynccancel (oldtype);
if (err != 0 && err != -EWOULDBLOCK)
{
__set_errno (-err);
err = -1;
break;
}
if (atomic_decrement_if_positive (&isem->value) > 0)
{
err = 0;
break;
}
}
pthread_cleanup_pop (0);
atomic_decrement (&isem->nwaiters);
return err;
}
versioned_symbol (libpthread, __new_sem_wait, sem_wait, GLIBC_2_1);
#if SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_1)
int
attribute_compat_text_section
__old_sem_wait (sem_t *sem)
{
struct sparc_old_sem *isem = (struct sparc_old_sem *) sem;
int err;
do
{
if (atomic_decrement_if_positive (&isem->value) > 0)
return 0;
/* Enable asynchronous cancellation. Required by the standard. */
int oldtype = __pthread_enable_asynccancel ();
err = lll_futex_wait (&isem->value, 0,
isem->private ^ FUTEX_PRIVATE_FLAG);
/* Disable asynchronous cancellation. */
__pthread_disable_asynccancel (oldtype);
}
while (err == 0 || err == -EWOULDBLOCK);
__set_errno (-err);
return -1;
}
compat_symbol (libpthread, __old_sem_wait, sem_wait, GLIBC_2_0);
#endif

View File

@ -29,19 +29,51 @@
int
__new_sem_post (sem_t *sem)
{
int *futex = (int *) sem, nr;
struct sparc_new_sem *isem = (struct sparc_new_sem *) sem;
int nr;
if (__atomic_is_v9)
nr = atomic_increment_val (futex);
nr = atomic_increment_val (&isem->value);
else
{
__sparc32_atomic_do_lock24 (futex + 1);
nr = ++*futex;
__sparc32_atomic_do_unlock24 (futex + 1);
__sparc32_atomic_do_lock24 (&isem->lock);
nr = ++(isem->value);
__sparc32_atomic_do_unlock24 (&isem->lock);
}
int err = lll_futex_wake (futex, nr,
// XYZ check mutex flag
LLL_SHARED);
atomic_full_barrier ();
if (isem->nwaiters > 0)
{
int err = lll_futex_wake (&isem->value, 1,
isem->private ^ FUTEX_PRIVATE_FLAG);
if (__builtin_expect (err, 0) < 0)
{
__set_errno (-err);
return -1;
}
}
return 0;
}
versioned_symbol (libpthread, __new_sem_post, sem_post, GLIBC_2_1);
#if SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_1)
int
attribute_compat_text_section
__old_sem_post (sem_t *sem)
{
struct sparc_old_sem *isem = (struct sparc_old_sem *) sem;
int nr;
if (__atomic_is_v9)
nr = atomic_increment_val (&isem->value);
else
{
__sparc32_atomic_do_lock24 (&isem->lock);
nr = ++(isem->value);
__sparc32_atomic_do_unlock24 (&isem->lock);
}
int err = lll_futex_wake (&isem->value, 1,
isem->private ^ FUTEX_PRIVATE_FLAG);
if (__builtin_expect (err, 0) < 0)
{
__set_errno (-err);
@ -49,8 +81,5 @@ __new_sem_post (sem_t *sem)
}
return 0;
}
versioned_symbol (libpthread, __new_sem_post, sem_post, GLIBC_2_1);
#if SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_1)
strong_alias (__new_sem_post, __old_sem_post)
compat_symbol (libpthread, __old_sem_post, sem_post, GLIBC_2_0);
#endif

View File

@ -1,5 +1,5 @@
/* sem_timedwait -- wait on a semaphore. SPARC version.
Copyright (C) 2003, 2006 Free Software Foundation, Inc.
Copyright (C) 2003, 2006, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Paul Mackerras <paulus@au.ibm.com>, 2003.
@ -28,37 +28,48 @@
#include <shlib-compat.h>
extern void __sem_wait_cleanup (void *arg) attribute_hidden;
int
sem_timedwait (sem_t *sem, const struct timespec *abstime)
{
/* First check for cancellation. */
CANCELLATION_P (THREAD_SELF);
int *futex = (int *) sem;
int val;
struct sparc_new_sem *isem = (struct sparc_new_sem *) sem;
int err;
int val;
if (*futex > 0)
if (__atomic_is_v9)
val = atomic_decrement_if_positive (&isem->value);
else
{
if (__atomic_is_v9)
val = atomic_decrement_if_positive (futex);
else
{
__sparc32_atomic_do_lock24 (futex + 1);
val = *futex;
if (val > 0)
*futex = val - 1;
__sparc32_atomic_do_unlock24 (futex + 1);
}
__sparc32_atomic_do_lock24 (&isem->lock);
val = isem->value;
if (val > 0)
return 0;
isem->value = val - 1;
__sparc32_atomic_do_unlock24 (&isem->lock);
}
err = -EINVAL;
if (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)
goto error_return;
if (val > 0)
return 0;
do
if (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)
{
__set_errno (EINVAL);
return -1;
}
if (__atomic_is_v9)
atomic_increment (&isem->nwaiters);
else
{
__sparc32_atomic_do_lock24 (&isem->lock);
isem->nwaiters++;
__sparc32_atomic_do_unlock24 (&isem->lock);
}
pthread_cleanup_push (__sem_wait_cleanup, isem);
while (1)
{
struct timeval tv;
struct timespec rt;
@ -79,7 +90,11 @@ sem_timedwait (sem_t *sem, const struct timespec *abstime)
/* Already timed out? */
err = -ETIMEDOUT;
if (sec < 0)
goto error_return;
{
__set_errno (ETIMEDOUT);
err = -1;
break;
}
/* Do wait. */
rt.tv_sec = sec;
@ -88,30 +103,47 @@ sem_timedwait (sem_t *sem, const struct timespec *abstime)
/* Enable asynchronous cancellation. Required by the standard. */
int oldtype = __pthread_enable_asynccancel ();
err = lll_futex_timed_wait (futex, 0, &rt);
err = lll_futex_timed_wait (&isem->value, 0, &rt,
isem->private ^ FUTEX_PRIVATE_FLAG);
/* Disable asynchronous cancellation. */
__pthread_disable_asynccancel (oldtype);
if (err != 0 && err != -EWOULDBLOCK)
goto error_return;
{
__set_errno (-err);
err = -1;
break;
}
if (__atomic_is_v9)
val = atomic_decrement_if_positive (futex);
val = atomic_decrement_if_positive (&isem->value);
else
{
__sparc32_atomic_do_lock24 (futex + 1);
val = *futex;
__sparc32_atomic_do_lock24 (&isem->lock);
val = isem->value;
if (val > 0)
*futex = val - 1;
__sparc32_atomic_do_unlock24 (futex + 1);
isem->value = val - 1;
__sparc32_atomic_do_unlock24 (&isem->lock);
}
if (val > 0)
{
err = 0;
break;
}
}
while (val <= 0);
return 0;
pthread_cleanup_pop (0);
error_return:
__set_errno (-err);
return -1;
if (__atomic_is_v9)
atomic_decrement (&isem->nwaiters);
else
{
__sparc32_atomic_do_lock24 (&isem->lock);
isem->nwaiters--;
__sparc32_atomic_do_unlock24 (&isem->lock);
}
return err;
}

View File

@ -1,5 +1,5 @@
/* sem_trywait -- wait on a semaphore. SPARC version.
Copyright (C) 2003, 2006 Free Software Foundation, Inc.
Copyright (C) 2003, 2006, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Paul Mackerras <paulus@au.ibm.com>, 2003.
@ -30,20 +30,20 @@
int
__new_sem_trywait (sem_t *sem)
{
int *futex = (int *) sem;
struct sparc_old_sem *isem = (struct sparc_old_sem *) sem;
int val;
if (*futex > 0)
if (isem->value > 0)
{
if (__atomic_is_v9)
val = atomic_decrement_if_positive (futex);
val = atomic_decrement_if_positive (&isem->value);
else
{
__sparc32_atomic_do_lock24 (futex + 1);
val = *futex;
__sparc32_atomic_do_lock24 (&isem->lock);
val = isem->value;
if (val > 0)
*futex = val - 1;
__sparc32_atomic_do_unlock24 (futex + 1);
isem->value = val - 1;
__sparc32_atomic_do_unlock24 (&isem->lock);
}
if (val > 0)
return 0;

View File

@ -1,5 +1,5 @@
/* sem_wait -- wait on a semaphore. SPARC version.
Copyright (C) 2003, 2006 Free Software Foundation, Inc.
/* sem_wait -- wait on a semaphore. Generic futex-using version.
Copyright (C) 2003, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Paul Mackerras <paulus@au.ibm.com>, 2003.
@ -28,35 +28,135 @@
#include <shlib-compat.h>
void
attribute_hidden
__sem_wait_cleanup (void *arg)
{
struct sparc_new_sem *isem = (struct sparc_new_sem *) arg;
if (__atomic_is_v9)
atomic_decrement (&isem->nwaiters);
else
{
__sparc32_atomic_do_lock24 (&isem->lock);
isem->nwaiters--;
__sparc32_atomic_do_unlock24 (&isem->lock);
}
}
int
__new_sem_wait (sem_t *sem)
{
/* First check for cancellation. */
CANCELLATION_P (THREAD_SELF);
int *futex = (int *) sem;
struct sparc_new_sem *isem = (struct sparc_new_sem *) sem;
int err;
int val;
if (__atomic_is_v9)
val = atomic_decrement_if_positive (&isem->value);
else
{
__sparc32_atomic_do_lock24 (&isem->lock);
val = isem->value;
if (val > 0)
isem->value = val - 1;
else
isem->nwaiters++;
__sparc32_atomic_do_unlock24 (&isem->lock);
}
if (val > 0)
return 0;
if (__atomic_is_v9)
atomic_increment (&isem->nwaiters);
else
/* Already done above while still holding isem->lock. */;
pthread_cleanup_push (__sem_wait_cleanup, isem);
while (1)
{
/* Enable asynchronous cancellation. Required by the standard. */
int oldtype = __pthread_enable_asynccancel ();
err = lll_futex_wait (&isem->value, 0,
isem->private ^ FUTEX_PRIVATE_FLAG);
/* Disable asynchronous cancellation. */
__pthread_disable_asynccancel (oldtype);
if (err != 0 && err != -EWOULDBLOCK)
{
__set_errno (-err);
err = -1;
break;
}
if (__atomic_is_v9)
val = atomic_decrement_if_positive (&isem->value);
else
{
__sparc32_atomic_do_lock24 (&isem->lock);
val = isem->value;
if (val > 0)
isem->value = val - 1;
__sparc32_atomic_do_unlock24 (&isem->lock);
}
if (val > 0)
{
err = 0;
break;
}
}
pthread_cleanup_pop (0);
if (__atomic_is_v9)
atomic_decrement (&isem->nwaiters);
else
{
__sparc32_atomic_do_lock24 (&isem->lock);
isem->nwaiters--;
__sparc32_atomic_do_unlock24 (&isem->lock);
}
return err;
}
versioned_symbol (libpthread, __new_sem_wait, sem_wait, GLIBC_2_1);
#if SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_1)
int
attribute_compat_text_section
__old_sem_wait (sem_t *sem)
{
struct sparc_old_sem *isem = (struct sparc_old_sem *) sem;
int err;
int val;
do
{
int val;
if (__atomic_is_v9)
val = atomic_decrement_if_positive (futex);
val = atomic_decrement_if_positive (&isem->value);
else
{
__sparc32_atomic_do_lock24 (futex + 1);
val = *futex;
__sparc32_atomic_do_lock24 (&isem->lock);
val = isem->value;
if (val > 0)
*futex = val - 1;
__sparc32_atomic_do_unlock24 (futex + 1);
isem->value = val - 1;
__sparc32_atomic_do_unlock24 (&isem->lock);
}
if (val > 0)
return 0;
/* Enable asynchronous cancellation. Required by the standard. */
int oldtype = __pthread_enable_asynccancel ();
err = lll_futex_wait (futex, 0);
err = lll_futex_wait (futex, 0,
isem->private ^ FUTEX_PRIVATE_FLAG);
/* Disable asynchronous cancellation. */
__pthread_disable_asynccancel (oldtype);
@ -67,8 +167,5 @@ __new_sem_wait (sem_t *sem)
return -1;
}
versioned_symbol (libpthread, __new_sem_wait, sem_wait, GLIBC_2_1);
#if SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_1)
strong_alias (__new_sem_wait, __old_sem_wait)
compat_symbol (libpthread, __old_sem_wait, sem_wait, GLIBC_2_0);
#endif

View File

@ -1 +0,0 @@
#include "../../../../../../../sem_init.c"

View File

@ -1 +1 @@
#include "../../../sem_post.c"
#include "../../sem_post.c"

View File

@ -1 +1 @@
#include "../../../sem_timedwait.c"
#include "../../sem_timedwait.c"

View File

@ -1 +1 @@
#include "../../../sem_wait.c"
#include "../../sem_wait.c"

View File

@ -1,5 +1,5 @@
/* Store current floating-point environment and clear exceptions.
Copyright (C) 1997, 1998, 2005 Free Software Foundation, Inc.
Copyright (C) 1997, 1998, 2005, 2007 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
@ -26,8 +26,8 @@ feholdexcept (fenv_t *envp)
__fenv_stfsr (*envp);
/* Set all exceptions to non-stop. */
tmp = *envp & ~(0x1f << 23);
/* Set all exceptions to non-stop and clear all exceptions. */
tmp = *envp & ~((0x1f << 23) | FE_ALL_EXCEPT);
__fenv_ldfsr (tmp);

View File

@ -1,5 +1,5 @@
/* Raise given exceptions.
Copyright (C) 1997, 1999, 2000, 2002 Free Software Foundation, Inc.
Copyright (C) 1997, 1999, 2000, 2002, 2007 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
@ -26,9 +26,9 @@ int
__feraiseexcept (int excepts)
{
static const struct {
double zero, one, max, min, sixteen, pi;
double zero, one, max, min, pi;
} c = {
0.0, 1.0, DBL_MAX, DBL_MIN, 16.0, M_PI
0.0, 1.0, DBL_MAX, DBL_MIN, M_PI
};
double d;
@ -66,7 +66,7 @@ __feraiseexcept (int excepts)
if ((FE_UNDERFLOW & excepts) != 0)
{
__asm ("" : "=e" (d) : "0" (c.min));
d /= c.sixteen;
d *= d;
__asm __volatile ("" : : "e" (d));
}