1 /**
2  * @file atomic.h
3  * @author fslongjin (longjin@RinGoTek.cn)
4  * @brief 原子变量
5  * @version 0.1
6  * @date 2022-04-12
7  *
8  * @copyright Copyright (c) 2022
9  *
10  */
11 #pragma once
12 
13 #define atomic_read(atomic)	((atomic)->value)   // 读取原子变量
14 #define atomic_set(atomic,val)	(((atomic)->value) = (val)) // 设置原子变量的初始值
15 
16 typedef struct
17 {
18     volatile long value;
19 } atomic_t;
20 
21 /**
22  * @brief 原子变量增加值
23  *
24  * @param ato 原子变量对象
25  * @param val 要增加的值
26  */
atomic_add(atomic_t * ato,long val)27 inline void atomic_add(atomic_t *ato, long val)
28 {
29     asm volatile("lock addq %1, %0 \n\t"
30                  : "=m"(ato->value)
31                  : "m"(val)
32                  : "memory");
33 }
34 
35 /**
36  * @brief 原子变量减少值
37  *
38  * @param ato 原子变量对象
39  * @param val 要减少的值
40  */
atomic_sub(atomic_t * ato,long val)41 inline void atomic_sub(atomic_t *ato, long val)
42 {
43     asm volatile("lock subq %1, %0  \n\t"
44                  : "=m"(ato->value)
45                  : "m"(val)
46                  : "memory");
47 }
48 
49 /**
50  * @brief 原子变量自增
51  *
52  * @param ato 原子变量对象
53  */
atomic_inc(atomic_t * ato)54 void atomic_inc(atomic_t *ato)
55 {
56     asm volatile("lock incq %0   \n\t"
57                  : "=m"(ato->value)
58                  : "m"(ato->value)
59                  : "memory");
60 }
61 
62 /**
63  * @brief 原子变量自减
64  *
65  * @param ato 原子变量对象
66  */
atomic_dec(atomic_t * ato)67 void atomic_dec(atomic_t *ato)
68 {
69     asm volatile("lock decq %0 \n\t"
70                  : "=m"(ato->value)
71                  : "m"(ato->value)
72                  : "memory");
73 }
74 
75 /**
76  * @brief 设置原子变量的mask
77  *
78  * @param ato 原子变量对象
79  */
atomic_set_mask(atomic_t * ato,long mask)80 inline void atomic_set_mask(atomic_t *ato, long mask)
81 {
82     __asm__ __volatile__("lock	orq	%1,	%0	\n\t"
83                          : "=m"(ato->value)
84                          : "r"(mask)
85                          : "memory");
86 }
87 
88 /**
89  * @brief 清除原子变量的mask
90  *
91  * @param ato 原子变量对象
92  */
atomic_clear_mask(atomic_t * ato,long mask)93 inline void atomic_clear_mask(atomic_t *ato, long mask)
94 {
95     __asm__ __volatile__("lock	andq	%1,	%0	\n\t"
96                          : "=m"(ato->value)
97                          : "r"(mask)
98                          : "memory");
99 }
100