diff options
author | Christian Cunningham <cc@localhost> | 2021-12-19 14:50:45 -0800 |
---|---|---|
committer | Christian Cunningham <cc@localhost> | 2021-12-19 14:50:45 -0800 |
commit | 43db8c57ebe496bea03d66e2ddd0aa6bc298738c (patch) | |
tree | 6a4a8bf25319d1ceb834ee2dd567089fd70c87bd | |
parent | 456580be4408869962cf28bb39d909fb5fcb6176 (diff) |
Added atomic swap
-rw-r--r-- | src/cpu/atomic/swap.a.h | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/src/cpu/atomic/swap.a.h b/src/cpu/atomic/swap.a.h new file mode 100644 index 0000000..63dd50b --- /dev/null +++ b/src/cpu/atomic/swap.a.h @@ -0,0 +1,32 @@ +#ifndef CPU_ATOMIC_SWAP_A_H +#define CPU_ATOMIC_SWAP_A_H + +/// https://stackoverflow.com/questions/16329123/use-of-strexeq-instead-of-strex-for-spinlock-implementation-in-arm + +static inline void atm_lock(unsigned long pid, unsigned long* addr) { + unsigned long tmp, current_lock_value; + asm volatile( +"1: ldrex %0, [%3]\n" +" cmp %0, #0\n" +" wfene\n" +" strexeq %1, %2, [%3]\n" +" teq %1, #0\n" +" bne 1b\n" +" dmb" + : "=&r" (current_lock_value), "=&r" (tmp) + : "r" (pid), "r" (addr) + : "cc"); +} + +static inline void atm_unlock(unsigned long* addr) { + unsigned long cleared = 0; + asm volatile( +" dmb\n" +" str %0, [%1]\n" +" dsb\n" +" sev" + :: "r" (cleared), "r" (addr) + : "cc"); +} + +#endif |