osq_lock.h 1.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940
  1. #ifndef __LINUX_OSQ_LOCK_H
  2. #define __LINUX_OSQ_LOCK_H
  3. /*
  4. * An MCS like lock especially tailored for optimistic spinning for sleeping
  5. * lock implementations (mutex, rwsem, etc).
  6. */
  7. struct optimistic_spin_node {
  8. struct optimistic_spin_node *next, *prev;
  9. int locked; /* 1 if lock acquired */
  10. int cpu; /* encoded CPU # + 1 value */
  11. };
  12. struct optimistic_spin_queue {
  13. /*
  14. * Stores an encoded value of the CPU # of the tail node in the queue.
  15. * If the queue is empty, then it's set to OSQ_UNLOCKED_VAL.
  16. */
  17. atomic_t tail;
  18. };
  19. #define OSQ_UNLOCKED_VAL (0)
  20. /* Init macro and function. */
  21. #define OSQ_LOCK_UNLOCKED { ATOMIC_INIT(OSQ_UNLOCKED_VAL) }
  22. static inline void osq_lock_init(struct optimistic_spin_queue *lock)
  23. {
  24. atomic_set(&lock->tail, OSQ_UNLOCKED_VAL);
  25. }
  26. extern bool osq_lock(struct optimistic_spin_queue *lock);
  27. extern void osq_unlock(struct optimistic_spin_queue *lock);
  28. static inline bool osq_is_locked(struct optimistic_spin_queue *lock)
  29. {
  30. return atomic_read(&lock->tail) != OSQ_UNLOCKED_VAL;
  31. }
  32. #endif