[toc]
include/asm-generic/rwonce.h: 提供 READ_ONCE() 和 WRITE_ONCE() 宏,防止编译器优化,保证单次读写的原子性
1 | /* |
compiletime_assert_rwonce_type
__native_word
是一个宏,用于检查给定类型是否是本机字长(通常是 32 位或 64 位)。如果类型不是本机字长,则检查它的大小是否为sizeof(long long)
,即 64 位。这个宏通常用于确保在进行原子操作时,数据类型的大小与系统架构相匹配。
1 | /* 是的,这允许在 32 位架构上进行 64 位访问。在某些情况下,这些实际上是原子的(即 Armv7 + LPAE),但对于其他情况,我们依赖于将访问分成 2x32 位访问,以获得 32 位数量(例如虚拟地址)和强大的盛行风。 |
READ_ONCE 保证原子性读取
READ_ONCE
是一个宏,用于在多线程环境中安全地读取变量的值。它确保读取操作是原子的,即不会被其他线程的写入操作打断。这对于避免数据竞争和确保数据一致性非常重要。compiletime_assert_rwonce_type
是一个编译时断言,用于检查传入的变量类型是否符合要求。它确保变量是原子类型或具有与长整型相同的大小。这有助于在编译时捕获潜在的错误,确保代码的正确性和安全性。__READ_ONCE
是一个底层实现,用于执行实际的读取操作。它使用了__unqual_scalar_typeof
来获取变量的类型,并将其转换为const volatile
指针,以确保读取操作是原子的。
1 | /* |
include/asm-generic/irqflags.h 提供中断标志位的通用操作函数
arch_irqs_disabled_flags 判断中断是否被禁用
1 | /* test flags */ |
arch_irqs_disabled
1 | /* test hardware interrupt enable bit */ |
include/linux/irqflags.h 包含特定于体系结构的 irqflags.h,提供中断开关等操作
kernel/locking/irqflag-debug.c
1 | noinstr //禁止内联插桩的段 |
raw_check_bogus_irq_restore 检查中断恢复
1 |
|
local_irq_save 返回当前中断状态并禁用中断
- 返回当前的中断状态,并将其保存到 flags 变量中。
- 执行中断禁止操作
local_irq_restore 恢复中断状态
- 恢复之前保存的中断状态,允许中断再次发生。
include/linux/instruction_pointer.h: 提供获取当前指令指针(IP)的宏
RET_IP 返回地址
1 | /* |
THIS_IP 当前指令地址
_THIS_IP_
是一个宏,用于获取当前指令的地址。它通常用于调试和错误处理,以便在发生异常或错误时记录当前指令的地址。- 具体来说,THIS_IP 被定义为一个复合语句表达式
({ __label__ __here; __here: (unsigned long)&&__here; })
。复合语句表达式是 GCC 的一种扩展语法,允许在表达式中包含多个语句。 - 在这个复合语句表达式中,首先定义了一个局部标签
__here
,这是通过__label__
关键字实现的。局部标签是一种特殊的标签,只在当前复合语句表达式的作用域内有效。 - 接下来,表达式使用了标签
__here
,并通过&&__here
获取该标签的地址。标签地址运算符&&
是GCC
的一个扩展,用于获取标签的地址。然后,将这个地址强制转换为unsigned long
类型。 - 最终,这个宏
_THIS_IP_
提供了一种方法来获取当前代码位置的地址,并将其转换为unsigned long
类型。这在调试和分析代码执行路径时可能非常有用,因为它允许程序员获取当前执行点的地址。
1 |
include/asm-generic/topology.h 提供描述CPU拓扑结构(如节点、核心)的通用定义
cpu_to_node
1 |
|
include/linux/topology.h 包含特定于体系结构的CPU拓扑信息
numa_node_id
1 | static inline int numa_node_id(void) |
arch/arm/include/asm/word-at-a-time.h: ARM架构下用于一次性处理一个字(word)数据的优化函数
WORD_AT_A_TIME_CONSTANTS 一次单词常量
1 |
has_zero 检查一个无符号长整数 a 是否包含零字节,并返回一个掩码表示零字节的位置
1 | static inline unsigned long has_zero(unsigned long a, unsigned long *bits, |
prep_zero_mask zero_bytemask
1 |
create_zero_mask
1 | static inline unsigned long create_zero_mask(unsigned long bits) |
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 wdfk-prog的个人博客!
评论