Архитектура операционной системы UNIX

         

МЕХАНИЗМ ПОИСКА БУФЕРА


Как показано на Рисунке 2.1, алгоритмы верхнего уровня, используемые ядром для подсистемы управления файлами, инициируют выполнение алгоритмов управления буферным кешем. При выборке блока алгоритмы верхнего уровня устанавливают логический номер устройства и номер блока, к которым они хотели бы получить доступ. Например, если процесс хочет считать данные из файла, ядро устанавливает, в какой файловой системе находится файл и в каком блоке файловой системы содержатся данные, о чем подробнее мы узнаем из . Собираясь считать данные из определенного дискового блока, ядро проверяет, находится ли блок в буферном пуле, и если нет, назначает для него свободный буфер. Собираясь записать данные в определенный дисковый блок, ядро проверяет, находится ли блок в буферном пуле, и если нет, назначает для этого блока свободный буфер. Для выделения буферов из пула в алгоритмах чтения и записи дисковых блоков используется операция getblk (Рисунок 3.4).

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

  1. Ядро обнаруживает блок в хеш-очереди, соответствующий ему буфер свободен.
  2. Ядро не может обнаружить блок в хеш-очереди, поэтому оно выделяет буфер из списка свободных буферов.
  3. Ядро не может обнаружить блок в хеш-очереди и, пытаясь выделить буфер из списка свободных буферов (как в случае 2), обнаруживает в списке буфер, который помечен как "занят на время записи". Ядро должно переписать этот буфер на диск и выделить другой буфер.
  4. Ядро не может обнаружить блок в хеш-очереди, а список свободных буферов пуст.
  5. Ядро обнаруживает блок в хеш-очереди, но его буфер в настоящий момент занят.

Обсудим каждый случай более подробно.

Осуществляя поиск блока в буферном пуле по комбинации номеров устройства и блока, ядро ищет хеш-очередь, которая бы содержала этот блок. Просматривая хеш-очередь, ядро придерживается списка с указателями, пока (как в первом случае) не найдет буфер с искомыми номерами устройства и блока. Ядро проверяет занятость блока и в том случае, если он свободен, помечает буфер "занятым" для того, чтобы другие процессы не смогли к нему обратиться. Затем ядро удаляет буфер из списка свободных буферов, поскольку буфер не может одновременно быть занятым и находиться в указанном списке. Если другие процессы попытаются обратиться к блоку в то время, когда его буфер занят, они приостановятся до тех пор, пока буфер не освободится. На Рисунке 3.5 показан первый случай, когда ядро ищет блок 4 в хеш-очереди, помеченной как "блок 0 модуль 4". Обнаружив буфер, ядро удаляет его из списка свободных буферов, делая блоки 5 и 28 соседями в списке.

алгоритм getblk входная информация: номер файловой системы номер блока выходная информация: буфер, который можно использовать для блока { выполнить если (буфер не найден) { если (блок в хеш-очереди) { если (буфер занят) /* случай 5 */ { приостановиться (до освобождения буфера); продолжить; /* цикл с условием продолжения */ } пометить буфер занятым; /* случай 1 */ удалить буфер из списка свободных буферов; вернуть буфер; } в противном случае /* блока нет в хеш-очереди */ { если (в списке нет свободных буферов) /*случай 4*/ { приостановиться (до освобождения любого буфера); продолжить; /* цикл с условием продолжения */ } удалить буфер из списка свободных буферов; если (буфер помечен для отложенной переписи) /* случай 3 */ { асинхронная перепись содержимого буфера на диск; продолжить; /* цикл с условием продолжения */ } /* случай 2 -- поиск свободного буфера */ удалить буфер из старой хеш-очереди; включить буфер в новую хеш-очередь; вернуть буфер; } } }

<


Содержание  Назад  Вперед