物理页面的多个映射

Multiple mappings for a physical page

我想创建一个类似写时复制的接口,用于访问 GNU C 中的 mmap()ed 文件。这是它应该工作的方式:

  1. 我将使用 mmap() 将文件映射到地址 space。这样做,我将有一个指向包含真实数据的连续内存区域的指针。
  2. 使用某种魔法,我将使地址的另一部分 space 指向完全相同的物理页面。换句话说,我将有两个不同的地址来访问 mmap()ed 区域内存中的任何物理页面。
  3. 一旦指令尝试使用第二个映射写入页面,我将更改该特定页面的映射以指向不同的物理页面(我将以按需方式创建)。
  4. 在某些时候,我会将脏页与最初映射的页同步,并将别名更改为指向内存映射页。

这里的问题是:执行此操作的最佳方法是什么?

仍然不完全清楚您的具体要求。但这里有一些我看到的选项。

让 mmap 使用 MAP_PRIVATE 为您处理 COW。然后,当您准备好同步时,只需为原始文件创建一个常规 mmap(或直接打开文件),然后与修改后的 MAP_PRIVATE 页面进行同步。

这不允许您知道 MAP_PRIVATE 页面是否实际被修改过。如果你想要那样(例如,这样你就可以优化并且除非页面已更改,否则不进行同步)那么你可以将 MAP_PRIVATE 页面设置为只读。首次访问时将出现 SEGV。使用信号处理程序捕获该 SEGV 并将 MAP_PRIVATE 页面重新映射为可写,并在内部将其标记为脏。

最后,如果您不想使用 MAP_PRIVATE 并想要完全复制控制,请不要使用 MMAP_PRIVATE,而是执行只读映射和信号处理程序。在信号处理程序中,分配一些内存,复制原始页面并重新映射错误页面。

希望一切都有意义。