Руководство по языку B.Pascal 7

Управление оверлейным буфером


Оверлейный буфер Borland Pascal лучше всего описывается в виде кольцевого буфера, в котором имеется указатель начала и ука- затель конца. Оверлеи всегда загружаются в начало буфера. При этом более "старые" оверлеи смещаются к его концу. Когда буфер заполняется (то есть между его началом и концом не будет доста- точно свободного пространства), то оверлеи в конце буфера выгру- жаются (освобождаются), и освобождается место для новых оверлеев.

Поскольку обычная память по своей природе не имеет характера кольцевого буфера, действительная реализация кольцевого буфера предусматривает несколько шагов, обеспечивающих, чтобы буфер действительно стал кольцевым. Этот процесс показан на Рис. 20.1. Здесь изображен процесс загрузки оверлеев в первоначально пустой оверлейный буфер. Сначала загружается оверлей A, затем - оверлей B, потом C, и, наконец, D. Заштрихованные области показывают сво- бодное пространство в буфере.

Шаг 1 Шаг 2 ------------- ------------- ¦ ---------- ¦ ¦ ---------- ¦ ¦ ---------- ¦ ¦ ---------- ¦ ¦ ---------- ¦ ¦ ---------- ¦ ¦ ---------- ¦ Начало ---> +------------+ ¦ ---------- ¦ ¦ Оверлей B ¦ Начало ----> +------------+ +------------+ ¦ Оверлей А ¦ ¦ Оверлей А ¦ Конец ----> L------------- Конец ---> L-------------

Шаг 3 Шаг 4 ------------- ------------- ¦ ---------- ¦ ¦ Оверлей С ¦ ¦ ---------- ¦ +------------+ Начало ----> +------------+ ¦ Оверлей В ¦ ¦ Оверлей С ¦ Конец ---> +------------+ +------------+ ¦ ---------- ¦ ¦ Оверлей В ¦ ¦ ---------- ¦ +------------+ Начало ---> +------------+ ¦ Оверлей А ¦ ¦ Оверлей D ¦ Конец ----> L------------- L-------------

Рис. 20.1 Загрузка и освобождение оверлеев.

Как можно заметить, при переходе от шага 3 к шагу 4 происхо- дит несколько интересных моментов. Во-первых, заголовок начала перемещается к концу оверлейного буфера, приводя к тому, что под- система управления оверлеями смещает все загруженные оверлеи (и указатель конца) вверх. Это смещение необходимо, чтобы свободная область всегда находилась между указателем начала и указателем конца. Во-вторых, чтобы загрузить оверлей D, подсистеме управле- ния оверлеями приходится выгрузить из конца буфера оверлей A. В этом случае оверлей A является оверлеем, которых был загружен раньше всех, поэтому прежде чем продолжить работу, лучше всего выгрузить именно его. Администратор оверлеев продолжает освобож- дать оверлеи в конце буфера, освобождая место в его начале для новых оверлеев. При этом каждый раз повторяется операция смещения и переноса указателя начала.


Этот режим операция используется администратором оверлеев Borland Pascal 0 по умолчанию. Однако, Borland Pascal также поз- воляет вам использовать возможность оптимизации алгоритма управ- ления оверлеями.

Предположим, что оверлей A содержит некоторые часто исполь- зуемые подпрограммы. Хотя некоторые из этих подпрограмм использу- ются все время, существует вероятность, что оверлей A будет выгружен из буфера и вскоре загружен в него снова. Проблема здесь состоит в том, что подсистема управления оверлеями ничего не зна- ет о частоте вызовов подпрограмм в модуле A. Она знает только, что если при обращении к подпрограмме оверлея A его нет в памяти, то нужно загрузить этот оверлей. Одно из решений здесь может сос- тоять в том, чтобы перехватывать каждое обращение к подпрограммам оверлея A и затем при каждом вызове перемещать оверлей A в начало оверлейного буфера, чтобы было отражено его новое состояние, как последнего использованного оверлея. Такой перехват вызовов к со- жалению будет слишком непроизводительным в смысле скорости выпол- нения, и в некоторых случаях может даже более замедлить работу прикладной программы, чем дополнительная операция загрузки овер- лея.

В Borland Pascal предусматривается компромиссное решение, которое практически не увеличивает непроизводительные расходы и обеспечивает высокую степень успеха в идентификации последних ис- пользованных оверлеев, которые не следуют разгружать. Когда овер- лей приближается к концу оверлейного буфера, то начинается его "тестирование". Если в ходе этого "тестирования" выполняется вы- зов подпрограммы данного оверлея, "приговор" ему будет отменен, и он не будет разгружен, когда достигнет конца оверлейного буфера. Вместо этого он просто перемещается в начало буфера, и начинается новые цикл его перемещения по кольцевому оверлейному буферу. Ес- ли, с другой стороны, в процессе "тестирования" обращений к овер- лею не будет, то оверлей при достижении конца буфера выгружается.

Схема тестирования (проб/отказов) приводит к тому, что часто используемые оверлеи будут сохраняться в оверлейном буфере за счет того, что будет перехватываться почти каждый вызов, когда оверлей приближается к концу оверлейного буфера.

Механизмом тестирования управляют две новые подпрограммы подсистемы управления оверлеями - OvrSetRetry и OvrGetRetry. Подпрограмма OvrGetRetry устанавливает размер области в оверлей- ном буфере, которую нужно тестировать, а OvrGetRetry возвращает текущее состояние. Если оверлей смещается в последние OvrGetRetry байт перед концом оверлейного буфера, то он будет автоматически подвергаться тестированию. Все свободное пространство в оверлей- ном буфере рассматривается, как часть пробной области (области тестирования).


Содержание раздела