Spinlocks: Added capability to provide architecture-specific memory barriers. This was for i.MX6 but does not help with the SMP problems. It is still a good feature.

This commit is contained in:
Gregory Nutt 2016-11-21 11:55:59 -06:00
parent 337d0f1050
commit 558784d06f
3 changed files with 71 additions and 5 deletions

View file

@ -48,9 +48,31 @@
* Pre-processor Definitions
****************************************************************************/
/* Spinlock states */
#define SP_UNLOCKED 0 /* The Un-locked state */
#define SP_LOCKED 1 /* The Locked state */
/* Memory barriers for use with NuttX spinlock logic */
#ifndef arm_isb
# define arm_isb(n) __asm__ __volatile__ ("isb " #n : : : "memory")
#endif
#define SP_ISB() arm_isb(15)
#ifndef arm_dsb
# define arm_dsb(n) __asm__ __volatile__ ("dsb " #n : : : "memory")
#endif
#define SP_DSB() arm_dsb(15)
#ifndef arm_dmb
# define arm_dmb(n) __asm__ __volatile__ ("dmb " #n : : : "memory")
#endif
#define SP_DMB() arm_dmb(15)
/****************************************************************************
* Public Types
****************************************************************************/

View file

@ -203,8 +203,11 @@ void spin_lockr(FAR struct spinlock_s *lock);
*
****************************************************************************/
/* void spin_unlock(FAR spinlock_t *lock); */
#define spin_unlock(l) do { *(l) = SP_UNLOCKED; } while (0)
#ifdef SP_DMB
void spin_unlock(FAR volatile spinlock_t *lock);
#else
# define spin_unlock(l) do { *(l) = SP_UNLOCKED; } while (0)
#endif
/****************************************************************************
* Name: spin_unlockr

View file

@ -65,6 +65,22 @@
#undef CONFIG_SPINLOCK_LOCKDOWN /* Feature not yet available */
/* Memory barriers may be provided in arch/spinlock.h
*
* DMB - Data memory barrier. Assures writes are completed to memory.
* DSB - Data syncrhonization barrier.
*/
#define HAVE_DMB 1
#ifndef SP_DMB
# define SP_DMB()
# undef HAVE_DMB
#endif
#ifndef SP_DSB
# define SP_DSB()
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
@ -121,12 +137,37 @@ void spin_lock(FAR volatile spinlock_t *lock)
{
while (up_testset(lock) == SP_LOCKED)
{
#if 0 /* Would recurse */
sched_yield();
#endif
SP_DSB();
}
SP_DMB();
}
/****************************************************************************
* Name: spin_unlock
*
* Description:
* Release one count on a non-reentrant spinlock.
*
* Input Parameters:
* lock - A reference to the spinlock object to unlock.
*
* Returned Value:
* None.
*
* Assumptions:
* Not running at the interrupt level.
*
****************************************************************************/
#ifdef HAVE_DMB
void spin_unlock(FAR volatile spinlock_t *lock)
{
*lock = SP_UNLOCKED;
SP_DMB();
}
#endif
/****************************************************************************
* Name: spin_lockr
*