aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--linuxthreads/ChangeLog9
-rw-r--r--linuxthreads/internals.h7
-rw-r--r--linuxthreads/spinlock.c6
-rw-r--r--linuxthreads/sysdeps/i386/i686/pt-machine.h3
4 files changed, 25 insertions, 0 deletions
diff --git a/linuxthreads/ChangeLog b/linuxthreads/ChangeLog
index 1ce5a23186..b85f8c94df 100644
--- a/linuxthreads/ChangeLog
+++ b/linuxthreads/ChangeLog
@@ -1,3 +1,12 @@
+2001-08-29 Ulrich Drepper <drepper@redhat.com>
+
+ * spinlock.c (__pthread_lock): Top max_count value with
+ MAX_ADAPTIVE_SPIN_COUNT.
+ * internals.h (MAX_ADAPTIVE_SPIN_COUNT): Define if not already done.
+
+ * sysdeps/i386/i686/pt-machine.h (BUSY_WAIT_NOP): New macro to
+ help P4.
+
2001-08-27 Jakub Jelinek <jakub@redhat.com>
* sysdeps/pthread/bits/libc-lock.h (__libc_rwlock_t): Only define to
diff --git a/linuxthreads/internals.h b/linuxthreads/internals.h
index d5b469b347..ae49266278 100644
--- a/linuxthreads/internals.h
+++ b/linuxthreads/internals.h
@@ -414,6 +414,13 @@ static inline pthread_descr thread_self (void)
#define MAX_SPIN_COUNT 50
#endif
+/* Max number of times the spinlock in the adaptive mutex implementation
+ spins actively on SMP systems. */
+
+#ifndef MAX_ADAPTIVE_SPIN_COUNT
+#define MAX_ADAPTIVE_SPIN_COUNT 100
+#endif
+
/* Duration of sleep (in nanoseconds) when we can't acquire a spinlock
after MAX_SPIN_COUNT iterations of sched_yield().
With the 2.0 and 2.1 kernels, this MUST BE > 2ms.
diff --git a/linuxthreads/spinlock.c b/linuxthreads/spinlock.c
index 199386a4fc..3e16825997 100644
--- a/linuxthreads/spinlock.c
+++ b/linuxthreads/spinlock.c
@@ -94,6 +94,9 @@ again:
if (__pthread_smp_kernel) {
int max_count = lock->__spinlock * 2 + 10;
+ if (max_count > MAX_ADAPTIVE_SPIN_COUNT)
+ max_count = MAX_ADAPTIVE_SPIN_COUNT;
+
for (spin_count = 0; spin_count < max_count; spin_count++) {
if (((oldstatus = lock->__status) & 1) == 0) {
if(__compare_and_swap(&lock->__status, oldstatus, oldstatus | 1))
@@ -104,6 +107,9 @@ again:
return;
}
}
+#ifdef BUSY_WAIT_NOP
+ BUSY_WAIT_NOP;
+#endif
__asm __volatile ("" : "=m" (lock->__status) : "0" (lock->__status));
}
diff --git a/linuxthreads/sysdeps/i386/i686/pt-machine.h b/linuxthreads/sysdeps/i386/i686/pt-machine.h
index 7df3e7e487..c7396024bb 100644
--- a/linuxthreads/sysdeps/i386/i686/pt-machine.h
+++ b/linuxthreads/sysdeps/i386/i686/pt-machine.h
@@ -64,3 +64,6 @@ __compare_and_swap (long int *p, long int oldval, long int newval)
#if __ASSUME_LDT_WORKS > 0
#include "../useldt.h"
#endif
+
+/* The P4 and above really want some help to prevent overheating. */
+#define BUSY_WAIT_NOP __asm__ ("rep; nop")