Oracle® Solaris Studio 12.4:C 用户指南

退出打印视图

更新时间: 2014 年 12 月
 
 

3.6 内存屏障内部函数

编译器提供头文件 mbarrier.h,此头文件中针对 SPARC 和 x86 处理器定义了多种内存边界内部函数。这些内部函数可在开发者使用自己的同步基元编写多线程代码时使用。开发者应参阅处理器文档,以确定在特定情况下是否需要以及何时需要使用这些内部函数。

mbarrier.h 头文件支持的内存排序内部函数包括:

  • __machine_r_barrier()-这是读取边界。它确保边界前的所有装入操作能够在边界后的所有装入操作之前完成。

  • __machine_w_barrier()-这是写入边界。它确保边界前的所有存储操作能够在边界后的所有存储操作之前完成。

  • __machine_rw_barrier()-这是读写边界。它确保边界前的所有装入和存储操作能够在边界后的所有装入和存储操作之前完成。

  • __machine_acq_barrier()-这是具有 acquire 语义的边界。它确保边界前的所有装入操作能够在边界后的所有装入和存储操作之前完成。

  • __machine_rel_barrier()-这是具有 release 语义的边界。它确保边界前的所有装入和存储操作能够在边界后的所有存储操作之前完成。

  • __compiler_barrier()-阻止编译器跨边界移动内存访问。

__compiler_barrier() 内部函数之外的所有边界内部函数都将生成内存排序指令。在 x86 平台上,这些指令为 mfencesfencelfence 指令。在 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){}
   }
}