Changeset f43d8ce in mainline
- Timestamp:
- 2023-02-02T21:58:36Z (22 months ago)
- Branches:
- master, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 2b264c4
- Parents:
- 95658c9
- git-author:
- Jiří Zárevúcky <zarevucky.jiri@…> (2023-01-19 22:40:04)
- git-committer:
- Jiří Zárevúcky <zarevucky.jiri@…> (2023-02-02 21:58:36)
- Location:
- kernel
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/arch/mips32/src/mips32.c
r95658c9 rf43d8ce 41 41 #include <str.h> 42 42 #include <mem.h> 43 #include <preemption.h> 43 44 #include <userspace.h> 44 45 #include <stdbool.h> -
kernel/arch/ppc32/src/mm/frame.c
r95658c9 rf43d8ce 33 33 */ 34 34 35 #include <arch/asm.h> 35 36 #include <arch/boot/boot.h> 36 37 #include <arch/mm/frame.h> -
kernel/generic/include/mm/tlb.h
r95658c9 rf43d8ce 36 36 #define KERN_TLB_H_ 37 37 38 #include <arch/asm.h> 38 39 #include <arch/mm/asid.h> 39 40 #include <typedefs.h> -
kernel/generic/include/synch/spinlock.h
r95658c9 rf43d8ce 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 41 44 #ifdef CONFIG_SMP 42 #include <arch/types.h> 43 #include <assert.h> 45 44 46 typedef struct spinlock { 47 atomic_flag flag; 45 #define DEADLOCK_THRESHOLD 100000000 48 46 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 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 */ 69 typedef struct spinlock { 70 #ifdef CONFIG_SMP 71 atomic_flag flag; 162 72 163 /* On UP systems, spinlocks are effectively left out. */ 73 #ifdef CONFIG_DEBUG_SPINLOCK 74 const char *name; 75 #endif /* CONFIG_DEBUG_SPINLOCK */ 76 #endif 77 } spinlock_t; 164 78 165 /* Allow the use of spinlock_t as an incomplete type. */ 166 typedef struct spinlock spinlock_t; 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 167 85 168 #define SPINLOCK_DECLARE(name) 169 #define SPINLOCK_EXTERN(name) 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 170 95 171 #define SPINLOCK_INITIALIZE(name) 172 #define SPINLOCK_STATIC_INITIALIZE(name) 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) 173 103 174 #define SPINLOCK_ INITIALIZE_NAME(name, desc_name)175 #define SPINLOCK_STATIC_INITIALIZE_NAME(name,desc_name)104 #define SPINLOCK_STATIC_INITIALIZE_NAME(lock_name, desc_name) \ 105 static spinlock_t lock_name = SPINLOCK_INITIALIZER(desc_name) 176 106 177 #define ASSERT_SPINLOCK(expr, lock) assert(expr) 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 */ 178 112 179 #define spinlock_initialize(lock, name) 113 #define SPINLOCK_INITIALIZE(lock_name) \ 114 SPINLOCK_INITIALIZE_NAME(lock_name, #lock_name) 180 115 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 116 #define SPINLOCK_STATIC_INITIALIZE(lock_name) \ 117 SPINLOCK_STATIC_INITIALIZE_NAME(lock_name, #lock_name) 186 118 187 #define DEADLOCK_PROBE_INIT(pname) 188 #define DEADLOCK_PROBE(pname, value) 189 190 #endif /* CONFIG_SMP */ 119 extern void spinlock_initialize(spinlock_t *, const char *); 120 extern bool spinlock_trylock(spinlock_t *); 121 extern void spinlock_lock(spinlock_t *); 122 extern void spinlock_unlock(spinlock_t *); 123 extern bool spinlock_locked(spinlock_t *); 191 124 192 125 typedef struct { 193 SPINLOCK_DECLARE(lock);/**< Spinlock */126 spinlock_t lock; /**< Spinlock */ 194 127 bool guard; /**< Flag whether ipl is valid */ 195 128 ipl_t ipl; /**< Original interrupt level */ … … 199 132 #define IRQ_SPINLOCK_EXTERN(lock_name) extern irq_spinlock_t lock_name 200 133 201 #ifdef CONFIG_SMP202 203 134 #define ASSERT_IRQ_SPINLOCK(expr, irq_lock) \ 204 135 ASSERT_SPINLOCK(expr, &((irq_lock)->lock)) 136 137 #define IRQ_SPINLOCK_INITIALIZER(desc_name) \ 138 { \ 139 .lock = SPINLOCK_INITIALIZER(desc_name), \ 140 .guard = false, \ 141 .ipl = 0, \ 142 } 205 143 206 144 /* … … 209 147 * as global or static symbol) and initialize the lock. 210 148 */ 211 #ifdef CONFIG_DEBUG_SPINLOCK212 213 149 #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 } 150 irq_spinlock_t lock_name = IRQ_SPINLOCK_INITIALIZER(desc_name) 222 151 223 152 #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 */ 153 static irq_spinlock_t lock_name = IRQ_SPINLOCK_INITIALIZER(desc_name) 279 154 280 155 #define IRQ_SPINLOCK_INITIALIZE(lock_name) \ -
kernel/generic/src/synch/irq_spinlock.c
r95658c9 rf43d8ce 36 36 */ 37 37 38 #include <arch/asm.h> 38 39 #include <synch/spinlock.h> 39 40 -
kernel/generic/src/synch/spinlock.c
r95658c9 rf43d8ce 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 * … … 47 48 #include <cpu.h> 48 49 49 #ifdef CONFIG_SMP50 51 50 /** Initialize spinlock 52 51 * … … 56 55 void spinlock_initialize(spinlock_t *lock, const char *name) 57 56 { 57 #ifdef CONFIG_SMP 58 58 atomic_flag_clear_explicit(&lock->flag, memory_order_relaxed); 59 59 #ifdef CONFIG_DEBUG_SPINLOCK 60 60 lock->name = name; 61 61 #endif 62 #endif 62 63 } 63 64 64 #ifdef CONFIG_DEBUG_SPINLOCK65 66 65 /** Lock spinlock 67 *68 * Lock spinlock.69 * This version has limitted ability to report70 * possible occurence of deadlock.71 66 * 72 67 * @param lock Pointer to spinlock_t structure. 73 68 * 74 69 */ 75 void spinlock_lock _debug(spinlock_t *lock)70 void spinlock_lock(spinlock_t *lock) 76 71 { 72 preemption_disable(); 73 74 #ifdef CONFIG_SMP 75 bool deadlock_reported = false; 77 76 size_t i = 0; 78 bool deadlock_reported = false;79 77 80 preemption_disable();81 78 while (atomic_flag_test_and_set_explicit(&lock->flag, memory_order_acquire)) { 79 #ifdef CONFIG_DEBUG_SPINLOCK 82 80 /* 83 81 * We need to be careful about particular locks … … 111 109 deadlock_reported = true; 112 110 } 111 #endif 113 112 } 113 114 /* Avoid compiler warning with debug disabled. */ 115 (void) i; 114 116 115 117 if (deadlock_reported) 116 118 printf("cpu%u: not deadlocked\n", CPU->id); 119 120 #endif 117 121 } 118 122 119 123 /** Unlock spinlock 120 124 * 121 * Unlock spinlock.122 *123 125 * @param sl Pointer to spinlock_t structure. 124 126 */ 125 void spinlock_unlock _debug(spinlock_t *lock)127 void spinlock_unlock(spinlock_t *lock) 126 128 { 129 #ifdef CONFIG_SMP 130 #ifdef CONFIG_DEBUG_SPINLOCK 127 131 ASSERT_SPINLOCK(spinlock_locked(lock), lock); 132 #endif 128 133 129 134 atomic_flag_clear_explicit(&lock->flag, memory_order_release); 135 #endif 136 130 137 preemption_enable(); 131 138 } 132 139 133 #endif 134 135 /** Lock spinlock conditionally 136 * 140 /** 137 141 * Lock spinlock conditionally. If the spinlock is not available 138 142 * at the moment, signal failure. … … 140 144 * @param lock Pointer to spinlock_t structure. 141 145 * 142 * @return Zero on failure, non-zero otherwise.146 * @return true on success. 143 147 * 144 148 */ … … 146 150 { 147 151 preemption_disable(); 152 153 #ifdef CONFIG_SMP 148 154 bool ret = !atomic_flag_test_and_set_explicit(&lock->flag, memory_order_acquire); 149 155 … … 152 158 153 159 return ret; 160 #else 161 return true; 162 #endif 154 163 } 155 164 … … 161 170 bool spinlock_locked(spinlock_t *lock) 162 171 { 172 #ifdef CONFIG_SMP 163 173 // NOTE: Atomic flag doesn't support simple atomic read (by design), 164 174 // so instead we test_and_set and then clear if necessary. … … 170 180 atomic_flag_clear_explicit(&lock->flag, memory_order_relaxed); 171 181 return ret; 182 #else 183 return true; 184 #endif 172 185 } 173 174 #endif175 186 176 187 /** @} -
kernel/generic/src/synch/waitq.c
r95658c9 rf43d8ce 48 48 #include <synch/waitq.h> 49 49 #include <synch/spinlock.h> 50 #include <preemption.h> 50 51 #include <proc/thread.h> 51 52 #include <proc/scheduler.h> -
kernel/generic/src/time/clock.c
r95658c9 rf43d8ce 59 59 #include <ddi/ddi.h> 60 60 #include <arch/cycle.h> 61 #include <preemption.h> 61 62 62 63 /* Pointer to variable with uptime */
Note:
See TracChangeset
for help on using the changeset viewer.