2012-02-26 3 views
4

Моя основная проблема заключается в том, что мне нужно разрешить нескольким процессам ОС связи через большую кучу общей памяти, которая сопоставляется с одинаковыми диапазонами адресов во всех процессах. (Чтобы убедиться, что значения указателя действительно значимы.)Как обеспечить совместимость malloc и mmap, т. Е. Работать с неперекрывающимися областями памяти?

Теперь я столкнулся с проблемой, что часть программы/библиотеки использует стандартный malloc/free, и мне кажется, что базовая реализация не учитывает сопоставления, которые я создаю с mmap. Или еще один вариант заключается в том, что я создаю сопоставления в регионах, которые malloc уже планировал использовать.

К сожалению, я не могу гарантировать 100% идентичное поведение malloc/free во всех процессах, прежде чем устанавливать mmap-сопоставления.

Это заставляет меня указывать флаг MAP_FIXED в mmap. Первый процесс использует 0x0 в качестве базового адреса, чтобы гарантировать, что диапазон отображения по крайней мере как-то разумный, но, похоже, не передается другим процессам. (Двоичный файл также связан с -Wl, -no_pie.)

Я попытался выяснить, могу ли я запросить систему, какие страницы она планирует использовать для malloc, прочитав malloc_default_zone, но этот API не я предлагаю то, что мне нужно.

Есть ли способ гарантировать, что malloc не использует определенные страницы памяти/адреса?

(Он должен работать на советы OSX Linux, которые направляют меня в правильном направлении оценить, тоже.).

ответ

3

Я заметил это в mmap documentation:

Если MAP_FIXED, то успешный ММАП удаляет все предыдущие отображение в выделенном диапазоне адресов

Однако malloc не будет использовать карты фиксирован, так до тех пор, как вы получите прежде, чем таНос, вы бы хорошо: вы можете проверить, является ли в рег ion бесплатно, сначала попробуйте сопоставить его без MAP_FIXED, и если это удастся с тем же адресом (который он будет делать, если адрес свободен), вы можете переназначить с помощью MAP_FIXED, зная, что вы не выбираете раздел адресного пространства, malloc уже захватил

Единственный гарантированный способ гарантировать, что один и тот же блок логической памяти будет доступен в двух процессах, - это иметь одну вилку от другой.

Однако, если вы компилируете 64-разрядные указатели, вы можете просто выбрать (необычную) область памяти и надеяться на лучшее, так как вероятность столкновения крошечная.

См. Также this question о действующих адресных пространствах.

+0

Самый надежный способ я нашел, к сожалению, не универсален: я был в состоянии перестроить мой Smalltalk VM немного и был в состоянии чтобы избавиться от типичного 'exec()' after' fork() '. Это, естественно, сохраняет mmappings. Однако он поставляется с кучей других компромиссов. – smarr

0

В реализации malloc() для OpenBSD для распределения памяти используется mmap(). Я предлагаю вам посмотреть, как это работает, а затем написать собственную собственную реализацию malloc() и сообщить вашей программе и библиотекам, используемым ею, для использования вашей собственной реализации malloc().

Вот OpenBSD таНос():

http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/lib/libc/stdlib/malloc.c?rev=1.140

RBA

+0

Я думаю, что есть намного более простые решения этой проблемы, чем катить еще один malloc! – James

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