[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[commits] r3162 - in /fsf/trunk/libc: ./ nptl/ nptl/sysdeps/unix/sysv/linux/sparc/ nptl/sysdeps/unix/sysv/linux/sparc/sparc32/ nptl/sy...



Author: eglibc
Date: Thu Aug 16 00:03:33 2007
New Revision: 3162

Log:
Import glibc-mainline for 2007-08-16

Added:
    fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/sparc/sem_init.c
    fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/sparc/sem_post.c
    fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/sparc/sem_timedwait.c
    fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/sparc/sem_wait.c
Removed:
    fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sem_init.c
    fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sparcv9/sem_init.c
Modified:
    fsf/trunk/libc/ChangeLog
    fsf/trunk/libc/nptl/ChangeLog
    fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/sparc/internaltypes.h
    fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sem_post.c
    fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sem_timedwait.c
    fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sem_trywait.c
    fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sem_wait.c
    fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sparcv9/sem_post.c
    fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sparcv9/sem_timedwait.c
    fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sparcv9/sem_wait.c
    fsf/trunk/libc/sysdeps/sparc/fpu/feholdexcpt.c
    fsf/trunk/libc/sysdeps/sparc/fpu/fraiseexcpt.c

Modified: fsf/trunk/libc/ChangeLog
==============================================================================
--- fsf/trunk/libc/ChangeLog (original)
+++ fsf/trunk/libc/ChangeLog Thu Aug 16 00:03:33 2007
@@ -1,3 +1,11 @@
+2007-08-15  Jakub Jelinek  <jakub@xxxxxxxxxx>
+
+	* 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@xxxxxxxxxx>
 
 	* sysdeps/sparc/sparc32/dl-machine.h (elf_machine_runtime_setup): No

Modified: fsf/trunk/libc/nptl/ChangeLog
==============================================================================
--- fsf/trunk/libc/nptl/ChangeLog (original)
+++ fsf/trunk/libc/nptl/ChangeLog Thu Aug 16 00:03:33 2007
@@ -1,3 +1,38 @@
+2007-08-15  Jakub Jelinek  <jakub@xxxxxxxxxx>
+
+	* 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@xxxxxxxxxxxxxx>
 
 	* sysdeps/unix/sysv/linux/sh/pthread_cond_broadcast.S

Modified: fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/sparc/internaltypes.h
==============================================================================
--- fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/sparc/internaltypes.h (original)
+++ fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/sparc/internaltypes.h Thu Aug 16 00:03:33 2007
@@ -15,4 +15,20 @@
     } 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

Added: fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/sparc/sem_init.c
==============================================================================
--- fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/sparc/sem_init.c (added)
+++ fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/sparc/sem_init.c Thu Aug 16 00:03:33 2007
@@ -1,0 +1,93 @@
+/* Copyright (C) 2002, 2007 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@xxxxxxxxxx>, 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 <errno.h>
+#include <string.h>
+#include <semaphore.h>
+#include <lowlevellock.h>
+#include <shlib-compat.h>
+#include "semaphoreP.h"
+#include <kernel-features.h>
+
+
+int
+__new_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_new_sem *isem = (struct sparc_new_sem *) sem;
+
+  /* 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)
+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

Added: fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/sparc/sem_post.c
==============================================================================
--- fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/sparc/sem_post.c (added)
+++ fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/sparc/sem_post.c Thu Aug 16 00:03:33 2007
@@ -1,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@xxxxxxxxxx>, 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

Added: fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/sparc/sem_timedwait.c
==============================================================================
--- fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/sparc/sem_timedwait.c (added)
+++ fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/sparc/sem_timedwait.c Thu Aug 16 00:03:33 2007
@@ -1,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@xxxxxxxxxx>, 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;
+}

Added: fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/sparc/sem_wait.c
==============================================================================
--- fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/sparc/sem_wait.c (added)
+++ fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/sparc/sem_wait.c Thu Aug 16 00:03:33 2007
@@ -1,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@xxxxxxxxxx>, 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

Modified: fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sem_post.c
==============================================================================
--- fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sem_post.c (original)
+++ fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sem_post.c Thu Aug 16 00:03:33 2007
@@ -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 @@
     }
   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

Modified: fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sem_timedwait.c
==============================================================================
--- fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sem_timedwait.c (original)
+++ fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sem_timedwait.c Thu Aug 16 00:03:33 2007
@@ -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@xxxxxxxxxx>, 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);
+  struct sparc_new_sem *isem = (struct sparc_new_sem *) sem;
+  int err;
+  int val;
 
-  int *futex = (int *) sem;
-  int val;
-  int err;
-
-  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 (val > 0)
+    return 0;
+
   if (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)
-    goto error_return;
+    {
+      __set_errno (EINVAL);
+      return -1;
+    }
 
-  do
+  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 @@
       /* 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 @@
       /* 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;
 }

Modified: fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sem_trywait.c
==============================================================================
--- fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sem_trywait.c (original)
+++ fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sem_trywait.c Thu Aug 16 00:03:33 2007
@@ -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@xxxxxxxxxx>, 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;

Modified: fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sem_wait.c
==============================================================================
--- fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sem_wait.c (original)
+++ fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sem_wait.c Thu Aug 16 00:03:33 2007
@@ -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@xxxxxxxxxx>, 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);
+  struct sparc_new_sem *isem = (struct sparc_new_sem *) sem;
+  int err;
+  int val;
 
-  int *futex = (int *) sem;
+  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 @@
   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

Modified: fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sparcv9/sem_post.c
==============================================================================
--- fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sparcv9/sem_post.c (original)
+++ fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sparcv9/sem_post.c Thu Aug 16 00:03:33 2007
@@ -1,1 +1,1 @@
-#include "../../../sem_post.c"
+#include "../../sem_post.c"

Modified: fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sparcv9/sem_timedwait.c
==============================================================================
--- fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sparcv9/sem_timedwait.c (original)
+++ fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sparcv9/sem_timedwait.c Thu Aug 16 00:03:33 2007
@@ -1,1 +1,1 @@
-#include "../../../sem_timedwait.c"
+#include "../../sem_timedwait.c"

Modified: fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sparcv9/sem_wait.c
==============================================================================
--- fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sparcv9/sem_wait.c (original)
+++ fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sparcv9/sem_wait.c Thu Aug 16 00:03:33 2007
@@ -1,1 +1,1 @@
-#include "../../../sem_wait.c"
+#include "../../sem_wait.c"

Modified: fsf/trunk/libc/sysdeps/sparc/fpu/feholdexcpt.c
==============================================================================
--- fsf/trunk/libc/sysdeps/sparc/fpu/feholdexcpt.c (original)
+++ fsf/trunk/libc/sysdeps/sparc/fpu/feholdexcpt.c Thu Aug 16 00:03:33 2007
@@ -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 @@
 
   __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);
 

Modified: fsf/trunk/libc/sysdeps/sparc/fpu/fraiseexcpt.c
==============================================================================
--- fsf/trunk/libc/sysdeps/sparc/fpu/fraiseexcpt.c (original)
+++ fsf/trunk/libc/sysdeps/sparc/fpu/fraiseexcpt.c Thu Aug 16 00:03:33 2007
@@ -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 @@
 __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 @@
   if ((FE_UNDERFLOW & excepts) != 0)
     {
       __asm ("" : "=e" (d) : "0" (c.min));
-      d /= c.sixteen;
+      d *= d;
       __asm __volatile ("" : : "e" (d));
     }