sched/semaphore/spinlock.c: spin_trylock handle memory barrier and instrumentation correctly.
This commit is contained in:
parent
e1a89d29ee
commit
c397692532
@ -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
|
* Name: spin_unlock
|
||||||
|
@ -134,7 +134,7 @@ static inline bool irq_waitlock(int cpu)
|
|||||||
* for the deadlock condition.
|
* 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? */
|
/* Is a pause request pending? */
|
||||||
|
|
||||||
@ -152,8 +152,6 @@ static inline bool irq_waitlock(int cpu)
|
|||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
SP_DSB();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We have g_cpu_irqlock! */
|
/* We have g_cpu_irqlock! */
|
||||||
@ -164,7 +162,6 @@ static inline bool irq_waitlock(int cpu)
|
|||||||
sched_note_spinlocked(tcb, &g_cpu_irqlock);
|
sched_note_spinlocked(tcb, &g_cpu_irqlock);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
SP_DMB();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -131,6 +131,87 @@ void spin_lock_wo_note(FAR volatile spinlock_t *lock)
|
|||||||
SP_DMB();
|
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
|
* Name: spin_unlock
|
||||||
*
|
*
|
||||||
|
Loading…
Reference in New Issue
Block a user