vserver 1.9.3
[linux-2.6.git] / include / asm-i386 / spinlock.h
index 8bd4f23..89ad2d7 100644 (file)
@@ -42,19 +42,33 @@ typedef struct {
 
 #define spin_is_locked(x)      (*(volatile signed char *)(&(x)->lock) <= 0)
 #define spin_unlock_wait(x)    do { barrier(); } while(spin_is_locked(x))
-#define _raw_spin_lock_flags(lock, flags) _raw_spin_lock(lock)
 
 #define spin_lock_string \
        "\n1:\t" \
        "lock ; decb %0\n\t" \
-       "js 2f\n" \
-       LOCK_SECTION_START("") \
+       "jns 3f\n" \
        "2:\t" \
        "rep;nop\n\t" \
        "cmpb $0,%0\n\t" \
        "jle 2b\n\t" \
        "jmp 1b\n" \
-       LOCK_SECTION_END
+       "3:\n\t"
+
+#define spin_lock_string_flags \
+       "\n1:\t" \
+       "lock ; decb %0\n\t" \
+       "jns 4f\n\t" \
+       "2:\t" \
+       "testl $0x200, %1\n\t" \
+       "jz 3f\n\t" \
+       "sti\n\t" \
+       "3:\t" \
+       "rep;nop\n\t" \
+       "cmpb $0, %0\n\t" \
+       "jle 3b\n\t" \
+       "cli\n\t" \
+       "jmp 1b\n" \
+       "4:\n\t"
 
 /*
  * This works. Despite all the confusion.
@@ -114,10 +128,8 @@ static inline int _raw_spin_trylock(spinlock_t *lock)
 static inline void _raw_spin_lock(spinlock_t *lock)
 {
 #ifdef CONFIG_DEBUG_SPINLOCK
-       __label__ here;
-here:
        if (unlikely(lock->magic != SPINLOCK_MAGIC)) {
-               printk("eip: %p\n", &&here);
+               printk("eip: %p\n", __builtin_return_address(0));
                BUG();
        }
 #endif
@@ -126,6 +138,18 @@ here:
                :"=m" (lock->lock) : : "memory");
 }
 
+static inline void _raw_spin_lock_flags (spinlock_t *lock, unsigned long flags)
+{
+#ifdef CONFIG_DEBUG_SPINLOCK
+       if (unlikely(lock->magic != SPINLOCK_MAGIC)) {
+               printk("eip: %p\n", __builtin_return_address(0));
+               BUG();
+       }
+#endif
+       __asm__ __volatile__(
+               spin_lock_string_flags
+               :"=m" (lock->lock) : "r" (flags) : "memory");
+}
 
 /*
  * Read-write spinlocks, allowing multiple readers