xiaoxiang781216 commented on code in PR #10776: URL: https://github.com/apache/nuttx/pull/10776#discussion_r1359755758
########## sched/irq/irq_spinlock.c: ########## @@ -45,6 +45,17 @@ static volatile spinlock_t g_irq_spin = SP_UNLOCKED; static volatile uint8_t g_irq_spin_count[CONFIG_SMP_NCPUS]; +#ifdef CONFIG_RW_SPINLOCK +/* Used for access control */ + +static volatile rwlock_t g_irq_rw_spin = RW_SP_UNLOCKED; + +/* Handles nested calls to write_lock_irqsave and write_unlock_irqrestore */ + +static volatile uint8_t g_irq_write_spin_count[CONFIG_SMP_NCPUS]; Review Comment: g_irq_rwspin_count ########## sched/semaphore/spinlock.c: ########## @@ -446,4 +446,225 @@ void spin_clrbit(FAR volatile cpu_set_t *set, unsigned int cpu, } #endif +#ifdef CONFIG_RW_SPINLOCK + +/**************************************************************************** + * Name: read_lock + * + * Description: + * If this task does not already hold the spinlock, then loop until the + * spinlock is successfully locked. + * + * This implementation is non-reentrant and set a bit of lock. + * + * The priority of reader is higher than writter if a reader hold the + * lock, a new reader can get its lock but writer can't get this lock. + * + * Input Parameters: + * lock - A reference to the spinlock object to lock. + * + * Returned Value: + * None. When the function returns, the spinlock was successfully locked + * by this CPU. + * + * Assumptions: + * Not running at the interrupt level. + * + ****************************************************************************/ + +void read_lock(FAR volatile rwlock_t *lock) +{ + rwlock_t old; + + while (true) + { + old = atomic_load(lock); + + if (old >= RW_SP_UNLOCKED && + atomic_compare_exchange_strong(lock, &old, old + 1)) + { + break; + } + else if (old < 0) + { + SP_DSB(); + SP_WFE(); + } + } + + SP_DMB(); +} + +/**************************************************************************** + * Name: read_trylock + * + * Description: + * If this task does not already hold the spinlock, then try to get the + * lock. + * + * This implementation is non-reentrant and set a bit of lock. + * + * The priority of reader is higher than writter if a reader hold the + * lock, a new reader can get its lock but writer can't get this lock. + * + * Input Parameters: + * lock - A reference to the spinlock object to lock. + * + * Returned Value: + * false - Failure, the spinlock was already locked + * true - Success, the spinlock was successfully locked + * + * Assumptions: + * Not running at the interrupt level. + * + ****************************************************************************/ + +bool read_trylock(FAR volatile rwlock_t *lock) +{ + rwlock_t old = atomic_load(lock); + + if (old >= RW_SP_UNLOCKED && + atomic_compare_exchange_strong(lock, &old, old + 1)) + { + SP_DMB(); + return true; + } + + return false; +} + +/**************************************************************************** + * Name: read_unlock + * + * Description: + * Release a bit 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. + * + ****************************************************************************/ + +void read_unlock(FAR volatile rwlock_t *lock) +{ + DEBUGASSERT(atomic_load(lock) >= RW_SP_READ_LOCKED); + + SP_DMB(); + atomic_fetch_add(lock, -1); + SP_DSB(); + SP_SEV(); +} + +/**************************************************************************** + * Name: write_lock + * + * Description: + * If this task does not already hold the spinlock, then loop until the + * spinlock is successfully locked. + * + * This implementation is non-reentrant and set all bit on lock to avoid + * readers and writers. + * + * The priority of reader is higher than writter if a reader hold the + * lock, a new reader can get its lock but writer can't get this lock. + * + * Input Parameters: + * lock - A reference to the spinlock object to lock. + * + * Returned Value: + * None. When the function returns, the spinlock was successfully locked + * by this CPU. + * + * Assumptions: + * Not running at the interrupt level. + * + ****************************************************************************/ + +void write_lock(FAR volatile rwlock_t *lock) +{ + rwlock_t zero = RW_SP_UNLOCKED; + + while (!atomic_compare_exchange_strong(lock, &zero, RW_SP_WRITE_LOCKED)) + { + SP_DSB(); + SP_WFE(); + } + + SP_DMB(); +} + +/**************************************************************************** + * Name: write_trylock + * + * Description: + * If this task does not already hold the spinlock, then loop until the + * spinlock is successfully locked. + * + * This implementation is non-reentrant and set all bit on lock to avoid + * readers and writers. + * + * The priority of reader is higher than writter if a reader hold the + * lock, a new reader can get its lock but writer can't get this lock. + * + * Input Parameters: + * lock - A reference to the spinlock object to lock. + * + * Returned Value: + * false - Failure, the spinlock was already locked + * true - Success, the spinlock was successfully locked + * + * Assumptions: + * Not running at the interrupt level. + * + ****************************************************************************/ + +bool write_trylock(FAR volatile rwlock_t *lock) +{ + rwlock_t zero = RW_SP_UNLOCKED; + + if (!atomic_compare_exchange_strong(lock, &zero, RW_SP_WRITE_LOCKED)) + { + SP_DSB(); Review Comment: why need in fail case ########## sched/irq/irq_spinlock.c: ########## @@ -45,6 +45,17 @@ static volatile spinlock_t g_irq_spin = SP_UNLOCKED; static volatile uint8_t g_irq_spin_count[CONFIG_SMP_NCPUS]; +#ifdef CONFIG_RW_SPINLOCK +/* Used for access control */ + +static volatile rwlock_t g_irq_rw_spin = RW_SP_UNLOCKED; Review Comment: g_irq_rwspin ########## sched/semaphore/spinlock.c: ########## @@ -474,7 +474,7 @@ void spin_clrbit(FAR volatile cpu_set_t *set, unsigned int cpu, void read_lock(FAR volatile rwlock_t *lock) { - rwlock_t old; + int32_t old; Review Comment: why not continue rwlock_t ########## sched/semaphore/spinlock.c: ########## @@ -446,4 +446,225 @@ void spin_clrbit(FAR volatile cpu_set_t *set, unsigned int cpu, } #endif +#ifdef CONFIG_RW_SPINLOCK + +/**************************************************************************** + * Name: read_lock + * + * Description: + * If this task does not already hold the spinlock, then loop until the + * spinlock is successfully locked. + * + * This implementation is non-reentrant and set a bit of lock. + * + * The priority of reader is higher than writter if a reader hold the + * lock, a new reader can get its lock but writer can't get this lock. + * + * Input Parameters: + * lock - A reference to the spinlock object to lock. + * + * Returned Value: + * None. When the function returns, the spinlock was successfully locked + * by this CPU. + * + * Assumptions: + * Not running at the interrupt level. + * + ****************************************************************************/ + +void read_lock(FAR volatile rwlock_t *lock) +{ + rwlock_t old; + + while (true) + { + old = atomic_load(lock); + + if (old >= RW_SP_UNLOCKED && Review Comment: ``` if (old < 0) { SP_DSB(); SP_WFE(); } else if (atomic_compare_exchange_strong(lock, &old, old + 1)) { break; } ``` ########## sched/semaphore/spinlock.c: ########## @@ -446,4 +446,225 @@ void spin_clrbit(FAR volatile cpu_set_t *set, unsigned int cpu, } #endif +#ifdef CONFIG_RW_SPINLOCK + +/**************************************************************************** + * Name: read_lock + * + * Description: + * If this task does not already hold the spinlock, then loop until the + * spinlock is successfully locked. + * + * This implementation is non-reentrant and set a bit of lock. + * + * The priority of reader is higher than writter if a reader hold the + * lock, a new reader can get its lock but writer can't get this lock. + * + * Input Parameters: + * lock - A reference to the spinlock object to lock. + * + * Returned Value: + * None. When the function returns, the spinlock was successfully locked + * by this CPU. + * + * Assumptions: + * Not running at the interrupt level. + * + ****************************************************************************/ + +void read_lock(FAR volatile rwlock_t *lock) +{ + rwlock_t old; Review Comment: merge to line 481 ########## sched/semaphore/spinlock.c: ########## @@ -446,4 +446,225 @@ void spin_clrbit(FAR volatile cpu_set_t *set, unsigned int cpu, } #endif +#ifdef CONFIG_RW_SPINLOCK + +/**************************************************************************** + * Name: read_lock + * + * Description: + * If this task does not already hold the spinlock, then loop until the + * spinlock is successfully locked. + * + * This implementation is non-reentrant and set a bit of lock. + * + * The priority of reader is higher than writter if a reader hold the + * lock, a new reader can get its lock but writer can't get this lock. + * + * Input Parameters: + * lock - A reference to the spinlock object to lock. + * + * Returned Value: + * None. When the function returns, the spinlock was successfully locked + * by this CPU. + * + * Assumptions: + * Not running at the interrupt level. + * + ****************************************************************************/ + +void read_lock(FAR volatile rwlock_t *lock) +{ + rwlock_t old; + + while (true) + { + old = atomic_load(lock); + + if (old >= RW_SP_UNLOCKED && + atomic_compare_exchange_strong(lock, &old, old + 1)) + { + break; + } + else if (old < 0) + { + SP_DSB(); + SP_WFE(); + } + } + + SP_DMB(); +} + +/**************************************************************************** + * Name: read_trylock + * + * Description: + * If this task does not already hold the spinlock, then try to get the + * lock. + * + * This implementation is non-reentrant and set a bit of lock. + * + * The priority of reader is higher than writter if a reader hold the + * lock, a new reader can get its lock but writer can't get this lock. + * + * Input Parameters: + * lock - A reference to the spinlock object to lock. + * + * Returned Value: + * false - Failure, the spinlock was already locked + * true - Success, the spinlock was successfully locked + * + * Assumptions: + * Not running at the interrupt level. + * + ****************************************************************************/ + +bool read_trylock(FAR volatile rwlock_t *lock) +{ + rwlock_t old = atomic_load(lock); + + if (old >= RW_SP_UNLOCKED && Review Comment: ``` while (true) { rwlock_t old = atomic_load(lock); if (old < 0) { return false; } else if (atomic_compare_exchange_strong(lock, &old, old + 1)) { break; } } SP_DMB(); return true; ``` -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: commits-unsubscr...@nuttx.apache.org For queries about this service, please contact Infrastructure at: us...@infra.apache.org