550W Document
550W, a high-end OS
atomic.h
浏览该文件的文档.
1 #pragma once
2 
3 /* from linux/arch/riscv/include/asm/cmpxchg.h */
4 
5 #include <common/types.h>
6 
7 static inline uint32_t atomic_swap(uint32_t val, ptr_t mem_addr) {
8  uint32_t ret;
9  __asm__ __volatile__("amoswap.w.aqrl %0, %2, %1\n" : "=r"(ret), "+A"(*(uint32_t *)mem_addr) : "r"(val) : "memory");
10  return ret;
11 }
12 
13 static inline uint64_t atomic_swap_d(uint64_t val, ptr_t mem_addr) {
14  uint64_t ret;
15  __asm__ __volatile__("amoswap.d.aqrl %0, %2, %1\n" : "=r"(ret), "+A"(*(uint64_t *)mem_addr) : "r"(val) : "memory");
16  return ret;
17 }
18 
19 static inline int fetch_add(volatile void *obj, int arg) {
20  uint32_t ret;
21  __asm__ __volatile__("amoadd.w.aqrl %0, %2, %1\n" : "=r"(ret), "+A"(*(uint32_t *)obj) : "r"(arg) : "memory");
22  return ret;
23 }
24 
25 static inline uint32_t atomic_load(volatile uint32_t *obj) {
26  uint32_t arg = UINT32_MAX;
27  uint32_t ret;
28  __asm__ __volatile__("amoand.w.aqrl %0, %2, %1\n" : "=r"(ret), "+A"(*(uint32_t *)obj) : "r"(arg) : "memory");
29  return ret;
30 }
31 
32 /* if *mem_addr == old_val, then *mem_addr = new_val, else return *mem_addr */
33 static inline uint32_t atomic_cmpxchg(uint32_t old_val, uint32_t new_val, ptr_t mem_addr) {
34  uint32_t ret;
35  register unsigned int __rc;
36  __asm__ __volatile__("0: lr.w %0, %2\n"
37  " bne %0, %z3, 1f\n"
38  " sc.w.rl %1, %z4, %2\n"
39  " bnez %1, 0b\n"
40  " fence rw, rw\n"
41  "1:\n"
42  : "=&r"(ret), "=&r"(__rc), "+A"(*(uint32_t *)mem_addr)
43  : "rJ"(old_val), "rJ"(new_val)
44  : "memory");
45  return ret;
46 }
47 
48 /* if *mem_addr == old_val, then *mem_addr = new_val, else return *mem_addr */
49 static inline uint64_t atomic_cmpxchg_d(uint64_t old_val, uint64_t new_val, ptr_t mem_addr) {
50  uint64_t ret;
51  register unsigned int __rc;
52  __asm__ __volatile__("0: lr.d %0, %2\n"
53  " bne %0, %z3, 1f\n"
54  " sc.d.rl %1, %z4, %2\n"
55  " bnez %1, 0b\n"
56  " fence rw, rw\n"
57  "1:\n"
58  : "=&r"(ret), "=&r"(__rc), "+A"(*(uint64_t *)mem_addr)
59  : "rJ"(old_val), "rJ"(new_val)
60  : "memory");
61  return ret;
62 }
uint64_t ptr_t
Definition: types.h:44
#define UINT32_MAX
Definition: types.h:176