4

所以我有一段代码如下所示:

uint8_t *buffer = <16 MB memory region>
uint32_t count = 1024;
uint32_t position = 0;

uint8_t *get_data() {

    uint8_t *region = buffer + position * 16;

    position += 1;
    position %= count;

    do {
        __sync_synchronize();
    } while (reigon[0] != 1);

    return region;
}

有问题的缓冲区正在由硬件设备写入。在某个时刻(可能在我们开始循环之前,可能在我们开始之后),硬件将写入该位置以及缓冲区的其余部分。

我目前正在使用 __sync_synchronize 来发出内存屏障,因为我想确保编译器不会导致该内存区域的其余部分从之前的任何时间被缓存region[0] == 1

我知道我可以将整个缓冲区标记为易失性。但是,我希望能够从此函数返回一个非易失性缓冲区。

那么,有什么方法可以做 a __sync_synchronize,但只能针对我指定的内存范围。在这种情况下,内存来自[region, region + 1024)

顺便说一句,这段代码存在于用户空间中。内存缓冲区是一个固定的内存区域,我用内核模块分配了它,映射到用户空间,并告诉 FPGA 最终对它进行 DMA。这实质上是在尝试在 FPGA 上实现轮询机制来完成 DMA 传输。

4

2 回答 2

2

区域限制的内存栅栏将是一个相当不寻常的架构特征。但是,您只需要在循环终止后使用栅栏:

while (*(volatile uint8_t *)region != 1)
    ;

__sync_synchronize();
return region;
于 2011-09-30T05:49:21.520 回答
0

这应该可以解决问题:

uint8_t *get_data() {    
    uint8_t *region = buffer + position * 16;
    volatile uint8_t *volatile_region = region;

    position += 1;
    position %= count;

    do {
    } while (volatile_region[0] != 1);

    return region;
}
于 2011-09-30T04:18:04.443 回答