【问题标题】:How to allocate a region of memories which similar VirtualAlloc?如何分配一个类似VirtualAlloc的内存区域?
【发布时间】:2011-08-30 11:05:14
【问题描述】:

我正在寻找一种在 Linux 上分配内存的方法,类似于 Windows 上的 VirtualAlloc。要求是:

  1. 要分配的内存块大小为 2^16。
  2. 内存块地址大于0x0000ffff
  3. 内存块地址的最后 16 位必须为零。

在 Windows 上,因为应用程序地址的下限 (lpMinimumApplicationAddress) 我们有 (2) 明显的权利。从(1)、(2)和系统规则我们也实现了(3)。

感谢您的帮助。

【问题讨论】:

  • @Ignacio:通常用于 DMA。这(间接)是直接 I/O 函数通常需要对齐缓冲区的原因。
  • 用户代码在为 DMA 分配内存做什么?
  • @Ignacio:我刚刚告诉过你:直接(无缓冲)I/O。在 Windows 上为 FILE_FLAG_NO_BUFFERING。不确定它是如何在 Linux 上完成的,但内核只是锁定您提供的缓冲区并将其用于 DMA,而不是从 DMA 反弹缓冲区复制。 “零拷贝 I/O”需求量很大。
  • @Ignacio:对于#3,我正在尝试实现内存池。我可以通过 (blockPtr & 0xffff0000) 获得块的地址。这在释放块时很有用。

标签: linux virtualalloc


【解决方案1】:

试试mmap(..., MAP_ANONYMOUS, ...)

您将获得一个与页面边界对齐的地址。对于比这更严格的对齐方式,您可能需要分配额外的空间并在比正确对齐方式更大的块内选择一个地址。

【讨论】:

  • 谢谢,但是如何获得(2)和(3)呢?。
  • @Giang:#2 发生了,操作系统保留前几页内存以帮助检测 NULL 指针。对于#3,如果您分配 217 个字节,则可以保证在分配区域某处的 2**16 边界上开始有一个 216 的块。或者,正如@sherpya 所说,您可以请求一个满足您要求的地址。如果尚未使用,您将获得您请求的确切地址。
  • 谢谢,但这样做似乎太浪费了。能否告诉 mmap 我们想要的内存地址的下限?
  • @Giang:你读过mmap 的手册页吗?它实际上非常具有描述性。
  • 是的,我什至在问这个问题之前就阅读了它。提示参数不是真的是一个下限。
【解决方案2】:

你想要posix_memalign():

void *ptr;
int memalign_err = posix_memalign(&ptr, 1UL << 16, 1UL << 16);

if (memalign_err) {
    fprintf(stderr, "posix_memalign: %s\n", strerror(memalign_err));
} else {
    /* ptr is valid */
}

第一个1UL &lt;&lt; 16是对齐方式,第二个是大小。

当你完成块后,你将它传递给free()

【讨论】:

    【解决方案3】:

    你可以要求一个特定的地址来mmap,对于某些特定的地址可能会失败,但通常它可以工作

    【讨论】:

    • 但是这个分配我做了很多次,无法预知具体的地址是什么合适的。
    • vm.mmap_min_addr 通过 proc 接口,但它是全局内核设置
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-07-18
    • 2014-05-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-21
    • 2011-08-25
    相关资源
    最近更新 更多