blob: 304e2c64ce611a4f1412fc9d3c2abdc7f4447188 [file] [log] [blame]
Nicholas Flintham1e3d3112013-04-10 10:48:38 +01001#ifndef __LINUX_BIT_SPINLOCK_H
2#define __LINUX_BIT_SPINLOCK_H
3
4#include <linux/kernel.h>
5#include <linux/preempt.h>
6#include <linux/atomic.h>
7#include <linux/bug.h>
8
9static inline void bit_spin_lock(int bitnum, unsigned long *addr)
10{
11 preempt_disable();
12#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
13 while (unlikely(test_and_set_bit_lock(bitnum, addr))) {
14 preempt_enable();
15 do {
16 cpu_relax();
17 } while (test_bit(bitnum, addr));
18 preempt_disable();
19 }
20#endif
21 __acquire(bitlock);
22}
23
24static inline int bit_spin_trylock(int bitnum, unsigned long *addr)
25{
26 preempt_disable();
27#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
28 if (unlikely(test_and_set_bit_lock(bitnum, addr))) {
29 preempt_enable();
30 return 0;
31 }
32#endif
33 __acquire(bitlock);
34 return 1;
35}
36
37static inline void bit_spin_unlock(int bitnum, unsigned long *addr)
38{
39#ifdef CONFIG_DEBUG_SPINLOCK
40 BUG_ON(!test_bit(bitnum, addr));
41#endif
42#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
43 clear_bit_unlock(bitnum, addr);
44#endif
45 preempt_enable();
46 __release(bitlock);
47}
48
49static inline void __bit_spin_unlock(int bitnum, unsigned long *addr)
50{
51#ifdef CONFIG_DEBUG_SPINLOCK
52 BUG_ON(!test_bit(bitnum, addr));
53#endif
54#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
55 __clear_bit_unlock(bitnum, addr);
56#endif
57 preempt_enable();
58 __release(bitlock);
59}
60
61static inline int bit_spin_is_locked(int bitnum, unsigned long *addr)
62{
63#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
64 return test_bit(bitnum, addr);
65#elif defined CONFIG_PREEMPT_COUNT
66 return preempt_count();
67#else
68 return 1;
69#endif
70}
71
72#endif
73