Частичное распаковка файла сопоставления памяти Win32 - PullRequest
0 голосов
/ 08 сентября 2010

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

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

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

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

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

редактирование:

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

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

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

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

Ответы [ 2 ]

2 голосов
/ 08 сентября 2010

Это довольно явно указано в документах библиотеки MSDN для UnmapViewOfFile:

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

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

Вам придется сделать это по-другому.

0 голосов
/ 16 сентября 2010

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

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

...