mirror of
https://github.com/apache/nuttx.git
synced 2026-05-30 05:16:47 +08:00
risc-v/up_testset: Implement test-and-set with AMOSWAP
It should be a bit more efficient to do compared to the LR/SC pair.
This commit is contained in:
@@ -72,10 +72,12 @@
|
|||||||
*
|
*
|
||||||
* RISC-V architecture (in the standard atomic-instruction extension "A")
|
* RISC-V architecture (in the standard atomic-instruction extension "A")
|
||||||
* supports exclusive accesses to memory locations in the form of the
|
* supports exclusive accesses to memory locations in the form of the
|
||||||
* Load-Reserved (LR) and Store-Conditional (SC) instructions. RV64 supports
|
* Load-Reserved (LR), Store-Conditional (SC) and Atomic Memory Operations
|
||||||
* doubleword aligned data only but others supports word aligned data.
|
* (AMO) instructions. For LR and SC, RV64 supports doubleword aligned data
|
||||||
|
* only but others supports word aligned data. For AMO, word and doubleword
|
||||||
|
* alignments are accepted.
|
||||||
*
|
*
|
||||||
* RISC-V architecture supports fence instruction to ensure memory ordering
|
* RISC-V architecture supports fence instruction to ensure memory ordering.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef uintptr_t spinlock_t;
|
typedef uintptr_t spinlock_t;
|
||||||
@@ -107,27 +109,18 @@ typedef uintptr_t spinlock_t;
|
|||||||
#if defined(CONFIG_ARCH_RV_ISA_A)
|
#if defined(CONFIG_ARCH_RV_ISA_A)
|
||||||
static inline_function spinlock_t up_testset(volatile spinlock_t *lock)
|
static inline_function spinlock_t up_testset(volatile spinlock_t *lock)
|
||||||
{
|
{
|
||||||
spinlock_t ret = SP_UNLOCKED;
|
spinlock_t ret = SP_LOCKED;
|
||||||
|
|
||||||
__asm__ __volatile__
|
__asm__ __volatile__
|
||||||
(
|
(
|
||||||
"1: \n"
|
|
||||||
#ifdef CONFIG_ARCH_RV32
|
#ifdef CONFIG_ARCH_RV32
|
||||||
"lr.w %0, (%2) \n"
|
"amoswap.w %0, %0, %1\n"
|
||||||
#else
|
#else
|
||||||
"lr.d %0, (%2) \n"
|
"amoswap.d %0, %0, %1\n"
|
||||||
#endif
|
#endif
|
||||||
"beq %0, %1, 2f \n"
|
"fence\n"
|
||||||
#ifdef CONFIG_ARCH_RV32
|
: "+r" (ret), "+A" (*lock)
|
||||||
"sc.w %0, %1, (%2) \n"
|
:
|
||||||
#else
|
|
||||||
"sc.d %0, %1, (%2) \n"
|
|
||||||
#endif
|
|
||||||
"bnez %0, 1b \n"
|
|
||||||
"fence \n"
|
|
||||||
"2: \n"
|
|
||||||
: "+r" (ret)
|
|
||||||
: "r" (SP_LOCKED), "r" (lock)
|
|
||||||
: "memory"
|
: "memory"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user