[PARISC] Only write to memory in test_and_set_bit/test_and_clear_bit if we're
authorMatthew Wilcox <matthew@wil.cx>
Thu, 14 Dec 2006 16:00:25 +0000 (09:00 -0700)
committerKyle McMartin <kyle@athena.road.mcmartin.ca>
Sat, 17 Feb 2007 05:43:03 +0000 (00:43 -0500)
going to change the bit.

Signed-off-by: Matthew Wilcox <matthew@wil.cx>
Signed-off-by: Kyle McMartin <kyle@parisc-linux.org>
include/asm-parisc/bitops.h

index 900561922c4c26c5786e16625f510c5cfaf397f3..9577342f21aa26eda72d98553426c2e153102010 100644 (file)
@@ -60,31 +60,37 @@ static __inline__ void change_bit(int nr, volatile unsigned long * addr)
 static __inline__ int test_and_set_bit(int nr, volatile unsigned long * addr)
 {
        unsigned long mask = 1UL << CHOP_SHIFTCOUNT(nr);
-       unsigned long oldbit;
+       unsigned long old;
        unsigned long flags;
+       int set;
 
        addr += (nr >> SHIFT_PER_LONG);
        _atomic_spin_lock_irqsave(addr, flags);
-       oldbit = *addr;
-       *addr = oldbit | mask;
+       old = *addr;
+       set = (old & mask) ? 1 : 0;
+       if (!set)
+               *addr = old | mask;
        _atomic_spin_unlock_irqrestore(addr, flags);
 
-       return (oldbit & mask) ? 1 : 0;
+       return set;
 }
 
 static __inline__ int test_and_clear_bit(int nr, volatile unsigned long * addr)
 {
        unsigned long mask = 1UL << CHOP_SHIFTCOUNT(nr);
-       unsigned long oldbit;
+       unsigned long old;
        unsigned long flags;
+       int set;
 
        addr += (nr >> SHIFT_PER_LONG);
        _atomic_spin_lock_irqsave(addr, flags);
-       oldbit = *addr;
-       *addr = oldbit & ~mask;
+       old = *addr;
+       set = (old & mask) ? 1 : 0;
+       if (set)
+               *addr = old & ~mask;
        _atomic_spin_unlock_irqrestore(addr, flags);
 
-       return (oldbit & mask) ? 1 : 0;
+       return set;
 }
 
 static __inline__ int test_and_change_bit(int nr, volatile unsigned long * addr)