RISC-V port mostly links now
[akaros.git] / kern / arch / riscv / atomic.c
1 #include <atomic.h>
2
3 // This emulates compare and swap by hashing the address into one of
4 // K buckets, acquiring the lock for that bucket, then performing the
5 // operation during the critical section.  :-(
6 bool atomic_comp_swap(uintptr_t *addr, uintptr_t exp_val, uintptr_t new_val)
7 {
8         if (*addr != exp_val)
9                 return 0;
10         
11   #define K 17
12         static spinlock_t cas_locks[K*HW_CACHE_ALIGN/sizeof(spinlock_t)];
13
14   uintptr_t bucket = (uintptr_t)addr / sizeof(uintptr_t) % K;
15         spinlock_t* lock = &cas_locks[bucket*HW_CACHE_ALIGN/sizeof(spinlock_t)];
16         
17         bool retval = 0;
18         spin_lock_irqsave(lock);
19         if (*addr == exp_val) {
20                 atomic_swap(addr, new_val);
21                 retval = 1;
22         }
23         spin_unlock_irqsave(lock);
24         return retval;
25 }