This is an automated email from the ASF dual-hosted git repository.
archer pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
The following commit(s) were added to refs/heads/master by this push:
new 3146ea04b8 risc-v/up_testset: Implement test-and-set with AMOSWAP
3146ea04b8 is described below
commit 3146ea04b83b04f79913c0329882bf68d3034b61
Author: Ville Juven <[email protected]>
AuthorDate: Thu Nov 7 12:11:21 2024 +0200
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.
---
arch/risc-v/include/spinlock.h | 29 +++++++++++------------------
1 file changed, 11 insertions(+), 18 deletions(-)
diff --git a/arch/risc-v/include/spinlock.h b/arch/risc-v/include/spinlock.h
index f3140f261f..925ee2a650 100644
--- a/arch/risc-v/include/spinlock.h
+++ b/arch/risc-v/include/spinlock.h
@@ -72,10 +72,12 @@
*
* RISC-V architecture (in the standard atomic-instruction extension "A")
* supports exclusive accesses to memory locations in the form of the
- * Load-Reserved (LR) and Store-Conditional (SC) instructions. RV64 supports
- * doubleword aligned data only but others supports word aligned data.
+ * Load-Reserved (LR), Store-Conditional (SC) and Atomic Memory Operations
+ * (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;
@@ -107,27 +109,18 @@ typedef uintptr_t spinlock_t;
#if defined(CONFIG_ARCH_RV_ISA_A)
static inline_function spinlock_t up_testset(volatile spinlock_t *lock)
{
- spinlock_t ret = SP_UNLOCKED;
+ spinlock_t ret = SP_LOCKED;
__asm__ __volatile__
(
- "1: \n"
#ifdef CONFIG_ARCH_RV32
- "lr.w %0, (%2) \n"
+ "amoswap.w %0, %0, %1\n"
#else
- "lr.d %0, (%2) \n"
+ "amoswap.d %0, %0, %1\n"
#endif
- "beq %0, %1, 2f \n"
-#ifdef CONFIG_ARCH_RV32
- "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)
+ "fence\n"
+ : "+r" (ret), "+A" (*lock)
+ :
: "memory"
);