2016-01-01 2 views
5

У меня есть набор файлов, длина которых кратна размеру моей операционной системы (FreeBSD 10). Я хотел бы до mmap() этих файлов на последовательные страницы ОЗУ, давая мне возможность обрабатывать коллекцию файлов как один большой массив данных.Как найти отверстия в адресном пространстве?

Предпочтительно использовать портативные функции, как я могу найти достаточно большую область немаркированного адресного пространства, поэтому я могу быть уверен, что серия вызовов mmap() в этом регионе будет успешной?

+0

Могу я узнать, что вы делаете? – Downvoter

+0

@cad См. Первый абзац. В принципе, у меня есть набор данных, который разделен на несколько файлов, и я хочу отобразить его в область непрерывной памяти, чтобы рассматривать его как единое целое. – fuz

+0

Можете ли вы 'mmap()' первый файл, позволяющий o/s выбрать адрес для вас, а затем попытаться сопоставить другие файлы с ним? Я бы ожидал, что это будет работать достаточно хорошо, но я не тестировал его ни в одной системе, и меньше всего FreeBSD 10. –

ответ

5

Выполните следующие действия:

  1. Во-первых вычислить общий размер, необходимый перечисления файлов и суммируя их размеры.
  2. Создайте единую область анонимной памяти такого размера с помощью mmap. Если это не удается, вы проиграете.
  3. Сохраните указатель и unmap область (на самом деле, unmap может не понадобиться, если ваш mmap вашей системы с фиксированным адресом неявно удаляет любую ранее перекрывающуюся область).
  4. Соедините первый файл по указанному адресу соответствующим фразу MAP_FIXED.
  5. Увеличьте адрес на размер файла.
  6. перейдите к шагу 4, пока все файлы не пострадали.

Это должно быть полностью переносимым для любой системы POSIX, но некоторые ОС могут иметь причуды, которые предотвращают этот метод. Попробуй.

+1

Отличная идея!Чтобы получить начальное сопоставление зондов, я могу создать разреженный файл нужной длины и отобразить его, поскольку моя операционная система не позволит мне отображать больше анонимной памяти, чем у меня есть ОЗУ (насколько мне известно). – fuz

+0

@FUZxxl: Хороший момент, я не думал об этом специальном случае. – chqrlie

+2

О да, вам даже не нужно снимать область - «ммм» с радостью сопоставляет ее с «MAP_FIXED», насколько мне известно. – fuz

1

Вы можете mmap большой регион, где размер является суммой размеров всех файлов, используя MAP_PRIVATE | MAP_ANON, и защиту PROT_NONE, которая помешала бы ОС из-за излишней фиксации зарядов памяти.

Это зарезервирует, но не зафиксирует память.

После этого вы можете открыть файл filename1 по адресу [baseAddr, size1) и открыть filename2 по адресу [baseAddr + size1, baseAddr + size1 + size2) и так далее.

Я считаю, что флагами для этого являются MAP_FIXED | MAP_PRIVATE.

+0

У FreeBSD нет 'MAP_NORESERVE'. – fuz

+0

Читайте внимательно. Это манга из SunOS 5.10. – fuz

+0

Я считаю, что это все равно должно работать без 'MAP_NORESERVE'. Это также вызовет резервирование пространства подкачки, что часто не является проблемой. –

Смежные вопросы