在linux上的Malloc特定地址或页面(指定"最小偏移量")

时间:2015-09-16 06:39:22

标签: c linux pointers memory-management luajit

在Linux上的LuaJIT中,所有VM maaged ram必须低于2GB进程内存边界,因为内部指针总是32位。因此,我想自己管理更大的分配(使用FFI和malloc等),例如适用于大纹理,音频,缓冲区等。

我现在想确保将这些内容映射到上面 2GB boudary,因为这样他们就不会占用任何VM可管理的内存。

有没有办法mallocmmap(没有映射文件,或者可能在SHM中)分配特定于该地址之上的指针?甚至不必占用2gig,只需将指针映射到更高(=非32位)的地址

2 个答案:

答案 0 :(得分:4)

分配2 GB块。如果它位于限制之下,则分配另一个2 GB(这个必须高于2 GB,因为只有一个块的大小可以低于2 GB)。

/* Allocates size bytes at an address higher than address */
void *HighMalloc(size_t size, void *address) {
    size_t mysize = (size_t)address;
    void *y, *x;
    if (mysize < size) {
        mysize = size;
    }
    y = x = malloc(mysize);
    if (x < address) {
        /* The memory starts at a low address. 
         * mysize is so big that another block this size cannot fit 
         * at a low address. So let's allocate another block and 
         * then free the block that is using low memory. */
        x = malloc(mysize);
        free(y);
    }
    return x;
}

注意:

如果size小于address,则第二个malloc的低地址可能有足够的空间。这就是我在这种情况下增加分配大小的原因。所以不要用它来分配小内存块。分配一大块然后手动将它分成小块。

答案 1 :(得分:3)

唯一认为我知道(也许这不是最好的选择)是使用mmap用于Linux。在某些情况下,我必须分配与特定值对齐的大内存块,所以我使用它(因为在这里你可以指定内存块的地址和长度)但它需要实现一些内存管理器单元,因为现在你是将管理分配(和发布)。

void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);

在此查看详细信息:http://man7.org/linux/man-pages/man2/mmap.2.html

要使其未映射到仅将flags设置为MAP_ANONYMOUS的任何文件:

  

MAP_ANONYMOUS

     

任何文件都不支持映射;它的内容是      初始化为零。 fd和offset参数被忽略;      但是,有些实现要求fd为-1      MAP_ANONYMOUS(或MAP_ANON)已指定且可移植      应用程序应确保这一点使用MAP_ANONYMOUS      仅在Linux上支持与MAP_SHARED的结合      内核2.4。

如果addr为NULL,那么系统将为您选择可用的地址,但由于您要将其分配到2G以上,您需要管理已分配页面的列表,以便知道上面使用了哪些地址2G。另请注意,如果您指定addr=X,并且mmap将无法使用此地址,则它将不会失败,它只会选择另一个可以在没有任何失败指示的情况下使用的地址(除了返回指针不等于addr)的事实。但是,您可以使用MAP_FIXED标记来强制执行您提供的地址,如果mmap无法使用它,则会失败(返回MAP_FAILED)。

  

MAP_FIXED

     

不要将addr解释为提示:将映射精确放置    那个地址。 addr必须是页面大小的倍数。如果    addr和len指定的内存区域重叠页面    任何现有的映射,然后是重叠的部分    现有的映射将被丢弃。如果指定的话    地址无法使用,mmap()将失败。因为需要一个    一个映射的固定地址不太便携,使用这个    不鼓励选择。

修改

请注意,建议不要使用MAP_FIXED,因为描述说明

  

如果addr和len指定的内存区域与任何现有映射的页面重叠,则将丢弃现有映射的重叠部分。

你甚至都不知道。更安全地检查addr是否等于mmap地址返回的内容。