Менеджер памяти в 3ОС

Немного теории

Менеджер памяти (далее VMM -- virtual memory manager) является неотъемлемой и наиболее важной частью любой операционной системы, именно поэтому разработка VMM является одной из основных задач. В мультизадачной операционной системе, когда в памяти загружены сразу несколько программ, защита одних программ от ошибок в других является приоритетной задачей, также эффективное разделение памяти позволяет увеличить быстродействие всей системы в целом. В древних системах разделение памяти выполнялось с помощью так называемых оверлеев. Их использование доставляло программистам очень много неудобств. С течением времени стали появляться новые, более эффективные и удобные модели памяти. Наиболее известными и распространёнными стали сегментная, страничная и сегментно-страничная модели памяти.

Схематичные наброски

Я думаю, что рассматривать применение сегментной модели памяти в 3ОС, современной и крутейшей системе не имеет смысла, так как эта модель уже давно морально устарела. Сегментно-страничная модель памяти, по моему мнению, не слишком хорошо подходит для 3ОС, потому что 3ОС первоначально разрабатывается для семейства процессоров Intel x86, а в этом семействе имеется не слишком хорошая поддержка данной модели, тем более, что сегментно-страничная модель сложна в реализации и требует значительных затрат ресурсов. Поэтому далее я буду рассматривать только страничную модель памяти вкупе с менеджером памяти.

Менеджер виртуальной памяти (он же VMM) будет реализован в виде модуля, который будет взаимодействовать непосредственно только с ядром 3ОС. Разработка VMM в виде модуля имеет сразу несколько преимуществ. Во-первых, можно реализовать два модуля VMM: первый будет реализовывать страничную модель, а второй сегментно-страничную. Таким образом, можно будет выбирать, какая модель больше подходит для ваших нужд. Во-вторых, разработка VMM в виде модуля будет удовлетворять концепции 3ОС :-) Основным классом менеджера будет являться класс ClassVMM:

class ClassVMM{
public:
    void *malloc(dword size);
    void free(void ptr);
    void *realloc(dword *ptr, dword size);
    void *calloc(dword nmenb, dword size);
    ClassVMM();
    ~ClassVMM();
protected:
    ClassPageLoader pg_loader;
    ClassTables *tables;
};

Этот класс на данной стадии является чисто наброском, который характеризует моё представление VMM. Публичные функции класса думаю понятны всем. Защищённым является объект класса ClassPageLoader. С помощью функций этого класса будет осуществляться страничная подкачка. В классе ClassTables будут реализованы методы для работы с таблицами PDE и PTE.

Диаграмма

На схеме показано взаимодействие между объектами VMM. Здесь TPDE и TPTE – структуры, которые будут использоваться в классе ClassTables. По схеме объект класса ClassVMM получает от ядра ОС запрос на выделение некоторого количества памяти. Далее при помощи методов класса ClassTables осуществляется поиск свободных таблиц. Если свободного места в физической памяти нет, то управление передаётся объекту класса ClassPageLoader, который выберет таблицы на выгрузку и произведёт собственно выгрузку этих таблиц на диск. После этого управление опять передаётся ClassVMM, который теперь уже выделяет память и возвращает ядру ОС адрес первой из выделенных страниц.

Алгоритм замещения страниц

Я думаю, что алгоритмом замещения страниц следует выбрать NFU. В принципе, этот алгоритм близок к LRU. Для реализации NFU в дескрипторе каждой страницы должен быть помещён счетчик, значение которого сдвигается вправо на 1 бит, а затем инкриминируется при каждом прерывании по времени, если у страницы установлен флаг обращения. После выполнения этих действий флаг сбрасывается.