/* * Copyright (c) 2014 Travis Geiselbrecht * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #pragma once #include #include __BEGIN_CDECLS /* interrupts should already be disabled */ static inline void spin_lock(spin_lock_t *lock) { arch_spin_lock(lock); } /* Returns 0 on success, non-0 on failure */ static inline int spin_trylock(spin_lock_t *lock) { return arch_spin_trylock(lock); } /* interrupts should already be disabled */ static inline void spin_unlock(spin_lock_t *lock) { arch_spin_unlock(lock); } static inline void spin_lock_init(spin_lock_t *lock) { arch_spin_lock_init(lock); } static inline bool spin_lock_held(spin_lock_t *lock) { return arch_spin_lock_held(lock); } /* spin lock irq save flags: */ /* Possible future flags: * SPIN_LOCK_FLAG_PMR_MASK = 0x000000ff * SPIN_LOCK_FLAG_PREEMPTION = 0x00000100 * SPIN_LOCK_FLAG_SET_PMR = 0x00000200 */ /* Generic flags */ #define SPIN_LOCK_FLAG_INTERRUPTS ARCH_DEFAULT_SPIN_LOCK_FLAG_INTERRUPTS /* same as spin lock, but save disable and save interrupt state first */ static inline void spin_lock_save( spin_lock_t *lock, spin_lock_saved_state_t *statep, spin_lock_save_flags_t flags) { arch_interrupt_save(statep, flags); spin_lock(lock); } /* restore interrupt state before unlocking */ static inline void spin_unlock_restore( spin_lock_t *lock, spin_lock_saved_state_t old_state, spin_lock_save_flags_t flags) { spin_unlock(lock); arch_interrupt_restore(old_state, flags); } /* hand(ier) routines */ #define spin_lock_irqsave(lock, statep) spin_lock_save(lock, &(statep), SPIN_LOCK_FLAG_INTERRUPTS) #define spin_unlock_irqrestore(lock, statep) spin_unlock_restore(lock, statep, SPIN_LOCK_FLAG_INTERRUPTS) __END_CDECLS