glibc&x27的目的是什么;s原子强制读取函数?
我试图理解原子强制读取定义的目的,它经常出现在malloc.c的GNULIBC实现中 对于内联汇编,我并不擅长,但它看起来返回的值与输入值的类型完全相同。我错过了什么 原子.h中的原子强制读取定义glibc&x27的目的是什么;s原子强制读取函数?,c,atomic,glibc,inline-assembly,libc,C,Atomic,Glibc,Inline Assembly,Libc,我试图理解原子强制读取定义的目的,它经常出现在malloc.c的GNULIBC实现中 对于内联汇编,我并不擅长,但它看起来返回的值与输入值的类型完全相同。我错过了什么 原子.h中的原子强制读取定义 523 #ifndef atomic_forced_read 524 # define atomic_forced_read(x) \ 525 ({ __typeof (x) __x; __asm ("" : "=r" (__x) : "0" (x)); __x; }) 526 #endif 链
523 #ifndef atomic_forced_read
524 # define atomic_forced_read(x) \
525 ({ __typeof (x) __x; __asm ("" : "=r" (__x) : "0" (x)); __x; })
526 #endif
链接到atomic.h
一种用法是原子强制读取:
#if HAVE_MALLOC_INIT_HOOK
void (*hook) (void) = atomic_forced_read(__malloc_initialize_hook);
if (hook != NULL)
(*hook)();
#endif
似乎可以从另一个线程更改\uuuuuuMalloc\uInitialize\uHook
,这样,如果\uuuuMalloc\uInitialize\uHook
在NULL
检查后再次从内存加载则其值可能已更改回NULL
atomic\u forced\u read
确保由于=r
输出约束而将\u malloc\u initialize\u hook
加载到寄存器中,以便\u malloc\u initialize\u hook
检查后不会从内存中重新加载\u malloc\u initialize\u hook
。这个空的asm
打破了钩子
对\uu malloc\u initialize\u钩子
的编译器依赖性,因为钩子
现在是用存储在寄存器中的\uuuuuumalloc\u initialize\u钩子
初始化的。用\uuux
初始化钩子后,后者将消失,并且无法重新加载
在C11模式下,\u malloc\u initialize\u hook
可以是原子的\u uintpttr\u t
和原子的\u load\u显式(&\u malloc\u initialize\u hook,memory\u order\u released)
可以用来代替原子的强制读取
从内存加载\u malloc\u initialize\u hook
?!原子强制读取与空指针有什么关系?!顺便说一句,C标准始终要求free(0)
是安全的,什么也不做。曾经有(不合规的和/或1989年以前的)C库会崩溃,但现在你几乎肯定不会遇到这样的库,除非你在做逆向计算。(更多详细信息,请参阅dandan78的链接。)在我看来,它与Linux内核中的ACCESS_ONCE类似。它只是强制读取到寄存器中,但我不知道这与易失性读取相比如何。如果数据已经在寄存器中,它会强制重新加载吗?它会阻止编译器将对目标的访问转换为对源数据的访问吗?@PeterCordes:在malloc中,它用于防止在检查钩子函数指针是否为NULL和调用它之间出现竞争条件。它的目的是访问共享变量,因为您知道访问将是原子的(支持的平台的大小和对齐方式合适),并防止编译器省略/复制您的加载。我只是不知道它到底能提供什么保证,尤其是与不稳定的读取相比。@ninjalj:听起来像是大规模的过度复杂;只需将共享值加载到本地,然后在通过它调用之前检查其是否为非NULL。不需要特殊的魔法来防止空检查优化掉,除非指针在之前或之后被无条件地取消引用。(然后编译器将对其进行优化,因为deref由于UB而意味着非NULL)。OP仍然没有在问题中包括用例,我也没有费心去寻找自己。是的,它“清洗”了\uuu malloc\u initialize\u hook
的值,因此优化器不能决定加载全局代码两次。正如ninjali对这个问题的评论,这表明即使在使用本地(但没有asm
或volatile
)的情况下,S390也会发生这种情况。@PeterCordes您提到的“清洗”,然而,std::launder
是一个非常独特和有限的工具,请参阅。