patch-2.3.99-pre6 linux/include/asm-i386/spinlock.h

Next file: linux/include/asm-i386/string.h
Previous file: linux/include/asm-i386/processor.h
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.3.99-pre5/linux/include/asm-i386/spinlock.h linux/include/asm-i386/spinlock.h
@@ -33,7 +33,7 @@
 #define SPINLOCK_MAGIC_INIT	/* */
 #endif
 
-#define SPIN_LOCK_UNLOCKED (spinlock_t) { 0 SPINLOCK_MAGIC_INIT }
+#define SPIN_LOCK_UNLOCKED (spinlock_t) { 1 SPINLOCK_MAGIC_INIT }
 
 #define spin_lock_init(x)	do { *(x) = SPIN_LOCK_UNLOCKED; } while(0)
 /*
@@ -43,32 +43,39 @@
  * We make no fairness assumptions. They have a cost.
  */
 
-#define spin_unlock_wait(x)	do { barrier(); } while(((volatile spinlock_t *)(x))->lock)
-#define spin_is_locked(x)	((x)->lock != 0)
+#define spin_is_locked(x)	(*(volatile char *)(&(x)->lock) <= 0)
+#define spin_unlock_wait(x)	do { barrier(); } while(spin_is_locked(x))
 
 #define spin_lock_string \
 	"\n1:\t" \
-	"lock ; btsl $0,%0\n\t" \
-	"jc 2f\n" \
+	"lock ; decb %0\n\t" \
+	"js 2f\n" \
 	".section .text.lock,\"ax\"\n" \
 	"2:\t" \
-	"testb $1,%0\n\t" \
+	"cmpb $0,%0\n\t" \
 	"rep;nop\n\t" \
-	"jne 2b\n\t" \
+	"jle 2b\n\t" \
 	"jmp 1b\n" \
 	".previous"
 
 /*
- * Sadly, some early PPro chips require the locked access,
- * otherwise we could just always simply do
- *
- * 	#define spin_unlock_string \
- *		"movb $0,%0"
- *
- * Which is noticeably faster.
+ * This works. Despite all the confusion.
  */
 #define spin_unlock_string \
-	"lock ; btrl $0,%0"
+	"movb $1,%0"
+
+/*
+ * Won't work on i386-SMP. Does anybody care?
+ */
+static inline int spin_trylock(spinlock_t *lock)
+{
+	char oldval;
+	__asm__ __volatile__(
+		"lock ; cmpxchg %b2,%1"
+		:"=a" (oldval), "=m" (__dummy_lock(lock))
+		:"q" (0), "0" (1));
+	return oldval > 0;
+}
 
 extern inline void spin_lock(spinlock_t *lock)
 {
@@ -90,15 +97,13 @@
 #if SPINLOCK_DEBUG
 	if (lock->magic != SPINLOCK_MAGIC)
 		BUG();
-	if (!lock->lock)
+	if (!spin_is_locked(lock))
 		BUG();
 #endif
 	__asm__ __volatile__(
 		spin_unlock_string
 		:"=m" (__dummy_lock(lock)));
 }
-
-#define spin_trylock(lock) ({ !test_and_set_bit(0,(lock)); })
 
 /*
  * Read-write spinlocks, allowing multiple readers

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)