Главная страница Межпроцессное взаимодействие (состязание) процессы, поэтому менеджер памяти - вполне подходящее место для выполнения этого вызова. Семь вызовов get/set вообще не имеют никакого отнощения к управлению памятью. Они были помещены в код менеджера просто потому, что код файловой системы и без того достаточно велик. Вызов ptrace, применяемый при отладке, попал сюда по той же причине. Таблица 4.3. Типы и параметры сообщений для менеджера памяти и ответные значения
Последнее сообщение, KSIG, не связано с системным вызовом. Этот тип сообщений используется ядром для того, чтобы информировать его о сигнале, исходящем из ядра. Примерами таких сигналов являются SIGINT, SIGQUIT и SIGALARM. Несмотря на существование библиотечного вызова sbrk, системного вызова sbrk нет. Эта подпрограмма вычисляет объем необходимой памяти, уменьшая или увеличивая текущее значение на величину переданного ей аргумента, и делает вызов Ьгк, чтобы изменить размер области. Точно так же нет отдельных системных вызовов для geteuid и getegid. Вызовы getuid и getgid возвращают как действующие, так и реальные идентификаторы пользователя и группы. Аналогично, вызов getpid возвращает идентификаторы как самого процесса, так и его родителя. Ключевой структурой данных для обработки сообщений является таблица calLvec, определяемая в файле table.c. Она содержит указатели на подпрограммы, обрабатывающие все различные типы сообщений. Когда сообщение попадает в менеджер памяти, команды в главном цикле извлекают из него тип сообщения и записывают его в глобальную переменную mm call. Позже это значение используется как индекс в таблице callvec, и по нему находится адрес подпрограммы для обработки прибывшего сообщения. Затем эта подпрограмма отрабатывает, выполняя системный вызов. Значение, которое возвращает обработчик, отправляется обратно, чтобы сообщить о выполнении или ошибке. Механизм подобен механизму обработки системных вызовов, но только в адресном пространстве пользователя, а не ядра. 4.7.3. Струю-уры данных и алгоритмы менеджера памяти у менеджера памяти есть две ключевые структуры данных: таблица процессов и таблица свободных блоков памяти ( дыр ). Из табл. 2.1 видно, что одни поля таблицы процессов нужны для управления процессами, другие для управления памятью, а третьи требуются файловой системе. В MINIX каждая из трех частей операционной системы поддерживает собственную таблицу процессов, содержащую только те поля, которые интересны ей. Записи всех трех таблиц соответствуют друг другу, чтобы не усложнять дело. Так, ячейка k таблицы процессов менеджера памяти соответствует тому же процессу, что и ячейка k из таблицы процессов файловой системы. При создании или уничтожении процесса необходимо обновлять записи во всех трех таблицах, чтобы поддерживать их в синхронизированном состоянии. Таблица процессов менеджера памяти называется mproc, она определена в файле /usr/src/mm/mproc.h. В этой таблице содержатся поля, связанные с выделением памяти, а также некоторые дополнительные сведения. Самым важным полем является mp seg, у которого есть три записи, для сегмента текста (кода), данных и стека. Все эти величины измеряются не в байтах, а в кликах. Размер клика (минимального блока памяти) зависит от реализации. Стандартным значением для MINIX является 256 байт. Все сегменты начинаются на границе клика и содержат целое число кликов. Способ записи информации о выделении памяти проиллюстрирован рис. 4.32. На рисунке показан процесс с такой структурой: 3 Кбайт текста, 4 Кбайт данных, зазор имеет величину 1 Кбайт, а после него следует стек объемом 2 Кбайт. Всего выделено 10 Кбайт памяти. На рис. 4.32, б показано, что хранится в полях длины и виртуального и физического адреса для этих сегментов, при условии, что про- цесс не разделяет адресные пространства кода и данных. В этой модели размер сегмента текста всегда считается равным нулю, а сегмент данных содержит и данные, и код. Когда показанный на рисунке процесс обращается к виртуальному адресу О или совершает переход по этому адресу, произойдет обращение к физическому адресу 0x32000 (в десятичной записи 200 Кбайт). В кликах этот адрес записывается как 0x320. Нужно отметить, что виртуальный адрес, с которого начинается стек, зависит от общего объема памяти, выделенной процессу. Так, если при помощи команды chmem модифицировать заголовок исполняемого файла, чтобы при запуске для программы резервировалось больше динамически распределяемой памяти (промежуток между сегментами стека и данных), то при следующем запуске программы начало стека будет расположено выше. Если стек вырастет на один клик, его запись должна измениться с тройки (0x20, 0x340, 0x8) на тройку (OxlF, ОхЗЗЕ, 0x9). Аппаратное обеспечение процессоров 8088 не поддерживает прерывание переполнения стека, и в MINIX стек задается так, чтобы на 32-разрядных процессорах не инициировать прерывание до тех пор, пока сегмент стека не пересечется с сегментом данных. Таким образом, информация о стеке будет обновлена только при следующем системном вызове Ьгк, при этом операционная система явно считывает значение SP (указатель стека) и пересчитывает параметры стека. На машинах, поддерживающих аппаратный контроль переполнения стека, информация о стеке должна обновляться как только стек переполнит свой сегмент. По причинам, которые мы далее обсудим, в 32-битной версии MINIX для процессоров Intel этого не делается. Стек Данные Адрес (шестнадцатеричный) 210 К (0x34800) 208 К (0x34000) 207К{0хЗЗсО0) 203 К (0х32с00) 200 К (0x32000)
Рис. 4.32. 8 - процесс в памяти; б - его представление с единым адресным пространством данных и кода; 8 - с раздельными пространствами данных и кода Ранее мы уже упоминали, что усилия разработчиков аппаратного обеспечения не всегда приводят к тем результатам, которые нужны программистам. Даже работая в защищенном режиме Pentium, MINIX не отслеживает ситуацию, когда
|
© 2000 - 2024 ULTRASONEX-AMFODENT.RU.
Копирование материалов разрешено исключительно при условии цититирования. |