Changes in kernel/generic/src/synch/spinlock.c [13108f24:313b617] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/src/synch/spinlock.c
r13108f24 r313b617 128 128 void spinlock_unlock_debug(spinlock_t *lock) 129 129 { 130 ASSERT (atomic_get(&lock->val) != 0);130 ASSERT_SPINLOCK(spinlock_locked(lock), lock); 131 131 132 132 /* … … 143 143 /** Lock spinlock conditionally 144 144 * 145 * Lock spinlock conditionally. 146 * If the spinlock is not available at the moment, 147 * signal failure. 145 * Lock spinlock conditionally. If the spinlock is not available 146 * at the moment, signal failure. 148 147 * 149 148 * @param lock Pointer to spinlock_t structure. … … 168 167 } 169 168 169 /** Find out whether the spinlock is currently locked. 170 * 171 * @param lock Spinlock. 172 * @return True if the spinlock is locked, false otherwise. 173 */ 174 bool spinlock_locked(spinlock_t *lock) 175 { 176 return atomic_get(&lock->val) != 0; 177 } 178 170 179 #endif 171 180 181 /** Initialize interrupts-disabled spinlock 182 * 183 * @param lock IRQ spinlock to be initialized. 184 * @param name IRQ spinlock name. 185 * 186 */ 187 void irq_spinlock_initialize(irq_spinlock_t *lock, const char *name) 188 { 189 spinlock_initialize(&(lock->lock), name); 190 lock->guard = false; 191 lock->ipl = 0; 192 } 193 194 /** Lock interrupts-disabled spinlock 195 * 196 * Lock a spinlock which requires disabled interrupts. 197 * 198 * @param lock IRQ spinlock to be locked. 199 * @param irq_dis If true, interrupts are actually disabled 200 * prior locking the spinlock. If false, interrupts 201 * are expected to be already disabled. 202 * 203 */ 204 void irq_spinlock_lock(irq_spinlock_t *lock, bool irq_dis) 205 { 206 if (irq_dis) { 207 ipl_t ipl = interrupts_disable(); 208 spinlock_lock(&(lock->lock)); 209 210 lock->guard = true; 211 lock->ipl = ipl; 212 } else { 213 ASSERT_IRQ_SPINLOCK(interrupts_disabled(), lock); 214 215 spinlock_lock(&(lock->lock)); 216 ASSERT_IRQ_SPINLOCK(!lock->guard, lock); 217 } 218 } 219 220 /** Unlock interrupts-disabled spinlock 221 * 222 * Unlock a spinlock which requires disabled interrupts. 223 * 224 * @param lock IRQ spinlock to be unlocked. 225 * @param irq_res If true, interrupts are restored to previously 226 * saved interrupt level. 227 * 228 */ 229 void irq_spinlock_unlock(irq_spinlock_t *lock, bool irq_res) 230 { 231 ASSERT_IRQ_SPINLOCK(interrupts_disabled(), lock); 232 233 if (irq_res) { 234 ASSERT_IRQ_SPINLOCK(lock->guard, lock); 235 236 lock->guard = false; 237 ipl_t ipl = lock->ipl; 238 239 spinlock_unlock(&(lock->lock)); 240 interrupts_restore(ipl); 241 } else { 242 ASSERT_IRQ_SPINLOCK(!lock->guard, lock); 243 spinlock_unlock(&(lock->lock)); 244 } 245 } 246 247 /** Lock interrupts-disabled spinlock 248 * 249 * Lock an interrupts-disabled spinlock conditionally. If the 250 * spinlock is not available at the moment, signal failure. 251 * Interrupts are expected to be already disabled. 252 * 253 * @param lock IRQ spinlock to be locked conditionally. 254 * 255 * @return Zero on failure, non-zero otherwise. 256 * 257 */ 258 int irq_spinlock_trylock(irq_spinlock_t *lock) 259 { 260 ASSERT_IRQ_SPINLOCK(interrupts_disabled(), lock); 261 int rc = spinlock_trylock(&(lock->lock)); 262 263 ASSERT_IRQ_SPINLOCK(!lock->guard, lock); 264 return rc; 265 } 266 267 /** Pass lock from one interrupts-disabled spinlock to another 268 * 269 * Pass lock from one IRQ spinlock to another IRQ spinlock 270 * without enabling interrupts during the process. 271 * 272 * The first IRQ spinlock is supposed to be locked. 273 * 274 * @param unlock IRQ spinlock to be unlocked. 275 * @param lock IRQ spinlock to be locked. 276 * 277 */ 278 void irq_spinlock_pass(irq_spinlock_t *unlock, irq_spinlock_t *lock) 279 { 280 ASSERT_IRQ_SPINLOCK(interrupts_disabled(), unlock); 281 282 /* Pass guard from unlock to lock */ 283 bool guard = unlock->guard; 284 ipl_t ipl = unlock->ipl; 285 unlock->guard = false; 286 287 spinlock_unlock(&(unlock->lock)); 288 spinlock_lock(&(lock->lock)); 289 290 ASSERT_IRQ_SPINLOCK(!lock->guard, lock); 291 292 if (guard) { 293 lock->guard = true; 294 lock->ipl = ipl; 295 } 296 } 297 298 /** Hand-over-hand locking of interrupts-disabled spinlocks 299 * 300 * Implement hand-over-hand locking between two interrupts-disabled 301 * spinlocks without enabling interrupts during the process. 302 * 303 * The first IRQ spinlock is supposed to be locked. 304 * 305 * @param unlock IRQ spinlock to be unlocked. 306 * @param lock IRQ spinlock to be locked. 307 * 308 */ 309 void irq_spinlock_exchange(irq_spinlock_t *unlock, irq_spinlock_t *lock) 310 { 311 ASSERT_IRQ_SPINLOCK(interrupts_disabled(), unlock); 312 313 spinlock_lock(&(lock->lock)); 314 ASSERT_IRQ_SPINLOCK(!lock->guard, lock); 315 316 /* Pass guard from unlock to lock */ 317 if (unlock->guard) { 318 lock->guard = true; 319 lock->ipl = unlock->ipl; 320 unlock->guard = false; 321 } 322 323 spinlock_unlock(&(unlock->lock)); 324 } 325 326 /** Find out whether the IRQ spinlock is currently locked. 327 * 328 * @param lock IRQ spinlock. 329 * @return True if the IRQ spinlock is locked, false otherwise. 330 */ 331 bool irq_spinlock_locked(irq_spinlock_t *ilock) 332 { 333 return spinlock_locked(&ilock->lock); 334 } 335 172 336 /** @} 173 337 */
Note:
See TracChangeset
for help on using the changeset viewer.