Как выделить буферы памяти, которые ОС может использовать для кэширования в расширении ядра Mac OS X? - PullRequest
5 голосов
/ 21 января 2011

Исходя из прочитанной документации и источника xnu, я понимаю, что Mac OS X кэширует файл ввода-вывода с использованием унифицированного буферного кэша (UBC).UBC увеличивается настолько, насколько это возможно, в зависимости от доступной оперативной памяти, но страницы UBC являются одними из первых, которые приносятся в жертву, когда память становится плотнее.

В моем драйвере я имею дело с различными метаданными на диске.Я хотел бы иметь возможность использовать UBC или аналогичный механизм для хранения кэшей MRU этих данных, чтобы ускорить процесс, и в то же время дать ядру возможность забирать эту память всякий раз, когда это необходимо.Однако метаданные не представляют данные file и поэтому не попадают непосредственно в домен UBC.Есть ли механизм более низкого уровня, который я могу использовать, или я могу каким-то образом использовать только ту часть UBC, которая имеет дело с самими буферами?

В настоящее время я искал исходный код HFS +, чтобы попытаться выяснить,кэширует ли она метаданные файловой системы, хотя и без особого успеха.

Конечно, главная альтернатива - зарезервировать определенную область памяти для кэшей и выполнить мой выбор LRU.Я могу выбрать фиксированный размер кэша или использовать какую-то эвристику, но она всегда будет использовать слишком мало памяти, когда ОЗУ много, и слишком много, когда ее нет.

Обновление:

После поиска еще, я обнаружил, что экземпляры IOBufferMemoryDescriptor могут быть созданы с опцией kIOMemoryPurgeable.Это позволяет вам вызывать IOMemoryDescriptor::setPurgeable(), чтобы пометить в памяти «честную игру» для сброса.Я попробую и обновлю вопрос с результатами.

1 Ответ

3 голосов
/ 01 июня 2011

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

Если вы хотите, чтобы ОС отказалась от него, вызовите setPurgeable(kIOMemoryPurgeableVolatile, &oldState );, и ОС при необходимости отменит его, а неподкачки на диск.

Если вы хотите получить доступ к памяти, вы должны вызвать setPurgeable(kIOMemoryPurgeableKeepCurrent, &oldState ); и проверить if(oldState != kIOMemoryPurgeableEmpty), которая будет иметь значение true, если память все еще доступна, и false, если она была удалена.

Мне было бы интересно услышать, столкнулись ли вы с какими-либо уловами.

...