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 #include <arch/x86_64/include/asm/cmpxchg.h> 13 14 #define atomic_read(atomic) ((atomic)->value) // 读取原子变量 15 #define atomic_set(atomic, val) (((atomic)->value) = (val)) // 设置原子变量的初始值 16 17 typedef struct 18 { 19 volatile long value; 20 } atomic_t; 21 22 /** 23 * @brief 原子变量增加值 24 * 25 * @param ato 原子变量对象 26 * @param val 要增加的值 27 */ 28 inline void atomic_add(atomic_t *ato, long val) 29 { 30 asm volatile("lock addq %1, %0 \n\t" 31 : "=m"(ato->value) 32 : "m"(val) 33 : "memory"); 34 } 35 36 /** 37 * @brief 原子变量减少值 38 * 39 * @param ato 原子变量对象 40 * @param val 要减少的值 41 */ 42 inline void atomic_sub(atomic_t *ato, long val) 43 { 44 asm volatile("lock subq %1, %0 \n\t" 45 : "=m"(ato->value) 46 : "m"(val) 47 : "memory"); 48 } 49 50 /** 51 * @brief 原子变量自增 52 * 53 * @param ato 原子变量对象 54 */ 55 void atomic_inc(atomic_t *ato) 56 { 57 asm volatile("lock incq %0 \n\t" 58 : "=m"(ato->value) 59 : "m"(ato->value) 60 : "memory"); 61 } 62 63 /** 64 * @brief 原子变量自减 65 * 66 * @param ato 原子变量对象 67 */ 68 void atomic_dec(atomic_t *ato) 69 { 70 asm volatile("lock decq %0 \n\t" 71 : "=m"(ato->value) 72 : "m"(ato->value) 73 : "memory"); 74 } 75 76 /** 77 * @brief 设置原子变量的mask 78 * 79 * @param ato 原子变量对象 80 */ 81 inline void atomic_set_mask(atomic_t *ato, long mask) 82 { 83 __asm__ __volatile__("lock orq %1, %0 \n\t" 84 : "=m"(ato->value) 85 : "r"(mask) 86 : "memory"); 87 } 88 89 /** 90 * @brief 清除原子变量的mask 91 * 92 * @param ato 原子变量对象 93 */ 94 inline void atomic_clear_mask(atomic_t *ato, long mask) 95 { 96 __asm__ __volatile__("lock andq %1, %0 \n\t" 97 : "=m"(ato->value) 98 : "r"(mask) 99 : "memory"); 100 } 101 102 // cmpxchgq 比较并交换 103 inline long atomic_cmpxchg(atomic_t *ato, long oldval, long newval) 104 { 105 bool success = arch_try_cmpxchg(&ato->value, &oldval, newval); 106 return success ? oldval : newval; 107 } 108