diff --git a/include/nuttx/spinlock.h b/include/nuttx/spinlock.h index d865a940e23..68607600215 100644 --- a/include/nuttx/spinlock.h +++ b/include/nuttx/spinlock.h @@ -208,7 +208,31 @@ void spin_lock_wo_note(FAR volatile spinlock_t *lock); * ****************************************************************************/ -#define spin_trylock(l) up_testset(l) +spinlock_t spin_trylock(FAR volatile spinlock_t *lock); + +/**************************************************************************** + * Name: spin_trylock_wo_note + * + * Description: + * Try once to lock the spinlock. Do not wait if the spinlock is already + * locked. + * + * This implementation is the same as the above spin_trylock() except that + * it does not perform instrumentation logic. + * + * Input Parameters: + * lock - A reference to the spinlock object to lock. + * + * Returned Value: + * SP_LOCKED - Failure, the spinlock was already locked + * SP_UNLOCKED - Success, the spinlock was successfully locked + * + * Assumptions: + * Not running at the interrupt level. + * + ****************************************************************************/ + +spinlock_t spin_trylock_wo_note(FAR volatile spinlock_t *lock); /**************************************************************************** * Name: spin_unlock diff --git a/sched/irq/irq_csection.c b/sched/irq/irq_csection.c index 4de430be823..dbe97d3cb5b 100644 --- a/sched/irq/irq_csection.c +++ b/sched/irq/irq_csection.c @@ -134,7 +134,7 @@ static inline bool irq_waitlock(int cpu) * for the deadlock condition. */ - while (spin_trylock(&g_cpu_irqlock) == SP_LOCKED) + while (spin_trylock_wo_note(&g_cpu_irqlock) == SP_LOCKED) { /* Is a pause request pending? */ @@ -152,8 +152,6 @@ static inline bool irq_waitlock(int cpu) return false; } - - SP_DSB(); } /* We have g_cpu_irqlock! */ @@ -164,7 +162,6 @@ static inline bool irq_waitlock(int cpu) sched_note_spinlocked(tcb, &g_cpu_irqlock); #endif - SP_DMB(); return true; } #endif diff --git a/sched/semaphore/spinlock.c b/sched/semaphore/spinlock.c index 74e07de1ccf..fa6b7c9939f 100644 --- a/sched/semaphore/spinlock.c +++ b/sched/semaphore/spinlock.c @@ -131,6 +131,87 @@ void spin_lock_wo_note(FAR volatile spinlock_t *lock) SP_DMB(); } +/**************************************************************************** + * Name: spin_trylock + * + * Description: + * Try once to lock the spinlock. Do not wait if the spinlock is already + * locked. + * + * Input Parameters: + * lock - A reference to the spinlock object to lock. + * + * Returned Value: + * SP_LOCKED - Failure, the spinlock was already locked + * SP_UNLOCKED - Success, the spinlock was successfully locked + * + * Assumptions: + * Not running at the interrupt level. + * + ****************************************************************************/ + +spinlock_t spin_trylock(FAR volatile spinlock_t *lock) +{ +#ifdef CONFIG_SCHED_INSTRUMENTATION_SPINLOCKS + /* Notify that we are waiting for a spinlock */ + + sched_note_spinlock(this_task(), lock); +#endif + + if (up_testset(lock) == SP_LOCKED) + { +#ifdef CONFIG_SCHED_INSTRUMENTATION_SPINLOCKS + /* Notify that we abort for a spinlock */ + + sched_note_spinabort(this_task(), &lock); +#endif + SP_DSB(); + return SP_LOCKED; + } + +#ifdef CONFIG_SCHED_INSTRUMENTATION_SPINLOCKS + /* Notify that we have the spinlock */ + + sched_note_spinlocked(this_task(), lock); +#endif + SP_DMB(); + return SP_UNLOCKED; +} + +/**************************************************************************** + * Name: spin_trylock_wo_note + * + * Description: + * Try once to lock the spinlock. Do not wait if the spinlock is already + * locked. + * + * This implementation is the same as the above spin_trylock() except that + * it does not perform instrumentation logic. + * + * Input Parameters: + * lock - A reference to the spinlock object to lock. + * + * Returned Value: + * SP_LOCKED - Failure, the spinlock was already locked + * SP_UNLOCKED - Success, the spinlock was successfully locked + * + * Assumptions: + * Not running at the interrupt level. + * + ****************************************************************************/ + +spinlock_t spin_trylock_wo_note(FAR volatile spinlock_t *lock) +{ + if (up_testset(lock) == SP_LOCKED) + { + SP_DSB(); + return SP_LOCKED; + } + + SP_DMB(); + return SP_UNLOCKED; +} + /**************************************************************************** * Name: spin_unlock *