Changes in kernel/generic/include/synch/spinlock.h [8df5f20:4f84ee42] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/include/synch/spinlock.h
r8df5f20 r4f84ee42 1 1 /* 2 2 * Copyright (c) 2001-2004 Jakub Jermar 3 * Copyright (c) 2023 Jiří Zárevúcky 3 4 * All rights reserved. 4 5 * … … 36 37 #define KERN_SPINLOCK_H_ 37 38 38 #include <assert.h>39 39 #include <stdatomic.h> 40 40 #include <stdbool.h> 41 #include <preemption.h> 42 #include <arch/asm.h> 43 44 #ifdef CONFIG_SMP 45 46 typedef struct spinlock { 47 atomic_flag flag; 48 49 #ifdef CONFIG_DEBUG_SPINLOCK 50 const char *name; 51 #endif /* CONFIG_DEBUG_SPINLOCK */ 52 } spinlock_t; 53 54 /* 55 * SPINLOCK_DECLARE is to be used for dynamically allocated spinlocks, 56 * where the lock gets initialized in run time. 57 */ 58 #define SPINLOCK_DECLARE(lock_name) spinlock_t lock_name 59 #define SPINLOCK_EXTERN(lock_name) extern spinlock_t lock_name 60 61 /* 62 * SPINLOCK_INITIALIZE and SPINLOCK_STATIC_INITIALIZE are to be used 63 * for statically allocated spinlocks. They declare (either as global 64 * or static) symbol and initialize the lock. 65 */ 66 #ifdef CONFIG_DEBUG_SPINLOCK 67 68 #define SPINLOCK_INITIALIZE_NAME(lock_name, desc_name) \ 69 spinlock_t lock_name = { \ 70 .name = desc_name, \ 71 .flag = ATOMIC_FLAG_INIT \ 72 } 73 74 #define SPINLOCK_STATIC_INITIALIZE_NAME(lock_name, desc_name) \ 75 static spinlock_t lock_name = { \ 76 .name = desc_name, \ 77 .flag = ATOMIC_FLAG_INIT \ 78 } 79 80 #define ASSERT_SPINLOCK(expr, lock) \ 81 assert_verbose(expr, (lock)->name) 82 83 #define spinlock_lock(lock) spinlock_lock_debug((lock)) 84 #define spinlock_unlock(lock) spinlock_unlock_debug((lock)) 85 86 #else /* CONFIG_DEBUG_SPINLOCK */ 87 88 #define SPINLOCK_INITIALIZE_NAME(lock_name, desc_name) \ 89 spinlock_t lock_name = { \ 90 .flag = ATOMIC_FLAG_INIT \ 91 } 92 93 #define SPINLOCK_STATIC_INITIALIZE_NAME(lock_name, desc_name) \ 94 static spinlock_t lock_name = { \ 95 .flag = ATOMIC_FLAG_INIT \ 96 } 97 98 #define ASSERT_SPINLOCK(expr, lock) \ 99 assert(expr) 100 101 /** Acquire spinlock 102 * 103 * @param lock Pointer to spinlock_t structure. 104 */ 105 _NO_TRACE static inline void spinlock_lock(spinlock_t *lock) 106 { 107 preemption_disable(); 108 while (atomic_flag_test_and_set_explicit(&lock->flag, 109 memory_order_acquire)) 110 ; 111 } 112 113 /** Release spinlock 114 * 115 * @param lock Pointer to spinlock_t structure. 116 */ 117 _NO_TRACE static inline void spinlock_unlock(spinlock_t *lock) 118 { 119 atomic_flag_clear_explicit(&lock->flag, memory_order_release); 120 preemption_enable(); 121 } 122 123 #endif /* CONFIG_DEBUG_SPINLOCK */ 124 125 #define SPINLOCK_INITIALIZE(lock_name) \ 126 SPINLOCK_INITIALIZE_NAME(lock_name, #lock_name) 127 128 #define SPINLOCK_STATIC_INITIALIZE(lock_name) \ 129 SPINLOCK_STATIC_INITIALIZE_NAME(lock_name, #lock_name) 130 131 extern void spinlock_initialize(spinlock_t *, const char *); 132 extern bool spinlock_trylock(spinlock_t *); 133 extern void spinlock_lock_debug(spinlock_t *); 134 extern void spinlock_unlock_debug(spinlock_t *); 135 extern bool spinlock_locked(spinlock_t *); 136 137 #ifdef CONFIG_DEBUG_SPINLOCK 41 42 #include <arch/types.h> 43 #include <assert.h> 44 45 #define DEADLOCK_THRESHOLD 100000000 46 47 #if defined(CONFIG_SMP) && defined(CONFIG_DEBUG_SPINLOCK) 138 48 139 49 #include <log.h> 140 141 #define DEADLOCK_THRESHOLD 100000000142 50 143 51 #define DEADLOCK_PROBE_INIT(pname) size_t pname = 0 … … 159 67 #endif /* CONFIG_DEBUG_SPINLOCK */ 160 68 161 #else /* CONFIG_SMP */ 162 163 /* On UP systems, spinlocks are effectively left out. */ 164 165 /* Allow the use of spinlock_t as an incomplete type. */ 166 typedef struct spinlock spinlock_t; 167 168 #define SPINLOCK_DECLARE(name) 169 #define SPINLOCK_EXTERN(name) 170 171 #define SPINLOCK_INITIALIZE(name) 172 #define SPINLOCK_STATIC_INITIALIZE(name) 173 174 #define SPINLOCK_INITIALIZE_NAME(name, desc_name) 175 #define SPINLOCK_STATIC_INITIALIZE_NAME(name, desc_name) 176 177 #define ASSERT_SPINLOCK(expr, lock) assert(expr) 178 179 #define spinlock_initialize(lock, name) 180 181 #define spinlock_lock(lock) preemption_disable() 182 #define spinlock_trylock(lock) ({ preemption_disable(); 1; }) 183 #define spinlock_unlock(lock) preemption_enable() 184 #define spinlock_locked(lock) 1 185 #define spinlock_unlocked(lock) 1 186 187 #define DEADLOCK_PROBE_INIT(pname) 188 #define DEADLOCK_PROBE(pname, value) 189 190 #endif /* CONFIG_SMP */ 69 typedef struct spinlock { 70 #ifdef CONFIG_SMP 71 atomic_flag flag; 72 73 #ifdef CONFIG_DEBUG_SPINLOCK 74 const char *name; 75 #endif /* CONFIG_DEBUG_SPINLOCK */ 76 #endif 77 } spinlock_t; 78 79 /* 80 * SPINLOCK_DECLARE is to be used for dynamically allocated spinlocks, 81 * where the lock gets initialized in run time. 82 */ 83 #define SPINLOCK_DECLARE(lock_name) spinlock_t lock_name 84 #define SPINLOCK_EXTERN(lock_name) extern spinlock_t lock_name 85 86 #ifdef CONFIG_SMP 87 #ifdef CONFIG_DEBUG_SPINLOCK 88 #define SPINLOCK_INITIALIZER(desc_name) { .name = (desc_name), .flag = ATOMIC_FLAG_INIT } 89 #else 90 #define SPINLOCK_INITIALIZER(desc_name) { .flag = ATOMIC_FLAG_INIT } 91 #endif 92 #else 93 #define SPINLOCK_INITIALIZER(desc_name) {} 94 #endif 95 96 /* 97 * SPINLOCK_INITIALIZE and SPINLOCK_STATIC_INITIALIZE are to be used 98 * for statically allocated spinlocks. They declare (either as global 99 * or static) symbol and initialize the lock. 100 */ 101 #define SPINLOCK_INITIALIZE_NAME(lock_name, desc_name) \ 102 spinlock_t lock_name = SPINLOCK_INITIALIZER(desc_name) 103 104 #define SPINLOCK_STATIC_INITIALIZE_NAME(lock_name, desc_name) \ 105 static spinlock_t lock_name = SPINLOCK_INITIALIZER(desc_name) 106 107 #if defined(CONFIG_SMP) && defined(CONFIG_DEBUG_SPINLOCK) 108 #define ASSERT_SPINLOCK(expr, lock) assert_verbose(expr, (lock)->name) 109 #else /* CONFIG_DEBUG_SPINLOCK */ 110 #define ASSERT_SPINLOCK(expr, lock) assert(expr) 111 #endif /* CONFIG_DEBUG_SPINLOCK */ 112 113 #define SPINLOCK_INITIALIZE(lock_name) \ 114 SPINLOCK_INITIALIZE_NAME(lock_name, #lock_name) 115 116 #define SPINLOCK_STATIC_INITIALIZE(lock_name) \ 117 SPINLOCK_STATIC_INITIALIZE_NAME(lock_name, #lock_name) 118 119 #ifdef CONFIG_SMP 120 121 extern void spinlock_initialize(spinlock_t *, const char *); 122 extern bool spinlock_trylock(spinlock_t *); 123 extern void spinlock_lock(spinlock_t *); 124 extern void spinlock_unlock(spinlock_t *); 125 extern bool spinlock_locked(spinlock_t *); 126 127 #else 128 129 #include <preemption.h> 130 131 static inline void spinlock_initialize(spinlock_t *l, const char *name) 132 { 133 } 134 135 static inline bool spinlock_trylock(spinlock_t *l) 136 { 137 preemption_disable(); 138 return true; 139 } 140 141 static inline void spinlock_lock(spinlock_t *l) 142 { 143 preemption_disable(); 144 } 145 146 static inline void spinlock_unlock(spinlock_t *l) 147 { 148 preemption_enable(); 149 } 150 151 static inline bool spinlock_locked(spinlock_t *l) 152 { 153 return true; 154 } 155 156 #endif 191 157 192 158 typedef struct { 193 SPINLOCK_DECLARE(lock); /**< Spinlock */ 194 bool guard; /**< Flag whether ipl is valid */ 195 ipl_t ipl; /**< Original interrupt level */ 159 spinlock_t lock; /**< Spinlock */ 160 bool guard; /**< Flag whether ipl is valid */ 161 ipl_t ipl; /**< Original interrupt level */ 162 #ifdef CONFIG_DEBUG_SPINLOCK 163 _Atomic(struct cpu *) owner; /**< Which cpu currently owns this lock */ 164 #endif 196 165 } irq_spinlock_t; 197 166 … … 199 168 #define IRQ_SPINLOCK_EXTERN(lock_name) extern irq_spinlock_t lock_name 200 169 201 #ifdef CONFIG_SMP202 203 170 #define ASSERT_IRQ_SPINLOCK(expr, irq_lock) \ 204 171 ASSERT_SPINLOCK(expr, &((irq_lock)->lock)) 172 173 #define IRQ_SPINLOCK_INITIALIZER(desc_name) \ 174 { \ 175 .lock = SPINLOCK_INITIALIZER(desc_name), \ 176 .guard = false, \ 177 .ipl = 0, \ 178 } 205 179 206 180 /* … … 209 183 * as global or static symbol) and initialize the lock. 210 184 */ 211 #ifdef CONFIG_DEBUG_SPINLOCK212 213 185 #define IRQ_SPINLOCK_INITIALIZE_NAME(lock_name, desc_name) \ 214 irq_spinlock_t lock_name = { \ 215 .lock = { \ 216 .name = desc_name, \ 217 .flag = ATOMIC_FLAG_INIT \ 218 }, \ 219 .guard = false, \ 220 .ipl = 0 \ 221 } 186 irq_spinlock_t lock_name = IRQ_SPINLOCK_INITIALIZER(desc_name) 222 187 223 188 #define IRQ_SPINLOCK_STATIC_INITIALIZE_NAME(lock_name, desc_name) \ 224 static irq_spinlock_t lock_name = { \ 225 .lock = { \ 226 .name = desc_name, \ 227 .flag = ATOMIC_FLAG_INIT \ 228 }, \ 229 .guard = false, \ 230 .ipl = 0 \ 231 } 232 233 #else /* CONFIG_DEBUG_SPINLOCK */ 234 235 #define IRQ_SPINLOCK_INITIALIZE_NAME(lock_name, desc_name) \ 236 irq_spinlock_t lock_name = { \ 237 .lock = { \ 238 .flag = ATOMIC_FLAG_INIT \ 239 }, \ 240 .guard = false, \ 241 .ipl = 0 \ 242 } 243 244 #define IRQ_SPINLOCK_STATIC_INITIALIZE_NAME(lock_name, desc_name) \ 245 static irq_spinlock_t lock_name = { \ 246 .lock = { \ 247 .flag = ATOMIC_FLAG_INIT \ 248 }, \ 249 .guard = false, \ 250 .ipl = 0 \ 251 } 252 253 #endif /* CONFIG_DEBUG_SPINLOCK */ 254 255 #else /* CONFIG_SMP */ 256 257 /* 258 * Since the spinlocks are void on UP systems, we also need 259 * to have a special variant of interrupts-disabled spinlock 260 * macros which take this into account. 261 */ 262 263 #define ASSERT_IRQ_SPINLOCK(expr, irq_lock) \ 264 ASSERT_SPINLOCK(expr, NULL) 265 266 #define IRQ_SPINLOCK_INITIALIZE_NAME(lock_name, desc_name) \ 267 irq_spinlock_t lock_name = { \ 268 .guard = false, \ 269 .ipl = 0 \ 270 } 271 272 #define IRQ_SPINLOCK_STATIC_INITIALIZE_NAME(lock_name, desc_name) \ 273 static irq_spinlock_t lock_name = { \ 274 .guard = false, \ 275 .ipl = 0 \ 276 } 277 278 #endif /* CONFIG_SMP */ 189 static irq_spinlock_t lock_name = IRQ_SPINLOCK_INITIALIZER(desc_name) 279 190 280 191 #define IRQ_SPINLOCK_INITIALIZE(lock_name) \
Note:
See TracChangeset
for help on using the changeset viewer.