/* * Copyright (c) 2012-2017 Richard Braun. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * * Spin lock. * * Critical sections built with spin locks run with preemption disabled. */ #ifndef _KERN_SPINLOCK_H #define _KERN_SPINLOCK_H #include #include #include #include #include #include struct spinlock; static inline void spinlock_init(struct spinlock *lock) { lock->locked = 0; } #define spinlock_assert_locked(lock) assert((lock)->locked) static inline int spinlock_trylock(struct spinlock *lock) { int error; thread_preempt_disable(); error = spinlock_tryacquire(lock); if (error) { thread_preempt_enable(); } return error; } static inline void spinlock_lock(struct spinlock *lock) { thread_preempt_disable(); spinlock_acquire(lock); } static inline void spinlock_unlock(struct spinlock *lock) { spinlock_release(lock); thread_preempt_enable(); } /* * Versions of the spinlock functions that also disable interrupts during * critical sections. */ static inline int spinlock_trylock_intr_save(struct spinlock *lock, unsigned long *flags) { int error; thread_preempt_disable(); cpu_intr_save(flags); error = spinlock_tryacquire(lock); if (error) { cpu_intr_restore(*flags); thread_preempt_enable(); } return error; } static inline void spinlock_lock_intr_save(struct spinlock *lock, unsigned long *flags) { thread_preempt_disable(); cpu_intr_save(flags); spinlock_acquire(lock); } static inline void spinlock_unlock_intr_restore(struct spinlock *lock, unsigned long flags) { spinlock_release(lock); cpu_intr_restore(flags); thread_preempt_enable(); } #endif /* _KERN_SPINLOCK_H */