合并页面是否允许在mmap中使用?

问题描述 投票:1回答:1

简而言之,我想调整内存大小,但将旧内存放在新内存的中间。

因此,我所做的是使用mmap作为初始大小(p1),在mmap之前的地址使用p1假装我增大了内存,然后将新指针视为与单个mmapp3mremap)。该代码似乎可以正常工作,但是我不确定这是否应该做。如果不是这样,我应该如何创建更多的内存并将旧的/当前的内存放在其中?

#include <sys/mman.h>
#include <cstdio>
#include <cstring>
#include <cassert>
#include <cerrno>
int main()
{
    auto p1 = (char*) mmap(0, 4096, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
    if (!p1 || p1==(char*)-1)
        return -1;

    auto p1_32 = (int *)p1;
    memset(p1, 0, 4096);
    p1_32[5] = 1035;

    auto p2 = mmap(p1-4096, 4096, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED, -1, 0);
    if (!p2 || p2==(void*)-1)
        return -2;

    auto p2_32 = (int *)p2;
    memset(p2, 0, 4096);
    p2_32[5] = 5301;

    assert(p2_32[1024+5] == 1035);

    auto p3 = mremap(p2, 4096*2, 4096*4, MREMAP_MAYMOVE);
    if (p3==(char*)-1)
    {
        printf("Errno %d\n", errno);
        return -2;
    }
    auto p3_32 = (int*)p3;

    assert(p3_32[5] == 5301);
    assert(p3_32[1024+5] == 1035);

    printf("Is this correct?\n");
    return 0;
}
c mmap
1个回答
0
投票

您的代码有问题:如何知道页面(p2)之前的页面(p1)是否未使用?程序的其他参数(包括malloc)可能已经分配了它,可以像这样使用MAP_FIXEDrewrite(重新映射)其内容:

当在flags参数中设置MAP_FIXED时,实现为告知pa的值应准确为addr。如果MAP_FIXED是设置为mmap()可能会返回MAP_FAILED并将errno设置为[EINVAL]。如果一个MAP_FIXED请求成功,由mmap()建立的映射替换范围内流程页面的所有先前映射[pa,pa+len)

因此,在一般情况下,我认为此技巧不会有用,应改为使用mremap

关于这个问题,Linux确实合并了顺序的私有匿名映射,因此两者都将合并到内核中的单个vma_struct中。该“特征”具有不良的副作用,例如[CO]。但这更多的是实现细节,而不是您可以控制的东西。

© www.soinside.com 2019 - 2024. All rights reserved.