Автоматизация

Вид материалаДокументы

Содержание


Многопользовательская операционная система
Планирование памяти
Организация смены задач
Формы системных директив
Ascii /lp/ ; alun
Inc dpb+a.lunu
Диагностика директив
Флаги событий
Асинхронные системные прерывания
Подобный материал:
1   ...   14   15   16   17   18   19   20   21   ...   25
ГЛАВА 8

МНОГОПОЛЬЗОВАТЕЛЬСКАЯ ОПЕРАЦИОННАЯ СИСТЕМА

РЕАЛЬНОГО ВРЕМЕНИ ОС РВ


§ 8.1. ОРГАНИЗАЦИЯ ВЫЧИСЛИТЕЛЬНОГО ПРОЦЕССА


Операционная система ОС РВ, о которой будет идти речь в настоящей главе, является мультипрограммной ОС реального времени, обеспечивающей управление процессами реального времени с одновременным обслуживанием многих пользователей. Пользователи, работая за индивидуальными терминалами, могут одновременно и независимо выполнять любую доступную системе работу: создавать исходные тексты программ на языках ФОРТРАН, МАКРОАССЕМБЛЕР, ПАСКАЛЬ и др., транслировать, отлаживать или выполнять эти программы, обрабатывать файлы данных на магнитных лентах, дисках и перфолентах, работать с графическими средствами и т. д. При этом каждый пользователь работает так, как будто все ресурсы машины находятся в его единоличном распоряжении. Для обеспечения такого режима работы система должна обеспечивать четкое взаимодействие между программами пользователей, с одной стороны, и разнообразными программными и аппаратными средствами самой ЭВМ - с другой.

Организация мультипрограммной работы вычислительного комплекса, особенно в условиях задач реального времени, требует решения целого ряда разноплановых вопросов, которые условно можно разбить на три группы:
  1. планирование оперативной памяти, т. е. разделение всей доступной памяти на участки, в которые загружаются задачи. При этом надо выполнять противоречивые требования одновременной обработки максимального количества задач и мак­симальной скорости обработки каждой из них;
  2. распределение между задачами времени центрального процессора. Поскольку готовые к выполнению задачи могут находится как в оперативной памяти, так и на магнитных дисках (если им не хватило места в памяти), то сюда входят также вопросы взаимодействия оперативной и внешней памяти;
  3. организация взаимодействия задач друг с другом, что может понадобиться в условиях работы единого программного комплекса. Сюда входят вопросы времен­ной синхронизации задач, передачи из задачи в задачу данных или служебной информации и пр.

При рассмотрении многозадачного режима надо иметь в виду, что в понятие задача входят как прикладные программы, написанные пользователем, так и многие программы ОС. ОС при организации вычислительного процесса, в принципе не делает между ними никакого различия. Если ЭВМ используется в составе многотерминального комплекса, служащего для разработки программного обеспечения, то большая часть выполняемых задач может принадлежать к системным; при написании исходных тестов программ, их трансляции, компоновке, отладке будут выполняться системные программы редактора текста, транслятора, компоновщика, отладчика и т. д.


Планирование памяти

Любая задача выполняется в заранее установленной неразрывной области памяти, называемой разделом. Разделы памяти устанавливаются при генерации системы, однако при необходимости их можно перераспределить с помощью соответству­ющих команд оператора.

При запуске задачи указывается, в каком разделе она должна выполняться; для этого разделы снабжают именами. На один раздел может претендовать не сколько задач. От типа раздела и его характеристик зависит порядок смены и выполнения задач.

В системе ОС РВ предусмотрено два типа разделов оперативной памяти: разделы, управляемые пользователем, и системно-управляемые разделы.

В системно-управляемом разделе монитор сам распределяет имеющееся про­странство так, чтобы в памяти одновременно находилось максимально возможное число задач. При этом может происходить перемещение уже загруженной задачи из одного места раздела в другое, чтобы получить непрерывную область памяти, достаточную для размещения новой задачи. Поскольку в любой момент времени процессор выполняет, строго говоря, только одну задачу, система управляет также и сменой состояния загруженных задач, обеспечивая их поочередное выполнение с учетом их приоритетов. Системно-управляемые разделы удобны при одновременной работе на ЭВМ многих пользователей. Им не нужно заботиться о своих взаимо­отношениях — система обеспечит наиболее эффективное, распределение ресурсов ВК между всеми активизированными задачами.

В разделе, управляемом пользователем, в любой момент времени может быть размещена только одна задача. Она не может быть ни перемещена, ни выгружена системой без ведома пользователя. Разделы, управляемые пользователем, удобны для задач реального времени, поскольку задача, загруженная в память, в любой момент готова к выполнению и, следовательно, обеспечивает максимальную скорость реакции на внешнее событие.

Рассмотрим рис. 8.1. Первые 14К слов (до восьмеричного адреса 70 000) занимает монитор — резидентное ядро ОС, всегда находящееся в памяти и управляющее всеми сторонами вычислительного процесса (для сравнения напомним, что в системе РАФОС резидентный монитор занимает всего 4К слов и располагается по старшим адресам памяти).




Рис. 8.1. Типичное распределение памяти в большой вычислительной системе


С адреса 70 000 начинается область памяти, которая может быть распланирована по-разному, в зависимости от конфигурации вычислительного комплекса и стоящих перед ним задач. В примере на рис. 8.1 первый раздел этой области носит имя DRVPAR, занимает 5,5К слов и предназначен для хранения драйверов ВУ. При генерации ОС этот раздел был объявлен системно-управляемым, что позволяет загружать в него несколько программ одновременно. Тогда же, на стадии генерации, в этот раздел были загружены три драйвера: драйвер ленты МТ:, драйвер диска DК: и драйвер терминала ТТ:. По мере надобности в резервную область этого раздела объемом 2,75К слов могут загружаться нужные драйверы, например перфосчитывателя, АЦПУ и др.

Следующий раздел с именем SYSPAR объявлен при генерации разделом, уп­равляемым пользователем. В него при генерации распределены (но не загружены!) три системные программы: MCR, анализирующая команды оператора, подаваемые с клавиатуры терминала, TKTN, участвующая в завершении задач, и SHF, с помощью которой происходит уплотнение задач, находящихся в системно-управляемых разделах. Поскольку SYSPAR является разделом, управляемым пользователем, эти три программы могут загружаться в него и выполняться только поочередно. Загружает эти задачи, естественно, система, а не пользователь, руководствуясь их приоритетами и складывающейся вычислительной ситуацией.

Следующий, системно-управляемый раздел FCPPAR содержит системную прог­рамму работы с файлами F11ACP.

Последний раздел GEN, под который отводится вся оставшаяся память (около 100К слов) — системно-управляемый. В него загружаются задачи пользователей. В нем же работает и большинство системных программ — трансляторы FOR и MAC, компоновщик ТКВ, редактор текста EDI и т. д.

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

Через некоторое время, после изменения ситуации, выгруженная задача снова вернется в память, но, возможно, уже на другое место.

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

По-другому обстоит дело, если вычислительный процесс организуется в разделе, управляемом пользователем. Такой раздел можно было бы создать в начале или в конце области памяти, отведенной первоначально под раздел GEN, уменьшив соответственно размер этого раздела. Новому разделу надо назначить имя, длину и базовый (начальный) адрес.

Любая задача, назначенная для выполнения в раздел, управляемый пользователем, настраивается на базовый адрес этого раздела и при загрузке всегда попадает на одно и то же, заранее определенное и известное место в памяти. В другой области памяти, например в другом разделе, эта задача выполняться не может. Однако и другие задачи не смогут претендовать на эту область памяти и выполняемая задача будет находиться в памяти до тех пор, пока не завершится естественным образом, либо не будет завершена "насильственно", например командой оператора ABORT.

В действительности, однако, дело обстоит несколько сложнее.

Во-первых, пользователь может активизировать несколько задач для выполнения в одном разделе. Тогда очередность их выполнения будет определяться системой (как и в системно-управляемом разделе) с учетом их приоритетов и текущего состояния.

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

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

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


Организация смены задач

Основой организации вычислительного процесса в ОС РВ является система приоритетов. Приоритет может быть назначен задаче на разных этапах ее создания, в том числе он может задаваться динамически во время выполнения задачи. Всего может быть 250 значений приоритетов — от 1 до 25010. В первую очередь всегда выполняется задача с наивысшим приоритетом, но на время, когда она освобождает процессор (ожидание завершения ввода-вывода, ожидание внешнего события и т. д.), автоматически запускается задача с более низким приоритетом.Если в системе находятся несколько задач с одинаковыми приоритетами, они регулярно сменяют друг друга.

Для того чтобы разобраться в механизме смены задач, надо сначала рассмотреть состояния, которые может принимать задача (рис. 8.2).




Рис. 8.2. Состояния задач в системе ОС РВ


Задача попадает под контроль монитора после установки задачи в системе. Задачу устанавливает пользователь вводом с привилегированного терминала команды оператора INSTALL. При этом монитор записывает информацию об устанавливаемой задаче (имя задачи, размер задачи, адрес образа задачи на диске и т. д.) в системный каталог задач. Установленная задача не размещена в памяти и не конкурирует за системные ресурсы. Система рассматривает ее как пассивную до тех пор, пока другая (выполняемая) задача или пользователь командой оператора RUN не потребует ее активизации.

Различие между активным и пассивным состояниями задачи является важным для систем реального времени. Пассивная задача требует минимальной памяти (только место в системном каталоге задач); в то же время в случае необходимости обслуживания задачей события реального времени монитор может быстро привести ее в состояние активной конкуренции за системные ресурсы. Это возможно благодаря наличию в системной таблице полной информации о задаче. Заметим, что число установленных, но пассивных задач может заметно превышать число активных задач.

Активизация задачи, осуществляемая командой оператора RUN или програм­мными запросами RUN$ (список системных директив с расшифровкой их обозна­чений приведен в табл. П.11) и RQST$, инициирует конкуренцию задачи за место в оперативной памяти. Став активной, задача продолжает находиться на диске до тех пор, пока в памяти не освободится достаточно места для ее загрузки. Если такое место найдено, задача загружается в память и становится готовой к выпол­нению, начиная тем самым конкуренцию за время центрального процессора. Одновременно в памяти могут находиться несколько задач, готовых к выполнению. Из них в любой момент выполняется одна, именно та, у которой наивысший приоритет.

Таким образом, система приоритетов - основа распределения времени центрального процессора между задачами. Если активизировать чисто вычислительную, "процессорную" задачу, назначив ей высокий приоритет, она захватит процессор и будет выполняться неограниченное, вплоть до завершения, время, превратив вычислительную систему в однозадачную. Однако программы реального времени не носят чисто вычислительного характера, а содержат обращения к внешним устройствам — стандартным (НМД, НМЛ, терминалы) и нестандартным (аппаратура физического эксперимента). Выполняемая задача может перейти в заблокированное состояние, если ждет наступления определенного события, например ввода данных с терминала или завершение вывода на магнитный диск. Задача может быть заблокирована и по другим причинам, например в результате выполнения программного запроса SPND$. Заблокированная задача остается в памяти, но не конкурирует за системные ресурсы. Если задача с наивысшим приоритетом заблокирована, выполняемой становится задача с наивысшим приоритетом среди остальных задач, готовых к выполнению.

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

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

Задачи, находящиеся в памяти и разделенные свободными окнами, переписываются на новые места вплотную друг к другу для устранения окон и объединения всех свободных участков в одну область.

Своеобразная ситуация возникает, если память раздела полностью занята, и активизируется еще одна задача, приоритет которой совпадает с приоритетом наименее приоритетных готовых к выполнению задач. Тогда, с одной стороны, новая задача не может инициировать выгрузку какой-либо задачи, поскольку ее приори­тет не превышает приоритета находящихся в памяти задач, а с другой стороны, она имеет такие же права на выполнение, как и задачи, уже находящиеся в памяти. Для преодоления этого противоречия предусмотрен специальный механизм свертывания задач (свопинг).

Свертывание — это разновидность выгрузки, реализуемая для задач с равными или близкими приоритетами. Когда задача загружается в память, к установленному значению ее приоритета прибавляется некоторое положительное число р(р~5). Текущее значение приоритета оказывается, таким образом, выше установленного. Затем по мере выполнения задачи эта добавка к приоритету периодически (1—2 раза в 1 с) уменьшается, пока не дойдет до значения - р. Если в числе активных задач на диске есть задача с таким же или даже несколько более низким приоритетом, чем рассматриваемая, то как только текущий приоритет выполняемой задачи упадет ниже приоритета ожидающей, выполняемая задача будет выгружена на диск и ее место сможет занять активная задача с диска, которой первоначально не нашлось место в памяти.

Свертывание обеспечивает равномерное выполнение всех активных задач с одинаковыми или близкими приоритетами, даже если в оперативной памяти хватает места только на часть этих задач.

Другая проблема при обработке нескольких равноприоритетных задач возникает из-за того, что монитор, определяя задачу, которой предстоит стать выполняемой, просматривает системный каталог задач всегда от начала каталога. В результате среди задач с равным приоритетом чаще становятся выполняемыми те, записи о которых сделаны ближе к началу каталога (записи в каталоге делаются в порядке уста­новки задач). Задачи, установленные и запущенные позже других, имеют меньше шансов на реальное выполнение. Для устранения этого недостатка вводится спе­циальный механизм круговой перестановки (круговой передиспетчеризации) задач. Задачи с равными приоритетами периодически (примерно 10 раз в 1 с) изменяют свое место в системном каталоге задач, перемещаясь по кругу. В результате время цент­рального процессора распределяется между равноприоритетными задачами более равномерно.

На рис. 8.3 показано возможное состояние задач в системе в некоторый момент времени. В оперативной памяти находятся задачи Т1—Т6. Задачи Т1 и Т2 за­блокированы: задача Т1 ждёт завершения собственного ввода, а задача Т2 — разре­шения на продолжение, которое должно поступить из задачи Т5 (задачи Т2 и Т5 вводят в единый программный комплекс). Задачи Т3 - Т6 активны и готовы к выполнению. Из них в настоящий момент выполняется задача Т5. Возможно, она имеет наивысший приоритет; тогда она будет выполняться до конца. Возможно, однако, что приоритеты задач ТЗ — Т6 одинаковы; тогда состояние выполнения будет переходить от задачи к задаче с интервалом свопинга.



Рис. 8.3 Пример состояния задач в системе


Задача Т7 была активизирована командой RUN, однако ее приоритет невысок и она будет находиться на диске до тех пор, пока для нее не освободится место в памяти от более приоритетных задач. Задача Т8 была установлена командой INSTALL, но не была запущена. Она находится на диске в пассивном состоянии, не участвуя в конкуренции за память. Задача Т9 некоторое время назад была вы­полняемой, но в процессе выполнения она запросила ввод данных с терминала и пока еще их не получила. В ожидании данных она находится в заблокированном состоянии и система выгрузила ее на диск, освобождая место в памяти для задач, готовых к выполнению. Наконец, задачи Т10 и Т11 даже не установлены и системе они неизвестны.

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

Важными в указанном смысле являются, в частности, следующие события:
  1. завершение ввода — вывода. Пока задача, инициировавшая ввод или вывод данных, ждала его завершения, выполняемой могла стать задача с меньшим приоритетом. Завершение ввода — вывода должно «восстановить справедливость»;
  2. завершение задачи. Ясно, что это событие должно приводить к смене задач;
  3. динамическая смена приоритета задачи, которая может быть выполнена с помощью системной директивы ALTP $;
  4. объявление важного события с помощью системных директив DECL $ или MRKT $ (таким образом, важные события можно «создать» в любой момент времени);
  5. выполнение алгоритма круговой перестановки в конце установленного для этого механизма интервала времени.

Существуют и другие причины, вызывающие важные события.


§ 8.2. ОБЩИЕ ХАРАКТЕРИСТИКИ СИСТЕМНЫХ ДИРЕКТИВ


Блок параметров директивы

Системные директивы служат для вызова стандартных программ выполнения некоторых функций монитора: ввода — вывода данных, запуска и приостановки задач, передачи данных из задачи в задачу и т.д. Все системные директивы оформлены в виде макроопределений, широко использующих, в свою очередь, директивы условной трансляции, директивы определения атрибутов параметров и пр. При указании в тексте программы имени директивы генерируется макрорасширение, фактический состав которого определяется количеством и видом параметров, сопровождающих макровызов. Такой подход к формированию стандартных программ позволяет расширить функции каждой директивы и уменьшить их количество. Например, директива QIO $ позволяет организовать обмен данными с любыми ВУ — терминалом, АЦПУ, перфоратором, магнитным диском и пр. В зависимости от параметров макровызова генерируется программа, учитывающая специфику соответствующего ВУ. Из параметров, записываемых в поле операндов макровызова, формируется блок параметров директивы (БПД) (рис. 8.4), который может храниться в поле данных стеке. Младший байт первого слова БПД содержит код соответствующей директивы (каждая директива имеет свой код), старший байт — размер данного БПД. Остальные слова БПД предназначены для параметров директивы. Для каждой директивы ха­рактерен свой список требуемых параметров.

В качестве примера рассмотрим БПД, создаваемый при макровызове ALUN $ 3, LP 2.

Эта директива служит для закрепления за конкретным ВУ определённого номера, на который можно ссылаться в дальнейшем тексте программы. В приведённом макровызове логический номер 3 закрепляется за АЦПУ (условное обозначение LP) с номером 2. В двух байтах первого слова БПД (рис. 8.5, а) записываются числа 7 (код директивы ALUN $) и 4 (длина БПД). В последующие слова последовательно переносится информация из поля операндов макровызова: логический номер (3), обозначение ВУ (LP) в коде ASCII и номер ВУ.




Рис. 8.4. Структура блока параметров директивы




Рис. 8.5. Примеры БПД


Макровызов ABRT $ PROG26, вызывающий динамическое снятие с выполнения задачи с именем PROG26, создаёт БПД, изображённый на рис. 8.5, б. Здесь в первом слове записываются числа 83 (код директивы) и 3 (размер БПД), а в два последующих слова заносится имя задачи в коде RADIX-50 (по три символа в слове).

Таким образом, различные параметры директив хранятся в БПД в разной форме: в виде двоичных эквивалентов целых чисел, в коде ASCII либо в коде RADIX-50.


Формы системных директив

К каждой системной директиве можно обратиться с тремя различными способами, в зависимости от того, какая форма макровызова (т. е. имени директивы) используется в программе. Имена всех системных директив состоят из 3 - 4 букв, заканчивающихся знаком $. Такое имя представляет одну форму макровызова. Две другие формы обра­зуются путём присоединения к имени директивы знаков С или S. Наличие или отсут­ствие дополнительных знаков не изменяет существа директивы, но влияет на порядок выполнения программного запроса.

Форма $ (без дополнительных знаков) служит только для создания БПД директивы в поле данных программы. Для того чтоб инициировать действие, определяемое указанной директивой, надо в соответствующем месте программы включить дополнительный макровызов DIR 3 , параметром которого является адрес БПД выполняемой директивы:

DPB: ALUN 3 3, LP, 2

.BYTE 7, 4 ; макрорасширение

.WORD 3 ; макровызова

.ASCII /LP/ ; ALUN $

.WORD 2

.

.

DIR 3 #DPB ; выполнение директивы

; ALUN 3

MOV #DPB,-(SP) ; макрорасширение

EMT 377 ; макровызова DIR $


Форма $ + DIR удобна, если данная директива должна выполняться многократно либо из нескольких разветвлений программы. В этом случае независимо от количества фактических вызовов директивы ее БПД существует только в одном экземпляре, чем экономится память и время при выполнении директивы.

Как показано в предыдущем примере, макровызов DIR $ расширяется в две программные строки; проталкивание в стек адреса блока параметров выполняемой директивы и выполнение команды ЕМТ. По команде ЕМТ происходит прерывание выполняемой программы через вектор прерывания с адресом 30, откуда берется адрес системной программы 3 EMTPR, обрабатывающей это системное прерывание. Эта программа, получив из стека адрес БПД и определив по содержимому младшего байта первого слова БПД код директивы, инициирует выполнение монитором со­ответствующей программы. Конкретные значения параметров, необходимые для выпол­нения монитором требуемого действия, берутся из БПД.

При необходимости многократного выполнения одного и того же программного запроса из разных точек программы пользователя имеется возможность модифицировать БПД между последовательными макровызовами DIR $. Например, назначение логических номеров 3, 5 и 7 трем АЦПУ с номерами 2, 3 и 4 можно осуществить следующей последовательностью командных строк:


DPB: ALUN $ 3, LP, 2

.

.

DIR $ #DРВ ; первый макровызов

ADD #2, DPB + 2 ; логический номер 5

INC DPB + 6 ; АЦПУ номер 3

DIR $ #DРВ ; второй макровызов

ADD #2, DPB + 2 ; логический номер 7

INC DPB + 6 ; АЦПУ номер 4

DIR $ #DРВ ; третий макровызов


Как видно из этого примера, при необходимости модифицировать БПД програм­мист должен знать в деталях его структуру. Модификацию БПД, так же как и обраще­ние к элементам БПД, например, с целью уточнения фактического значения того или иного параметра удобнее выполнять, пользуясь символическими смещениями. Каж­дый макровызов генерирует символические смещения для своего БПД. Так, смеще­ние к логическому номеру устройства для директивы ALUN$ обозначается A.LULU, смещение к слову, содержащему имя устройства, A.LUNA и смещение к номеру устройства — A.LUNU. С использованием символических смещений приведенный выше пример на модификацию БПД будет выглядеть следующим образом:


DPB: ALUN $ 3, LP, 2

.

.

DIR $ #DРВ

ADD #2, DPB+A.LULU


INC DPB+A.LUNU

DIR $ #DРВ

ADD #2, DPB+A.LULU


INC DPB+A.LUNU

DIR $ #DРВ


В описании директив приводятся закрепленные за смещениями символические имена.

Форму макровызова $ С целесообразно использовать, если данный программный запрос должен выполняться в программе только один раз. Макрорасширение фор­мы $ С включает в себя не только строки БПД, но и две рассмотренные выше строки проталкивания в стек адреса БПД и вызова системного прерывания командой ЕМТ 377. Поэтому макровызов в форме $С должен указываться не в поле данных, а в области программных строк:

.

.

. ; программные строки

.

ALUN $ С 3, LP, 2

.

. ; программные строки

.


Блок параметров выполняемой директивы в этом случае строится системой в недоступной пользователю области программы (точнее, в области программы с неизвестным пользователю адресом, именно в секции $ DPB $ S), что делает невозможным модификацию БПД.

Форма макровызова $ S используется прежде всего при написании реентерабельных программ. В этом случае также генерируются и БПД, и строки выполнения программного запроса, однако БПД создается не в памяти, а на стеке. Заполнение стека содержимым БПД происходит во время выполнения программы командами MOV. В случае большого количества параметров последовательное проталкивание их в стек увеличивает время выполнения программного запроса, однако при небольшом числе параметров рекомендуется использовать именно эту форму. Макрорасширение формы $ S выглядит следующим образом:


ALUN $ S #3, # LP, #2

MOV #2,—(SP)

MOV # LP,— (SP)

MOV #3,-(SP)

MOV (PC) + ,— (SP) ; проталкивание в стек следующей строки

.BYTE 7, 4

ЕМТ 377


Следует обратить внимание на то, что макровызовы в форме $ и $ С требуют параметров, записанных как операнды директив ассемблера .WORD, .BYTE, .ASCII и .RAD50, в то время как $ S-форма требует параметров в виде операндов команды MOV. В этом случае для передачи в качестве параметров чисел или адресов их следует предварять знаком непосредственной адресации #, а для пере­дачи кодов ASCII символов приходится использовать обозначение #"LP. Здесь две кавычки обозначают, что вместо двух символов воспринимаются их коды ASCII. Указанная разница определяет некоторые ограничения на использование разных форм макровызовов. Так, если значения одного или нескольких параметров директивы хранятся в РОН, возможна только S-форма макровызова, которая допускает использование обозначения РОН в качестве параметров:


ALUN $ S R0, #"LP, R1

MOV R0, — (SP) ; логический номер из R0 переносится в стек


MOV #"LP, -(SP)

MOV Rl, -(SP) ; номер АЦПУ из Rl переносится в стек

MOV (PC)+, -(SP)

.BYTE 7, 4

EMT 377

Если же в качестве параметра используются, например, имя программы (которое должно фигурировать в БПД в коде RADIX-50), то следует, наоборот, использовать форму $ С:


RSUM$ C ТТ12

.BYTE 47., 3 ; макрорасширение

.RAD50 /ТТ12/


Диагностика директив

Как и в ОС РАФОС, операционная система ОС РВ сигнализирует о неправиль­ном выполнении программных запросов установкой разряда С в ССП. Кроме того, после выполнения программного запроса код его завершения заносится в специально зарезервированное в заголовке задачи слово (слово состояния директивы, ССД) с символическим адресом $ DSW. Для большинства директив код успешного заверше­ния + 1, имеющий мнемоническое обозначение IS.SUC. Коды ошибочного завершения для каждой директивы свои. Все они имеют отрицательное значение. Например, директива ABRT $ имеет следующие коды завершения:


IS.SUC (000001) —успешное завершение;

IE.INS (177776) — задача не установлена;

IE.ACT (177771) —задача не активна;

IE.PRI (177760) —директиву издала непривилегированная задача;

IE.ADP (1.77636) —часть БПД вышла за пространство адресов задачи;

IE.SDP (177635)—неправильный размер БПД.

Отладку задач с использованием системных директив удобно производить следующим образом. В исходный текст программы после директивы, на которую падает подозрение в неправильном выполнении, включается команда вида


MOV $DSW, R0


Задача компонуется с модулем отладчика, и сразу после указанной команды устанавливается точка останова. При выполнении задачи можно распечатать на терминале содержимое R0 и определить код завершения директивы.

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

Пусть, например, задача выставляет запрос на вывод некоторых данных, причем дальнейшее выполнение задачи недопустимо, если запрос не принят монитором. Поскольку элемент очереди ввода — вывода строится в динамической области памяти, вероятной причиной неуспешного выполнения директивы может быть нехватка динамической памяти. В приведенном ниже фрагменте программы анализируется эта ситуация:

1 $: QIO $ C... ; запрос на вывод

ВСС 10 $ ; С=0? Да. Продолжение про-

; граммы

CALL CHECK ; С=1. Переход на подпрограмму

; проверки ССД

BR 1 $ ; повторить попытку вывода

10 $ : .... ; продолжение про-

; граммы

CHECK: CMP $DSW.≠IE.UPN ; нехватка динамической памяти?

BNE FIN ; нет. Переход на аварийное завершение

WSIG $ S ; да. Директива ожидания важного

; события

RETURN ; возврат на повторение попытки вывода

FIN: EXIT $ S ; аварийное завершение


Использованное в приведенном примере ожидание важного события в надежде получить недостающую динамическую память является распространенным примером. Во многих случаях (завершение ввода - вывода, завершение задачи) важное событие сопровождается освобождением динамической памяти.


Флаги событий

Выполнение целого ряда программных запросов прямо или косвенно связано с флагами событий. Флаг события — это средство, с помощью которого задача распознает определенные события: окончание ввода — вывода или передачи данных, выполнение заданной команды и т. д. Каждой задаче доступны 64 флага события, различающиеся номерами. Флаги с номерами от 1 до 32 — локальные, их можно использовать только внутри данной задачи. При этом каждая задача может иметь свои 32 локальных флага. Флаги с номерами от 33 до 64 являются общими для всех активных задач, они служат для организации взаимодействия задач. Последние 8 флагов в каждой группе зарезервированы для использования системой.

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

Пусть, например, задача А на некотором участке готовит данные для других задач или выполняет какие-либо установочные действия в системе. В конце этого подготовительного участка в текст программы включается директива SETF $ с ука­занием номера общего флага. Этот флаг устанавливается системой, когда выполняется программный запрос SETF $. Остальные задачи могут быть заблокированы с помощью директивы WTSE $ с указанием того же номера общего флага. Блокировка снимается, и задачи переходят в класс готовых к выполнению только после того, как задача А выполнит всю подготовительную работу.

Другой пример использования флагов событий — синхронизация хода задачи с некоторыми событиями, длительность которых нельзя предугадать заранее. Если, например, задача обращается к терминалу пользователя с просьбой ввести некото­рые данные, ее дальнейшее выполнение можно приостановить до завершения ввода. В этом случае используется то обстоятельство, что директивы, инициирующие пере­дачу данных, устанавливают заданный в параметрах директивы флаг событий после завершения передачи данных. Поэтому если после директивы ввода — вывода стоит директива WTSE $ ожидания соответствующего флага события (в данном случае — локального), задача блокируется до окончания передачи данных.

Асинхронные системные прерывания

Асинхронные системные прерывания (АСП) дают возможность задаче реагиро­вать на некоторые события, возникающие в неопределенные заранее моменты вре­мени. При возникновении определенного события монитор инициирует системное прерывание и передает управление специальной программе обработки АСП, написан­ной пользователем. После завершения обработки АСП управление передается прерванной задаче. Это средство является аналогом подпрограмм завершения в системе РАФОС.

Пусть, например, по ходу выполнения задачи происходит ввод данных из внешнего устройства. В директиве QIO $, инициирующей передачу данных, в ка­честве одного из параметров может быть указан адрес подпрограммы обработки АСП. В этом случае окончание ввода данных приведет к системному прерыванию и передаче управления программе обработки АСП, которая выполняет некоторые запланированные действия: активизирует программу обработки или дальнейшей передачи данных, сигнализирует оператору об окончании ввода и т. д. После отра­ботки программы обработки АСП управление возвращается в исходную задачу.

Таким образом, АСП имеет первоочередное по отношению к задаче право на выполнение. В случае возникновения в задаче нескольких запросов на АСП они устанавливаются в организуемую монитором очередь АСП. АСП не могут прерывать друг друга, а выполняются последовательно, в том порядке, в котором возникли запросы на них. Только после выхода из последнего АСП будет продолжена задача.

На программы обработки АСП не накладывается никаких ограничений. В частности, в них включаться системные директивы, активизироваться новые АСП и т. д.

Выход из программы обработки АСП происходит по специально предназна­ченной для этого системной директиве ASTX $ - При этом надо иметь в виду, что в процессе реализации системного прерывания в стек задачи заносится не­которая служебная информация (содержимое СК и ССП задачи, ее ССД, маска флагов и пр.). Часть этой информации будет использована директивой ASTX $. В обязанности программиста входит подготовка стека для правильного выполнения директивы ASTX $. Практически это сводится к удалению перед выходом из АСП последнего записанного туда слова, для чего используется "бессодержательная" в данном случае команда TST:


TST (SP) +

ASTX $ S