aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortegge <tegge@FreeBSD.org>2006-01-24 09:05:01 +0800
committertegge <tegge@FreeBSD.org>2006-01-24 09:05:01 +0800
commit7a9c86cda56dbc669b48966ed77c79c22939ed2c (patch)
tree554ea3ef1382fc4722a5ee87fb55906de44caa58
parent69c82e6a26880d3ecfb0771cc2aa437b185dedd3 (diff)
downloadfreebsd-ports-gnome-7a9c86cda56dbc669b48966ed77c79c22939ed2c.tar.gz
freebsd-ports-gnome-7a9c86cda56dbc669b48966ed77c79c22939ed2c.tar.zst
freebsd-ports-gnome-7a9c86cda56dbc669b48966ed77c79c22939ed2c.zip
Backport 2002-04-24 fix from newer linuxthreads versions to avoid hangs
or busy wait loop due to race between timeout and pthread_cond_signal.
-rw-r--r--devel/linuxthreads/Makefile2
-rw-r--r--devel/linuxthreads/files/patch-spinlock.c59
2 files changed, 60 insertions, 1 deletions
diff --git a/devel/linuxthreads/Makefile b/devel/linuxthreads/Makefile
index a2017ee7adea..b13fa99e8379 100644
--- a/devel/linuxthreads/Makefile
+++ b/devel/linuxthreads/Makefile
@@ -7,7 +7,7 @@
PORTNAME= linuxthreads
PORTVERSION= 2.2.3
-PORTREVISION= 19
+PORTREVISION= 20
CATEGORIES= devel
MASTER_SITES= ${MASTER_SITE_GNU}
MASTER_SITE_SUBDIR= glibc
diff --git a/devel/linuxthreads/files/patch-spinlock.c b/devel/linuxthreads/files/patch-spinlock.c
new file mode 100644
index 000000000000..56e74ed9530d
--- /dev/null
+++ b/devel/linuxthreads/files/patch-spinlock.c
@@ -0,0 +1,59 @@
+--- spinlock.c.orig Tue Mar 27 04:52:56 2001
++++ spinlock.c Tue Jan 10 09:44:39 2006
+@@ -72,8 +72,6 @@
+ #endif
+
+ #if defined HAS_COMPARE_AND_SWAP
+-again:
+-
+ /* On SMP, try spinning to get the lock. */
+
+ if (__pthread_smp_kernel) {
+@@ -94,6 +92,8 @@
+ lock->__spinlock += (spin_count - lock->__spinlock) / 8;
+ }
+
++again:
++
+ /* No luck, try once more or suspend. */
+
+ do {
+@@ -110,7 +110,7 @@
+ }
+
+ if (self != NULL) {
+- THREAD_SETMEM(self, p_nextlock, (pthread_descr) (oldstatus & ~1L));
++ THREAD_SETMEM(self, p_nextlock, (pthread_descr) oldstatus);
+ /* Make sure the store in p_nextlock completes before performing
+ the compare-and-swap */
+ MEMORY_BARRIER();
+@@ -188,7 +188,7 @@
+ multiprocessor Alphas) could perform such reordering even though
+ the loads are dependent. */
+ READ_MEMORY_BARRIER();
+- thr = *ptr;
++ thr = (pthread_descr)((long)(thr->p_nextlock) & ~1L);
+ }
+ /* Prevent reordering of the load of lock->__status above and
+ thr->p_nextlock below */
+@@ -198,17 +198,16 @@
+ /* If max prio thread is at head, remove it with compare-and-swap
+ to guard against concurrent lock operation. This removal
+ also has the side effect of marking the lock as released
+- because the new status comes from thr->p_nextlock whose
+- least significant bit is clear. */
++ by clearing the least significant bit. */
+ thr = (pthread_descr) (oldstatus & ~1L);
+ if (! __compare_and_swap_with_release_semantics
+- (&lock->__status, oldstatus, (long)(thr->p_nextlock)))
++ (&lock->__status, oldstatus, (long)(thr->p_nextlock) & ~1L))
+ goto again;
+ } else {
+ /* No risk of concurrent access, remove max prio thread normally.
+ But in this case we must also flip the least significant bit
+ of the status to mark the lock as released. */
+- thr = *maxptr;
++ thr = (pthread_descr)((long)*maxptr & ~1L);
+ *maxptr = thr->p_nextlock;
+
+ do {