Подтвердить что ты не робот

Как я могу определить, отображается ли конкретная страница в памяти?

Я хотел бы определить, была ли определенная страница уже отображена в памяти. Цель здесь - выполнить эту проверку перед вызовом mmap с фиксированным адресом памяти. Следующий код иллюстрирует, что происходит в этом случае по умолчанию: mmap молча переназначает исходные страницы памяти.

#include <sys/mman.h>
#include <stdio.h>
#include <unistd.h>

int main(int argc, char *argv[])
{
  int page_size;
  void *ptr;
  page_size = getpagesize();
  ptr = mmap(0, 10 * page_size, PROT_READ | PROT_WRITE,
             MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
  if (ptr == MAP_FAILED) {
    printf ("map1 failed\n");
    return 1;
  }
  ((int *)ptr)[0] = 0xdeadbeaf;
  ptr = mmap(ptr, 2 * page_size, PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, 0, 0);
  if (ptr == MAP_FAILED) {
    printf ("map2 failed\n");
    return 1;
  }
  if (((int *)ptr)[0] != 0xdeadbeaf) {
    printf ("oops, data gone !\n");
  }
  return 0;
}

Я понимаю, что я мог открывать и анализировать /proc/self/maps, чтобы определить, какой диапазон памяти был выделен, и сделать вывод из этого, если я могу безопасно запросить определенный диапазон памяти с помощью mmap, но я ищу подходящий API: есть ли такая вещь?

4b9b3361

Ответ 1

msync (addr, len, 0) и проверка для ENOMEM, похоже, работает (с довольно поверхностным тестом).

Ответ 2

Это не "переназначает" память, а создает другое сопоставление на другом адресе (так как тот, который вы даете, уже сделан, и в любом случае он рассматривается как подсказка). Старый все еще действителен, вы просто теряете ссылку на него, поскольку вы перезаписываете переменную ptr.

Если вы хотите создать несколько сопоставлений в той же памяти, что и в shm_open(2).

Если вы просто хотите проверить, отображается ли адрес, то трюк MAP_FIXED, на который указывает @MerickOWA, должен работать.

Изменить 0:

Вы правы в отношении MAP_FIXED, в этом случае это не помогает. Вы можете попробовать mincore(2). Одна из ошибок, которые он возвращает:

ENOMEM addr to addr + length contained unmapped memory.

Ответ 3

В QNX вы можете использовать mem_offset() и posix_mem_offset() и проверьте содержимое contig_len на выходе, сравнив его с входным параметром length.