Есть задача хранить данные, размером по 192 байта, которые приходят в драйвер (DeviceIoControl). Данные храняться в неподкачиваемом пуле. Естественно могу выделяить память (ExAllocatePool) но память выделяется размером в 1-у страницу (4 кб.) - не экономно, тем более в ядре. Сколько "кусков" придет в драйвер не известно. Есть мысли как правильно поступить и экономно расходовать память? Или какой-то алгоритм работы в данной ситуации ?
А разве при выделении меньше страницы ExAllocatePool выделяет целую страницу? Из MSDN: Вроде как, система умудряется впихать несколько буферов в страницу...
Может свой минименеджер памяти написать. Например, пространство выделенной страницы, организуется как массив из 21 элементов по 192 байта, плюс массив из 21 однобайтных значений сигнализирующих какие элементы выделены. При фиксированном размере блока, имхо их лучше всегда выделять массивами - например если с помощью malloc попытаться выделить под переменную 4 байта, всего будет захвачено порядка 40-50 байт, из которых только 4 доступны.
Ядерная куча организована в виде нескольких ассоциативных списков разного размера, хранящихся в структуре KPCR: Код (Text): kd> !kdex2x86.strct KPCR struct _KPCR (sizeof=2832) . . . +620 struct _PP_LOOKASIDE_LIST PPLookasideList[16] struct _NPAGED_LOOKASIDE_LIST *P struct _NPAGED_LOOKASIDE_LIST *L +6a0 struct _PP_LOOKASIDE_LIST PPNPagedLookasideList[8] struct _NPAGED_LOOKASIDE_LIST *P struct _NPAGED_LOOKASIDE_LIST *L +6e0 struct _PP_LOOKASIDE_LIST PPPagedLookasideList[8] struct _NPAGED_LOOKASIDE_LIST *P struct _NPAGED_LOOKASIDE_LIST *L . . . kd> При вызове ExAllocatePoolXxx система смотрит запрашиваемый размер, если он подходит под один из списков, то оттуда и выделяется память (+небольшой оверхед на управляющую информацию). Если запрашиваемый размер больше самого большого из ассоциативных списков, то тогда уже выделение идет страницами.