[Glibc-bsd-commits] r4569 - trunk/glibc-ports/kfreebsd/fbtl

Petr Salinger ps-guest at alioth.debian.org
Mon Jul 8 12:42:48 UTC 2013


Author: ps-guest
Date: 2013-06-22 08:38:54 +0000 (Sat, 22 Jun 2013)
New Revision: 4569

Added:
   trunk/glibc-ports/kfreebsd/fbtl/sem_post.c
   trunk/glibc-ports/kfreebsd/fbtl/sem_timedwait.c
   trunk/glibc-ports/kfreebsd/fbtl/sem_trywait.c
   trunk/glibc-ports/kfreebsd/fbtl/sem_wait.c
   trunk/glibc-ports/kfreebsd/fbtl/structsem.sym
   trunk/glibc-ports/kfreebsd/fbtl/unwindbuf.sym
Log:
semaphores from nptl/linux


Added: trunk/glibc-ports/kfreebsd/fbtl/sem_post.c
===================================================================
--- trunk/glibc-ports/kfreebsd/fbtl/sem_post.c	                        (rev 0)
+++ trunk/glibc-ports/kfreebsd/fbtl/sem_post.c	2013-06-22 08:38:54 UTC (rev 4569)
@@ -0,0 +1,80 @@
+/* sem_post -- post to a POSIX semaphore.  Generic futex-using version.
+   Copyright (C) 2003-2013 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Jakub Jelinek <jakub at 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, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <atomic.h>
+#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 new_sem *isem = (struct new_sem *) sem;
+
+  __typeof (isem->value) cur;
+  do
+    {
+      cur = isem->value;
+      if (isem->value == SEM_VALUE_MAX)
+	{
+	  __set_errno (EOVERFLOW);
+	  return -1;
+	}
+    }
+  while (atomic_compare_and_exchange_bool_rel (&isem->value, cur + 1, cur));
+
+  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)
+{
+  int *futex = (int *) sem;
+
+  (void) atomic_increment_val (futex);
+  /* We always have to assume it is a shared semaphore.  */
+  int err = lll_futex_wake (futex, 1, LLL_SHARED);
+  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: trunk/glibc-ports/kfreebsd/fbtl/sem_timedwait.c
===================================================================
--- trunk/glibc-ports/kfreebsd/fbtl/sem_timedwait.c	                        (rev 0)
+++ trunk/glibc-ports/kfreebsd/fbtl/sem_timedwait.c	2013-06-22 08:38:54 UTC (rev 4569)
@@ -0,0 +1,116 @@
+/* sem_timedwait -- wait on a semaphore.  Generic futex-using version.
+   Copyright (C) 2003-2013 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Paul Mackerras <paulus at 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, see
+   <http://www.gnu.org/licenses/>.  */
+
+#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;
+
+/* This is in a seperate function in order to make sure gcc
+   puts the call site into an exception region, and thus the
+   cleanups get properly run.  */
+static int
+__attribute__ ((noinline))
+do_futex_timed_wait (struct new_sem *isem, struct timespec *rt)
+{
+  int err, oldtype = __pthread_enable_asynccancel ();
+
+  err = lll_futex_timed_wait (&isem->value, 0, rt,
+			      isem->private ^ FUTEX_PRIVATE_FLAG);
+
+  __pthread_disable_asynccancel (oldtype);
+  return err;
+}
+
+int
+sem_timedwait (sem_t *sem, const struct timespec *abstime)
+{
+  struct new_sem *isem = (struct 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?  */
+      if (sec < 0)
+	{
+	  __set_errno (ETIMEDOUT);
+	  err = -1;
+	  break;
+	}
+
+      /* Do wait.  */
+      rt.tv_sec = sec;
+      rt.tv_nsec = nsec;
+      err = do_futex_timed_wait(isem, &rt);
+      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: trunk/glibc-ports/kfreebsd/fbtl/sem_trywait.c
===================================================================
--- trunk/glibc-ports/kfreebsd/fbtl/sem_trywait.c	                        (rev 0)
+++ trunk/glibc-ports/kfreebsd/fbtl/sem_trywait.c	2013-06-22 08:38:54 UTC (rev 4569)
@@ -0,0 +1,49 @@
+/* sem_trywait -- wait on a semaphore.  Generic futex-using version.
+   Copyright (C) 2003-2013 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Paul Mackerras <paulus at 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, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <errno.h>
+#include <sysdep.h>
+#include <lowlevellock.h>
+#include <internaltypes.h>
+#include <semaphore.h>
+
+#include <shlib-compat.h>
+
+
+int
+__new_sem_trywait (sem_t *sem)
+{
+  int *futex = (int *) sem;
+  int val;
+
+  if (*futex > 0)
+    {
+      val = atomic_decrement_if_positive (futex);
+      if (val > 0)
+	return 0;
+    }
+
+  __set_errno (EAGAIN);
+  return -1;
+}
+versioned_symbol (libpthread, __new_sem_trywait, sem_trywait, GLIBC_2_1);
+#if SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_1)
+strong_alias (__new_sem_trywait, __old_sem_trywait)
+compat_symbol (libpthread, __old_sem_trywait, sem_trywait, GLIBC_2_0);
+#endif

Added: trunk/glibc-ports/kfreebsd/fbtl/sem_wait.c
===================================================================
--- trunk/glibc-ports/kfreebsd/fbtl/sem_wait.c	                        (rev 0)
+++ trunk/glibc-ports/kfreebsd/fbtl/sem_wait.c	2013-06-22 08:38:54 UTC (rev 4569)
@@ -0,0 +1,122 @@
+/* sem_wait -- wait on a semaphore.  Generic futex-using version.
+   Copyright (C) 2003-2013 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Paul Mackerras <paulus at 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, see
+   <http://www.gnu.org/licenses/>.  */
+
+#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 new_sem *isem = (struct new_sem *) arg;
+
+  atomic_decrement (&isem->nwaiters);
+}
+
+/* This is in a seperate function in order to make sure gcc
+   puts the call site into an exception region, and thus the
+   cleanups get properly run.  */
+static int
+__attribute__ ((noinline))
+do_futex_wait (struct new_sem *isem)
+{
+  int err, oldtype = __pthread_enable_asynccancel ();
+
+  err = lll_futex_wait (&isem->value, 0, isem->private ^ FUTEX_PRIVATE_FLAG);
+
+  __pthread_disable_asynccancel (oldtype);
+  return err;
+}
+
+int
+__new_sem_wait (sem_t *sem)
+{
+  struct new_sem *isem = (struct 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)
+    {
+      err = do_futex_wait(isem);
+      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)
+{
+  int *futex = (int *) sem;
+  int err;
+
+  do
+    {
+      if (atomic_decrement_if_positive (futex) > 0)
+	return 0;
+
+      /* Enable asynchronous cancellation.  Required by the standard.  */
+      int oldtype = __pthread_enable_asynccancel ();
+
+      /* Always assume the semaphore is shared.  */
+      err = lll_futex_wait (futex, 0, LLL_SHARED);
+
+      /* 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

Added: trunk/glibc-ports/kfreebsd/fbtl/structsem.sym
===================================================================
--- trunk/glibc-ports/kfreebsd/fbtl/structsem.sym	                        (rev 0)
+++ trunk/glibc-ports/kfreebsd/fbtl/structsem.sym	2013-06-22 08:38:54 UTC (rev 4569)
@@ -0,0 +1,12 @@
+#include <limits.h>
+#include <stddef.h>
+#include <sched.h>
+#include <bits/pthreadtypes.h>
+#include "internaltypes.h"
+
+--
+
+VALUE		offsetof (struct new_sem, value)
+PRIVATE		offsetof (struct new_sem, private)
+NWAITERS	offsetof (struct new_sem, nwaiters)
+SEM_VALUE_MAX	SEM_VALUE_MAX

Added: trunk/glibc-ports/kfreebsd/fbtl/unwindbuf.sym
===================================================================
--- trunk/glibc-ports/kfreebsd/fbtl/unwindbuf.sym	                        (rev 0)
+++ trunk/glibc-ports/kfreebsd/fbtl/unwindbuf.sym	2013-06-22 08:38:54 UTC (rev 4569)
@@ -0,0 +1,7 @@
+#include <pthread.h>
+#include <stddef.h>
+
+--
+
+UNWINDBUFSIZE	sizeof (__pthread_unwind_buf_t)
+UWJMPBUF	offsetof (__pthread_unwind_buf_t, __cancel_jmp_buf)




More information about the Glibc-bsd-commits mailing list