svn commit: [25780] branches/uClibc-nptl/libpthread/nptl/sysdeps/unix/sysv/linux: sparc
austinf at uclibc.org
austinf at uclibc.org
Sat Mar 21 20:42:08 UTC 2009
Author: austinf
Date: 2009-03-21 20:42:07 +0000 (Sat, 21 Mar 2009)
New Revision: 25780
Log:
sparc nptl needs it's own lowlevellock.c
* Since sparc < v9 doesn't have a real compare exchange instruction,
we implement it with a test and set.
Added:
branches/uClibc-nptl/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/libc-lowlevellock.c
branches/uClibc-nptl/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.c
Modified:
branches/uClibc-nptl/libpthread/nptl/sysdeps/unix/sysv/linux/Makefile.in
branches/uClibc-nptl/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/Makefile.arch
Changeset:
Modified: branches/uClibc-nptl/libpthread/nptl/sysdeps/unix/sysv/linux/Makefile.in
===================================================================
--- branches/uClibc-nptl/libpthread/nptl/sysdeps/unix/sysv/linux/Makefile.in 2009-03-21 19:58:58 UTC (rev 25779)
+++ branches/uClibc-nptl/libpthread/nptl/sysdeps/unix/sysv/linux/Makefile.in 2009-03-21 20:42:07 UTC (rev 25780)
@@ -49,8 +49,6 @@
endif
ifeq ($(TARGET_ARCH),sparc)
-libpthread_CSRC += lowlevellock.c
-libc_CSRC += libc-lowlevellock.c
librt_CSRC := mq_notify.c __syscall_error.c
endif
Modified: branches/uClibc-nptl/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/Makefile.arch
===================================================================
--- branches/uClibc-nptl/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/Makefile.arch 2009-03-21 19:58:58 UTC (rev 25779)
+++ branches/uClibc-nptl/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/Makefile.arch 2009-03-21 20:42:07 UTC (rev 25780)
@@ -6,12 +6,14 @@
#
libpthread_SSRC = pt-vfork.S clone.S
-libpthread_CSRC = pthread_once.c
+libpthread_CSRC = pthread_once.c lowlevellock.c
-libc_a_CSRC = fork.c
+libc_a_CSRC = fork.c libc-lowlevellock.c
libc_a_SSRC = clone.S vfork.S
CFLAGS-OMIT-fork.c = -DNOT_IN_libc=1 -DIS_IN_libpthread=1
+CFLAGS-OMIT-libc-lowlevellock.c = -DNOT_IN_libc=1 -DIS_IN_libpthread=1
+
ifeq ($(UCLIBC_HAS_STDIO_FUTEXES),y)
CFLAGS-fork.c = -D__USE_STDIO_FUTEXES__
endif
@@ -19,6 +21,7 @@
ASFLAGS-pt-vfork.S = -DNOT_IN_libc=1 -DIS_IN_libpthread=1 -D_LIBC_REENTRANT -DUSE___THREAD
CFLAGS-pthread_once.c = -DNOT_IN_libc=1 -DIS_IN_libpthread=1
+CFLAGS-lowlevellock.c = -DNOT_IN_libc=1 -DIS_IN_libpthread=1
ASFLAGS-clone.S = -D_LIBC_REENTRANT
Added: branches/uClibc-nptl/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/libc-lowlevellock.c
===================================================================
--- branches/uClibc-nptl/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/libc-lowlevellock.c (rev 0)
+++ branches/uClibc-nptl/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/libc-lowlevellock.c 2009-03-21 20:42:07 UTC (rev 25780)
@@ -0,0 +1,21 @@
+/* Copyright (C) 2003 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, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* No difference to lowlevellock.c, except we lose a couple of functions. */
+#include "lowlevellock.c"
Added: branches/uClibc-nptl/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.c
===================================================================
--- branches/uClibc-nptl/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.c (rev 0)
+++ branches/uClibc-nptl/libpthread/nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.c 2009-03-21 20:42:07 UTC (rev 25780)
@@ -0,0 +1,131 @@
+/* low level locking for pthread library. SPARC version.
+ Copyright (C) 2003, 2006, 2007 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, 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 <sys/time.h>
+
+
+/* These functions don't get included in libc.so */
+void
+__lll_lock_wait (int *futex)
+{
+ do
+ {
+ int oldval = atomic_compare_and_exchange_val_24_acq (futex, 2, 1);
+ if (oldval != 0)
+ lll_futex_wait (futex, 2);
+ }
+ while (atomic_compare_and_exchange_val_24_acq (futex, 2, 0) != 0);
+}
+
+
+#ifdef IS_IN_libpthread
+int
+__lll_timedlock_wait (int *futex, const struct timespec *abstime)
+{
+ /* Reject invalid timeouts. */
+ if (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)
+ return EINVAL;
+
+ do
+ {
+ struct timeval tv;
+ struct timespec rt;
+
+ /* Get the current time. */
+ (void) gettimeofday (&tv, NULL);
+
+ /* Compute relative timeout. */
+ rt.tv_sec = abstime->tv_sec - tv.tv_sec;
+ rt.tv_nsec = abstime->tv_nsec - tv.tv_usec * 1000;
+ if (rt.tv_nsec < 0)
+ {
+ rt.tv_nsec += 1000000000;
+ --rt.tv_sec;
+ }
+
+ /* Already timed out? */
+ if (rt.tv_sec < 0)
+ return ETIMEDOUT;
+
+ /* Wait. */
+ int oldval = atomic_compare_and_exchange_val_24_acq (futex, 2, 1);
+ if (oldval != 0)
+ lll_futex_timed_wait (futex, 2, &rt);
+ }
+ while (atomic_compare_and_exchange_val_24_acq (futex, 2, 0) != 0);
+
+ return 0;
+}
+
+int
+lll_unlock_wake_cb(int* futex)
+{
+ int val = atomic_exchange_24_rel(futex, 0);
+
+ if( __builtin_expect( val > 1, 0 ) ) {
+ lll_futex_wake( futex, 1 );
+ }
+
+ return 0;
+}
+
+
+int
+__lll_timedwait_tid (int *tidp, const struct timespec *abstime)
+{
+ int tid;
+
+ if (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)
+ return EINVAL;
+
+ /* Repeat until thread terminated. */
+ while ((tid = *tidp) != 0)
+ {
+ struct timeval tv;
+ struct timespec rt;
+
+ /* Get the current time. */
+ (void) gettimeofday (&tv, NULL);
+
+ /* Compute relative timeout. */
+ rt.tv_sec = abstime->tv_sec - tv.tv_sec;
+ rt.tv_nsec = abstime->tv_nsec - tv.tv_usec * 1000;
+ if (rt.tv_nsec < 0)
+ {
+ rt.tv_nsec += 1000000000;
+ --rt.tv_sec;
+ }
+
+ /* Already timed out? */
+ if (rt.tv_sec < 0)
+ return ETIMEDOUT;
+
+ /* Wait until thread terminates. The kernel so far does not use
+ the private futex operations for this. */
+ if (lll_futex_timed_wait (tidp, tid, &rt) == -ETIMEDOUT)
+ return ETIMEDOUT;
+ }
+
+ return 0;
+}
+#endif
More information about the uClibc-cvs
mailing list