Ответ 1
msync (addr, len, 0) и проверка для ENOMEM, похоже, работает (с довольно поверхностным тестом).
Я хотел бы определить, была ли определенная страница уже отображена в памяти. Цель здесь - выполнить эту проверку перед вызовом 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: есть ли такая вещь?
msync (addr, len, 0) и проверка для ENOMEM, похоже, работает (с довольно поверхностным тестом).
Это не "переназначает" память, а создает другое сопоставление на другом адресе (так как тот, который вы даете, уже сделан, и в любом случае он рассматривается как подсказка). Старый все еще действителен, вы просто теряете ссылку на него, поскольку вы перезаписываете переменную ptr
.
Если вы хотите создать несколько сопоставлений в той же памяти, что и в shm_open(2)
.
Если вы просто хотите проверить, отображается ли адрес, то трюк MAP_FIXED
, на который указывает @MerickOWA, должен работать.
Вы правы в отношении MAP_FIXED
, в этом случае это не помогает. Вы можете попробовать mincore(2)
. Одна из ошибок, которые он возвращает:
ENOMEM
addr to addr + length contained unmapped memory.
В QNX вы можете использовать mem_offset()
и posix_mem_offset()
и проверьте содержимое contig_len
на выходе, сравнив его с входным параметром length
.