mirror of
https://github.com/apache/nuttx.git
synced 2026-08-01 20:28:58 +00:00
spinlock: add rspinlock interface for recursive spinlock support
Add new recursive spinlock (rspinlock) interface functions to support nested spinlock acquisitions by the same CPU. Includes rspin_lock, rspin_unlock, rspin_breaklock, and rspin_restorelock for proper recursive lock management. Signed-off-by: hujun5 <hujun5@xiaomi.com>
This commit is contained in:
parent
6f03601169
commit
bb69f77164
1 changed files with 48 additions and 12 deletions
|
|
@ -549,13 +549,20 @@ irqstate_t spin_lock_irqsave_nopreempt(FAR volatile spinlock_t *lock)
|
|||
****************************************************************************/
|
||||
|
||||
static inline_function
|
||||
irqstate_t rspin_lock_irqsave(FAR rspinlock_t *lock)
|
||||
void rspin_lock(FAR rspinlock_t *lock)
|
||||
{
|
||||
rspinlock_t new_val;
|
||||
rspinlock_t old_val = RSPINLOCK_INITIALIZER;
|
||||
irqstate_t flags = up_irq_save();
|
||||
int cpu = this_cpu() + 1;
|
||||
|
||||
/* Already owned this lock. */
|
||||
|
||||
if (lock->owner == cpu)
|
||||
{
|
||||
lock->count += 1;
|
||||
return;
|
||||
}
|
||||
|
||||
new_val.count = 1;
|
||||
new_val.owner = cpu;
|
||||
|
||||
|
|
@ -564,16 +571,15 @@ irqstate_t rspin_lock_irqsave(FAR rspinlock_t *lock)
|
|||
while (!atomic_cmpxchg_acquire((FAR atomic_t *)&lock->val,
|
||||
(FAR atomic_t *)&old_val.val, new_val.val))
|
||||
{
|
||||
/* Already owned this lock. */
|
||||
|
||||
if (old_val.owner == cpu)
|
||||
{
|
||||
lock->count += 1;
|
||||
break;
|
||||
}
|
||||
|
||||
old_val.val = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static inline_function
|
||||
irqstate_t rspin_lock_irqsave(FAR rspinlock_t *lock)
|
||||
{
|
||||
irqstate_t flags = up_irq_save();
|
||||
rspin_lock(lock);
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
|
@ -776,18 +782,30 @@ void spin_unlock_irqrestore_nopreempt(FAR volatile spinlock_t *lock,
|
|||
* spin_unlock_irqrestore_nopreempt(lock);
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
* true - Indicates exiting the spinlock.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline_function
|
||||
void rspin_unlock_irqrestore(FAR rspinlock_t *lock, irqstate_t flags)
|
||||
bool rspin_unlock(FAR rspinlock_t *lock)
|
||||
{
|
||||
DEBUGASSERT(lock->owner == this_cpu() + 1);
|
||||
DEBUGASSERT(lock->count >= 1);
|
||||
|
||||
if (--lock->count == 0)
|
||||
{
|
||||
atomic_set_release((FAR atomic_t *)&lock->val, 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline_function
|
||||
void rspin_unlock_irqrestore(FAR rspinlock_t *lock, irqstate_t flags)
|
||||
{
|
||||
if (rspin_unlock(lock))
|
||||
{
|
||||
up_irq_restore(flags);
|
||||
}
|
||||
|
||||
|
|
@ -802,6 +820,24 @@ void rspin_unlock_irqrestore_nopreempt(FAR rspinlock_t *lock,
|
|||
sched_unlock();
|
||||
}
|
||||
|
||||
static inline_function
|
||||
uint16_t rspin_breaklock(FAR rspinlock_t *lock)
|
||||
{
|
||||
int oldcount = lock->count;
|
||||
|
||||
lock->count = 1;
|
||||
rspin_unlock(lock);
|
||||
|
||||
return oldcount;
|
||||
}
|
||||
|
||||
static inline_function
|
||||
void rspin_restorelock(FAR rspinlock_t *lock, uint16_t count)
|
||||
{
|
||||
rspin_lock(lock);
|
||||
lock->count = count;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_RW_SPINLOCK)
|
||||
|
||||
/****************************************************************************
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue