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

Я хотел бы определить, была ли определенная страница уже отображена в памяти.Цель здесь - выполнить эту проверку перед вызовом 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: есть ли такая вещь?

Ответы [ 3 ]

7 голосов
/ 03 декабря 2011

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

3 голосов
/ 03 декабря 2011

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

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

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

Редактировать 0:

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

ENOMEMaddr to addr + length contained unmapped memory.

0 голосов
/ 24 июля 2015

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

...