Atomic or for ints (flag variables)
authorBarret Rhoden <brho@cs.berkeley.edu>
Mon, 14 Mar 2011 16:34:00 +0000 (09:34 -0700)
committerKevin Klues <klueska@cs.berkeley.edu>
Thu, 3 Nov 2011 00:36:00 +0000 (17:36 -0700)
kern/arch/i686/atomic.h
kern/arch/sparc/atomic.h

index 52edf56..a00d927 100644 (file)
@@ -31,6 +31,7 @@ static inline bool atomic_comp_swap(uint32_t *addr, uint32_t exp_val,
                                     uint32_t new_val);
 static inline void atomic_andb(volatile uint8_t RACY* number, uint8_t mask);
 static inline void atomic_orb(volatile uint8_t RACY* number, uint8_t mask);
+static inline void atomic_or_int(volatile int *number, int mask);
 static inline uint32_t spin_locked(spinlock_t *SAFE lock);
 static inline void __spin_lock(volatile uint32_t SRACY*CT(1) rlock);
 static inline void spin_lock(spinlock_t *lock);
@@ -140,6 +141,11 @@ static inline void atomic_orb(volatile uint8_t RACY*number, uint8_t mask)
        asm volatile("lock orb %1,%0" : "=m"(*number) : "q"(mask) : "cc");
 }
 
+static inline void atomic_or_int(volatile int *number, int mask)
+{
+       asm volatile("lock orl %1,%0" : "=m"(*number) : "q"(mask) : "cc");
+}
+
 static inline uint32_t spin_locked(spinlock_t *SAFE lock)
 {
        // the lock status is the lowest byte of the lock
index 550a2a3..db283cc 100644 (file)
@@ -34,6 +34,7 @@ static inline bool atomic_sub_and_test(atomic_t *number, long val);
 static inline uint32_t atomic_swap(uint32_t* addr, uint32_t val);
 static inline bool atomic_comp_swap(uint32_t *addr, uint32_t exp_val,
                                     uint32_t new_val);
+static inline void atomic_or_int(volatile int *number, int mask);
 static inline uint32_t spin_trylock(spinlock_t*SAFE lock);
 static inline uint32_t spin_locked(spinlock_t*SAFE lock);
 static inline void spin_lock(spinlock_t*SAFE lock);
@@ -151,6 +152,19 @@ static inline bool atomic_comp_swap(uint32_t *addr, uint32_t exp_val,
        return retval;
 }
 
+static inline void atomic_or_int(volatile int *number, int mask)
+{
+       int val;
+       /* this is pretty clever.  the lower 8 bits (i.e byte 3)
+        * of the atomic_t serve as a spinlock.  let's acquire it. */
+       spin_lock((spinlock_t*)number);
+       val = atomic_read((atomic_t*)number);
+       /* compute new counter value. */
+       val |= mask;
+       /* set the new counter value.  the lock is cleared (for free) */
+       atomic_init((atomic_t*)number, val);
+}
+
 static inline uint32_t spin_trylock(spinlock_t*SAFE lock)
 {
        uint32_t reg;