xref: /linux-6.15/include/linux/osq_lock.h (revision 7c223098)
1*b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
290631822SJason Low #ifndef __LINUX_OSQ_LOCK_H
390631822SJason Low #define __LINUX_OSQ_LOCK_H
490631822SJason Low 
590631822SJason Low /*
690631822SJason Low  * An MCS like lock especially tailored for optimistic spinning for sleeping
790631822SJason Low  * lock implementations (mutex, rwsem, etc).
890631822SJason Low  */
990631822SJason Low 
1090631822SJason Low struct optimistic_spin_queue {
1190631822SJason Low 	/*
1290631822SJason Low 	 * Stores an encoded value of the CPU # of the tail node in the queue.
1390631822SJason Low 	 * If the queue is empty, then it's set to OSQ_UNLOCKED_VAL.
1490631822SJason Low 	 */
1590631822SJason Low 	atomic_t tail;
1690631822SJason Low };
1790631822SJason Low 
18d84b6728SDavidlohr Bueso #define OSQ_UNLOCKED_VAL (0)
19d84b6728SDavidlohr Bueso 
204d9d951eSJason Low /* Init macro and function. */
214d9d951eSJason Low #define OSQ_LOCK_UNLOCKED { ATOMIC_INIT(OSQ_UNLOCKED_VAL) }
224d9d951eSJason Low 
osq_lock_init(struct optimistic_spin_queue * lock)234d9d951eSJason Low static inline void osq_lock_init(struct optimistic_spin_queue *lock)
244d9d951eSJason Low {
254d9d951eSJason Low 	atomic_set(&lock->tail, OSQ_UNLOCKED_VAL);
264d9d951eSJason Low }
274d9d951eSJason Low 
28d84b6728SDavidlohr Bueso extern bool osq_lock(struct optimistic_spin_queue *lock);
29d84b6728SDavidlohr Bueso extern void osq_unlock(struct optimistic_spin_queue *lock);
30d84b6728SDavidlohr Bueso 
osq_is_locked(struct optimistic_spin_queue * lock)3159aabfc7SWaiman Long static inline bool osq_is_locked(struct optimistic_spin_queue *lock)
3259aabfc7SWaiman Long {
3359aabfc7SWaiman Long 	return atomic_read(&lock->tail) != OSQ_UNLOCKED_VAL;
3459aabfc7SWaiman Long }
3559aabfc7SWaiman Long 
3690631822SJason Low #endif
37