编译器提供头文件 mbarrier.h,此头文件中针对 SPARC 和 x86 处理器定义了多种内存边界内部函数。这些内部函数可在开发者使用自己的同步基元编写多线程代码时使用。请参阅相应的处理器文档,以确定在特定情况下是否需要以及何时需要使用这些内部函数。
mbarrier.h 头文件支持以下内存排序内部函数:
__machine_r_barrier()-这是读取边界。它确保边界前的所有装入操作能够在边界后的所有装入操作之前完成。
__machine_w_barrier()-这是写入边界。它确保边界前的所有存储操作能够在边界后的所有存储操作之前完成。
__machine_rw_barrier()-这是读写边界。它确保边界前的所有装入和存储操作能够在边界后的所有装入和存储操作之前完成。
__machine_acq_barrier()-这是具有获取语义的边界。它确保边界前的所有装入操作能够在边界后的所有装入和存储操作之前完成。
__machine_rel_barrier()-这是具有释放语义的边界。它确保边界前的所有装入和存储操作能够在边界后的所有存储操作之前完成。
__compiler_barrier()-阻止编译器跨边界移动内存访问。
内部函数 __compiler_barrier() 出现异常的所有边界内部函数生成内存排序指令,在 x86 上这些指令是 mfence、sfence 或 lfence 指令,而在 SPARC 平台上这些指令是 membar 指令。
__compiler_barrier() 内部函数不会生成指令,但会通知编译器所有以前的内存操作必须在启动任何后续内存操作之前完成。所产生的实际结果为:具有 static 存储类说明符的所有非局部变量和局部变量都将在边界之前存储回到内存,然后在边界之后重新装入,编译器不会将边界之前的内存操作与边界之后的内存操作弄混。所有其他的边界均隐含 __compiler_barrier() 内部函数的行为。
例如,在以下代码中 __compiler_barrier() 内部函数的存在将阻止编译器合并两种循环:
#include "mbarrier.h" int thread_start[16]; void start_work() { /* Start all threads */ for (int i=0; i<8; i++) { thread_start[i]=1; } __compiler_barrier(); /* Wait for all threads to complete */ for (int i=0; i<8; i++) { while (thread_start[i]==1){} } }