perf: Fix buggy bitops
[akaros.git] / kern / include / atomic.h
index 11a9a69..e5d1d2d 100644 (file)
@@ -11,8 +11,7 @@
  *
  * The static inlines are defined farther down in the file (as always). */
 
-#ifndef ROS_KERN_ATOMIC_H
-#define ROS_KERN_ATOMIC_H
+#pragma once
 
 #include <ros/common.h>
 #include <ros/atomic.h>
@@ -101,6 +100,7 @@ static inline void spinlock_debug(spinlock_t *lock)
 static inline void spinlock_init(spinlock_t *lock);
 static inline void spinlock_init_irqsave(spinlock_t *lock);
 static inline void spin_lock_irqsave(spinlock_t *lock);
+static inline bool spin_trylock_irqsave(spinlock_t *lock);
 static inline void spin_unlock_irqsave(spinlock_t *lock);
 static inline bool spin_lock_irq_enabled(spinlock_t *lock);
 
@@ -275,6 +275,21 @@ static inline void spin_lock_irqsave(spinlock_t *lock)
                lock->rlock |= SPINLOCK_IRQ_EN;
 }
 
+static inline bool spin_trylock_irqsave(spinlock_t *lock)
+{
+       uint32_t irq_en = irq_is_enabled();
+
+       disable_irq();
+       if (!spin_trylock(lock)) {
+               if (irq_en)
+                       enable_irq();
+               return FALSE;
+       }
+       if (irq_en)
+               lock->rlock |= SPINLOCK_IRQ_EN;
+       return TRUE;
+}
+
 // if the high bit of the lock is set, then re-enable interrupts
 // (note from asw: you're lucky this works, you little-endian jerks)
 static inline void spin_unlock_irqsave(spinlock_t *lock)
@@ -345,5 +360,3 @@ static inline bool read_seqretry(seqlock_t *lock, seq_ctr_t ctr)
 {
        return seqctr_retry(lock->r_ctr, ctr);
 }
-
-#endif /* ROS_KERN_ATOMIC_H */