2010-09-08 5 views
0

У меня есть код (который я не могу изменить), который мне нужен, чтобы работать в среде Win32. Этот код вызывает mmap() и munmap(), поэтому я создал эти функции, используя CreateFileMapping(), MapViewOfFile() и т. Д., Чтобы выполнить то же самое. Первоначально это работает отлично, и код может получить доступ к файлам, как ожидалось. К сожалению, код переходит к munmap() выбранным частям файла, который больше не нужен.Частичный unmap файла с отображением памяти Win32

x = mmap(0, size, PROT_READ, MAP_SHARED, fd, 0); 
... 
munmap(x, hdr_size); 
munmap(x + foo, bar); 
... 

К сожалению, когда вы передаете указатель на середину преобразованного диапазона UnmapViewOfFile() она разрушает все отображение. Хуже того, я не могу понять, как я смогу обнаружить, что это частичный запрос на карту, и просто игнорируйте его.

Я попытался позвонить по номеру VirtualFree(), но, неудивительно, это производит ERROR_INVALID_PARAMETER.

Я начинаю думать, что я должен буду использовать статический/глобальные переменные для отслеживания всех открытых отображений памяти, так что я могу обнаружить и игнорировать частичный unmappings, но я надеюсь, что у вас есть идея получше ...

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

Поскольку я недостаточно четко указывал выше, документы для UnMapViewOfFile не точно отражают поведение этой функции.

Отсортировать весь вид и переназначить фрагменты не является хорошим решением, потому что вы можете только предложить базовый адрес для нового сопоставления, вы не можете его контролировать. Семантика munmap() не позволяет изменить базовый адрес неподвижной части.

Что мне действительно нужно, это найти базовый адрес и размер уже нанесенной области памяти.

edit2: Теперь, когда я повторяю проблему таким образом, похоже, что функция VirtualQuery() будет достаточной.

ответ

2

Это довольно явно в документации MSDN Library для UnmapViewOfFile:

lpBaseAddress
Указатель на базовый адрес отображенной зрения файла, который должен быть некартированных. Это значение должно соответствовать идентичным значению , возвращенному по предыдущему вызову функции MapViewOfFile или MapViewOfFileEx .

Вы меняете картографию, выбирая старую и создавая новую. Unmapping бит и куски не поддерживается, и не имеет никаких полезных побочных эффектов с точки зрения управления памятью. Вы не хотите рисковать, чтобы адресное пространство было фрагментировано.

Вам нужно будет сделать это по-другому.

+0

Ах, если только документация может считаться точным. Я надеялся, что частичные un-сопоставления просто потерпят неудачу, как это видно из того, что вы цитировали, но это не так. –

+0

Я тоже удивлен. Просто никогда не пробовал это раньше. –

+0

Выполнение бесплатного() на указателе в середине выделенного блока не просто терпит неудачу :-) – 2010-09-29 14:58:31

0

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

Создайте глобальный словарь для сопоставлений памяти через этот интерфейс. Когда приходит запрос сопоставления, запишите адрес, размер и количество страниц, находящихся в диапазоне. Когда выполняется запрос unmap, выясните, какое сопоставление владеет этим адресом и уменьшает количество страниц на количество освобождаемых страниц. Когда это число достигнет нуля, действительно отмените отображение.

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