1 /* 2 * Copyright (c) 2015 Travis Geiselbrecht 3 * 4 * Use of this source code is governed by a MIT-style 5 * license that can be found in the LICENSE file or at 6 * https://opensource.org/licenses/MIT 7 */ 8 #include <arch/spinlock.h> 9 10 // super simple spin lock implementation 11 riscv_spin_trylock(spin_lock_t * lock)12int riscv_spin_trylock(spin_lock_t *lock) { 13 unsigned long val = arch_curr_cpu_num() + 1UL; 14 unsigned long old; 15 16 __asm__ __volatile__( 17 "amoswap.w %0, %2, %1\n" 18 "fence r, rw\n" 19 : "=r"(old), "+A"(*lock) 20 : "r" (val) 21 : "memory" 22 ); 23 24 return !old; 25 } 26 riscv_spin_lock(spin_lock_t * lock)27void riscv_spin_lock(spin_lock_t *lock) { 28 unsigned long val = arch_curr_cpu_num() + 1UL; 29 30 for (;;) { 31 if (*lock) { 32 continue; 33 } 34 35 unsigned long old; 36 __asm__ __volatile__( 37 "amoswap.w %0, %2, %1\n" 38 "fence r, rw\n" 39 : "=r"(old), "+A"(*lock) 40 : "r" (val) 41 : "memory" 42 ); 43 44 if (!old) { 45 break; 46 } 47 } 48 } 49 riscv_spin_unlock(spin_lock_t * lock)50void riscv_spin_unlock(spin_lock_t *lock) { 51 __asm__ volatile("fence rw,w" ::: "memory"); 52 *lock = 0; 53 } 54 55