1#ifndef __LINUX_SPINLOCK_H
2#define __LINUX_SPINLOCK_H
3
4#include <linux/config.h>
5#include <linux/preempt.h>
6#include <linux/linkage.h>
7#include <linux/compiler.h>
8#include <linux/thread_info.h>
9#include <linux/kernel.h>
10
11#include <asm/system.h>
12
13
14
15
16
17#define spin_lock_irqsave(lock, flags) do { local_irq_save(flags); spin_lock(lock); } while (0)
18#define spin_lock_irq(lock) do { local_irq_disable(); spin_lock(lock); } while (0)
19#define spin_lock_bh(lock) do { local_bh_disable(); spin_lock(lock); } while (0)
20
21#define read_lock_irqsave(lock, flags) do { local_irq_save(flags); read_lock(lock); } while (0)
22#define read_lock_irq(lock) do { local_irq_disable(); read_lock(lock); } while (0)
23#define read_lock_bh(lock) do { local_bh_disable(); read_lock(lock); } while (0)
24
25#define write_lock_irqsave(lock, flags) do { local_irq_save(flags); write_lock(lock); } while (0)
26#define write_lock_irq(lock) do { local_irq_disable(); write_lock(lock); } while (0)
27#define write_lock_bh(lock) do { local_bh_disable(); write_lock(lock); } while (0)
28
29#define spin_unlock_irqrestore(lock, flags) do { _raw_spin_unlock(lock); local_irq_restore(flags); preempt_enable(); } while (0)
30#define _raw_spin_unlock_irqrestore(lock, flags) do { _raw_spin_unlock(lock); local_irq_restore(flags); } while (0)
31#define spin_unlock_irq(lock) do { _raw_spin_unlock(lock); local_irq_enable(); preempt_enable(); } while (0)
32#define spin_unlock_bh(lock) do { spin_unlock(lock); local_bh_enable(); } while (0)
33
34#define read_unlock_irqrestore(lock, flags) do { _raw_read_unlock(lock); local_irq_restore(flags); preempt_enable(); } while (0)
35#define read_unlock_irq(lock) do { _raw_read_unlock(lock); local_irq_enable(); preempt_enable(); } while (0)
36#define read_unlock_bh(lock) do { read_unlock(lock); local_bh_enable(); } while (0)
37
38#define write_unlock_irqrestore(lock, flags) do { _raw_write_unlock(lock); local_irq_restore(flags); preempt_enable(); } while (0)
39#define write_unlock_irq(lock) do { _raw_write_unlock(lock); local_irq_enable(); preempt_enable(); } while (0)
40#define write_unlock_bh(lock) do { write_unlock(lock); local_bh_enable(); } while (0)
41#define spin_trylock_bh(lock) ({ int __r; local_bh_disable();\
42 __r = spin_trylock(lock); \
43 if (!__r) local_bh_enable(); \
44 __r; })
45
46
47
48#include <linux/stringify.h>
49
50#define LOCK_SECTION_NAME \
51 ".text.lock." __stringify(KBUILD_BASENAME)
52
53#define LOCK_SECTION_START(extra) \
54 ".subsection 1\n\t" \
55 extra \
56 ".ifndef " LOCK_SECTION_NAME "\n\t" \
57 LOCK_SECTION_NAME ":\n\t" \
58 ".endif\n\t"
59
60#define LOCK_SECTION_END \
61 ".previous\n\t"
62
63#ifdef CONFIG_SMP
64#include <asm/spinlock.h>
65
66#elif !defined(spin_lock_init)
67
68
69#ifndef CONFIG_PREEMPT
70# define atomic_dec_and_lock(atomic,lock) atomic_dec_and_test(atomic)
71# define ATOMIC_DEC_AND_LOCK
72#endif
73
74
75
76
77
78
79#if (__GNUC__ > 2)
80 typedef struct { } spinlock_t;
81# define SPIN_LOCK_UNLOCKED (spinlock_t) { }
82#else
83 typedef struct { int gcc_is_buggy; } spinlock_t;
84# define SPIN_LOCK_UNLOCKED (spinlock_t) { 0 }
85#endif
86
87#define spin_lock_init(lock) do { (void)(lock); } while(0)
88#define _raw_spin_lock(lock) (void)(lock)
89#define spin_is_locked(lock) ((void)(lock), 0)
90#define _raw_spin_trylock(lock) ((void)(lock), 1)
91#define spin_unlock_wait(lock) do { (void)(lock); } while(0)
92#define _raw_spin_unlock(lock) do { (void)(lock); } while(0)
93
94
95
96
97
98
99
100
101
102
103
104
105
106#if (__GNUC__ > 2)
107 typedef struct { } rwlock_t;
108 #define RW_LOCK_UNLOCKED (rwlock_t) { }
109#else
110 typedef struct { int gcc_is_buggy; } rwlock_t;
111 #define RW_LOCK_UNLOCKED (rwlock_t) { 0 }
112#endif
113
114#define rwlock_init(lock) do { } while(0)
115#define _raw_read_lock(lock) (void)(lock)
116#define _raw_read_unlock(lock) do { } while(0)
117#define _raw_write_lock(lock) (void)(lock)
118#define _raw_write_unlock(lock) do { } while(0)
119
120#endif
121
122#ifdef CONFIG_PREEMPT
123
124#define spin_lock(lock) \
125do { \
126 preempt_disable(); \
127 _raw_spin_lock(lock); \
128} while(0)
129
130#define spin_trylock(lock) ({preempt_disable(); _raw_spin_trylock(lock) ? \
131 1 : ({preempt_enable(); 0;});})
132#define spin_unlock(lock) \
133do { \
134 _raw_spin_unlock(lock); \
135 preempt_enable(); \
136} while (0)
137
138#define read_lock(lock) ({preempt_disable(); _raw_read_lock(lock);})
139#define read_unlock(lock) ({_raw_read_unlock(lock); preempt_enable();})
140#define write_lock(lock) ({preempt_disable(); _raw_write_lock(lock);})
141#define write_unlock(lock) ({_raw_write_unlock(lock); preempt_enable();})
142#define write_trylock(lock) ({preempt_disable();_raw_write_trylock(lock) ? \
143 1 : ({preempt_enable(); 0;});})
144
145#else
146
147#define spin_lock(lock) _raw_spin_lock(lock)
148#define spin_trylock(lock) _raw_spin_trylock(lock)
149#define spin_unlock(lock) _raw_spin_unlock(lock)
150
151#define read_lock(lock) _raw_read_lock(lock)
152#define read_unlock(lock) _raw_read_unlock(lock)
153#define write_lock(lock) _raw_write_lock(lock)
154#define write_unlock(lock) _raw_write_unlock(lock)
155#define write_trylock(lock) _raw_write_trylock(lock)
156#endif
157
158
159#ifndef ATOMIC_DEC_AND_LOCK
160#include <asm/atomic.h>
161extern int atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock);
162#endif
163
164#endif
165