mmap共享缓冲区读取问题

时间:2012-02-07 23:43:09

标签: c++ c linux mmap cpu-cache

我有一个内核模块,它分配一个大的内存缓冲区,然后将这个缓冲区映射到用户空间。
模块从硬件接收一些数据,然后将新数据放入缓冲区,前面有一个标志。 (内存初始化为零,标志为1)。

用户空间程序在返回指向有效数据的指针

之前读取循环中的标志

代码的简化版本:

uint8_t * getData()
{
    while(1)
   {
      if(*((volatile uint32_t*)this->buffer) == 1)
          return this->buffer+sizeof(uint32_t);
   }
}

内存区域映射为共享,完整缓冲区内存转储确认缓冲区已正确写入。

问题是在经过一定数量的正确读取后,此功能会停止返回 这可能是由于CPU缓存?有没有办法规避这一点,并确保每次都直接从RAM进行读取,而不是从缓存中进行读取?

2 个答案:

答案 0 :(得分:0)

是的,这可能是由于读卡器端的cpu缓存造成的。有人可能会认为“volatile”关键字应该可以防止出现这种问题,但这并不完全正确,因为volatile只是指令编译器不注册变量,而不是指导cpu直接从主内存读取每一次。

问题需要在写入方面解决。从您的描述中,它听起来像是在内核模块中发生并从用户端读取。如果这两个操作发生在不同的cpus(不同的缓存域)上,并且没有任何东西可以在读取端触发缓存失效,那么在描述时你将被困在读取端。您需要在存储指令后强制在Linux内核上存储缓冲区刷新。假设它是linux内核,在设置标志后立即插入对smp_mb的调用,并且模块中的值很可能在所有体系结构上做正确的事情。

答案 1 :(得分:0)

提醒用户空间应用程序存在更多数据的更好方法是让它在read()中阻塞内核模块提供的文件描述符,内核模块在更多数据被唤醒时将其唤醒可用。