Операционная система ос2000

Здесь дается обзор операционной системы реального времени ос2000 (далее ОС РВ или просто ОС). Более подробная информация содержится в документации.

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

Разработка ОС РВ базируется на следующих принципах:

Соответствие стандартам

При разработке операционной системы использовались следующие международные стандарты:

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

Редакция POSIX 1996 года уже охватывает (в качестве необязательной части) основные функции операционных систем реального времени:

Операционная система полностью соответствует стандарту POSIX 1996 г. в части, относящейся к реальному времени. Те части стандарта, которые не относятся к системам реального времени (традиционный UNIX) реализованы не полностью.

В рамках стандарта С 1990 г. реализованы математические функции (sin, exp, log и др.), функции обработки символов и строк, функции распределения памяти и др. Эти функции хорошо знакомы всем тем, кто разрабатывает программы на языке С. Они входят в состав таких хорошо известных средств разработки программ на языке С, как Borland C и Microsoft Development Studio C/C++.

При разработке средств обработки исключительных ситуаций с плавающей точкой использовался стандарт IEEE 754, а также стандарт С 1999 г. Средства протоколирования в основном соответствуют стандарту POSIX 2001 г.

Для эмуляции протокола Ethernet в многопроцессорных системах, использующих шину VME, используется стандарт ANSI/VITA. Этот стандарт позволяет взаимодействовать через шину VME и общую память различным как по аппаратуре, так и по используемой операционной системе процессорным платам.

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

Отметим также, что использование стандартов облегчает освоение системы и помогает при подготовке кадров программистов.

Мобильность

С целью повышения мобильности операционная система разбита на три части:

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

Та часть ОС, которая зависит только от типа процессора, написана на языке C или на Ассемблере и имеет сравнительно небольшой объем. Туда входят, например, функции запоминания и восстановления контекста, пролог и эпилог диспетчера прерываний.

Пакет поддержки модуля (ППМ) содержит ту часть ОС, которая зависит от конкретной ЭВМ (модуля). ППМ, в частности, содержит драйверы устройств и диспетчер прерываний (за исключением пролога и эпилога).

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

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

Архитектура программного обеспечения

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

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

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

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

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

Объектно-ориентированный подход активно применялся при разработке ядра ОС, хотя объектно-ориентированные языки программирования не использовались. Каждый объект представляет собой структуру. Однотипные объекты объединяются в классы.

Класс имеет описатель класса - структуру, которая содержит идентификатор класса, функции обработки объектов класса (методы), а также общие для всех объектов класса переменные. Каждый объект содержит указатель на описатель класса, к которому он относится.

Временные характеристики

При оценке систем реального времени используются две важнейшие характеристики:

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

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

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

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

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

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

Средства разработки

Для разработки прикладного программного обеспечения используется комплекс, состоящий из двух ЭВМ, соединенных по сети:

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

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

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

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

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

Порождение потоков

Потоки управления могут порождаться как прикладной программой, так и операционной системой. Операционная система порождает потоки на одном из этапов инициализации системы (системные потоки и корневой поток прикладной программы). Прикладная программа порождает потоки управления динамически с помощью функции pthread_create().

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

Завершение потоков

Поток может быть завершен по его собственной инициативе (нормальное завершение) или принудительно (функцией pthread_cancel() или посылкой сигнала). Нормальное завершение происходит в результате вызова функции pthread_exit() или возврата управления из функции, указанной при порождении потока.

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

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

Завершение потока без освобождения ресурсов, которые, вообще говоря, следовало бы освободить, приводит к растратам этих ресурсов. Особенно это важно при принудительном удалении потоков. Для решения этой проблемы служат так называемые функции свертывания, которые выполняются во время завершения потока (как нормального, так и принудительного). Функции свертывания создаются прикладной программой. Для каждого потока могут использоваться несколько функций свертывания.

Состояния потоков

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

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

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

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

Поток может быть приостановлен отладочными средствами, если он достиг точки останова, установленной отладчиком, или если при выполнении потока произошла ошибка (например, деление на 0).

Планирование потоков

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

В соответствии с POSIX операционная система позволяет использовать следующие три стратегии планирования:

 

SCHED_FIFO

приоритетное планирование,

 

SCHED_RR

приоритетное планирование с разделением времени,

 

SCHED_OTHER

дополнительная стратегия планирования.

С каждым потоком управления должна быть связана соответствующая стратегия планирования и приоритет. Таким образом, в рамках одной системы разные потоки управления могут использовать различные стратегии планирования. Например, высокоприоритетные потоки могут использовать стратегию SCHED_FIFO, а низкоприоритетные - SCHED_RR.

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

Стратегия и приоритет потока задаются при его порождении, но они могут быть впоследствии изменены.

При приоритетном планировании (SCHED_FIFO) поток выполняется до тех пор, пока он не перестанет быть работоспособным или пока не появится более приоритетный работоспособный поток.

Приоритетное планирование с разделением времени (SCHED_RR) аналогично стратегии SCHED_FIFO с дополнительным условием: если текущий поток управления занимает процессор в течение определенного периода времени (кванта) или дольше, этот поток сначала извлекается из очереди, а затем вновь устанавливается в очередь (то есть становится последним среди потоков с данным приоритетом). При этом ему выделяется новый квант времени.

Смысл этой стратегии заключается в том, чтобы запретить монопольное использование процессора. Более точно, поток управления со стратегией планирования SCHED_RR не может монопольно использовать процессор, если есть другие потоки с тем же приоритетом.

В настоящей версии SCHED_OTHER совпадает с SCHED_RR.

Сигналы

Назначение и основные сведения

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

Сигналы могут генерироваться (посылаться прикладной программе) как операционной системой, так и прикладной программой.

В системе имеется несколько видов сигналов. Каждому сигналу соответствует уникальное положительное число (номер сигнала). Кроме того, для сигналов определены имена.

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

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

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

Синхронная обработка сигналов производится с помощью функций sigwait(), sigwaitinfo() или sigtimedwait(). В этом случае поток приостанавливается до тех пор, пока не придет сигнал. Говорят, что сигнал был принят, если он был обработан синхронным образом.

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

Сигналы реализованы в соответствии с POSIX. При этом надо иметь в виду, что в ОС реализованы только потоки управления, но не процессы (с точки зрения POSIX в системе имеется только один процесс). Доставка сигнала процессу трактуется как доставка сигнала прикладной программе (без указания потока управления).

Сигналы можно разбить на две группы:

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

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

Порождение сигналов

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

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

В этих случаях способ уведомления о событии (реакции на событие) указывается прикладной программой в структуре sigevent. Возможны следующие способы уведомления о событии:

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

Обработка сигналов

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

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

Так как функция обработки сигнала выполняется асинхронно по отношению к потоку управления, то существуют ограничения на использование функций ОС в функциях обработки сигналов.

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

Средства синхронизации

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

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

Семафоры

Семафоры обеспечивают две основные операции:

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

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

При освобождении семафора проверяется, имеются ли потоки, ожидающие освобождения семафора. Если таких потоков нет, счетчик семафора увеличивается на 1. В противном случае значение счетчика не меняется, а из очереди к семафору выбирается первый (наиболее приоритетный) поток управления и объявляется работоспособным.

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

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

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

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

Мьютексы

Мьютексы имеют много общего с семафорами. Они также используются для синхронизации потоков управления на основе двух операций:

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

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

При освобождении мьютекса проверяется, есть ли потоки управления, ожидающие освобождения мьютекса. Если такие потоки есть, то среди них выбирается наиболее приоритетный, а среди потоков с наибольшим приоритетом выбирается тот, который дольше других ждет захвата мьютекса. Этот поток объявляется работоспособным и становится владельцем мьютекса.

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

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

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

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

Условные переменные

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

Применение условных переменных основано на использовании двух операций:

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

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

Функции ожидания выполнения условия выполняются в три этапа:

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

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

Очереди сообщений

При работе с очередями сообщений используются в основном следующие операции:

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

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

Сообщение устанавливается в очередь в соответствии с приоритетом: после сообщений с большим или равным значением приоритета, но перед сообщениями с меньшим значением приоритета. При приеме сообщений из очереди выбирается первое (то есть наиболее приоритетное) сообщение в очереди. В процессе приема оно удаляется из очереди.

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

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

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

Часы и таймеры

Часы

Для хранения даты и времени в системе используются различные структуры данных.

Для хранения интервала времени, выраженного в секундах, используются переменные типа time_t. Для более точного измерения времени используется структура timespec, которая позволяет хранить время в секундах и наносекундах.

Оба типа данных (time_t и timespec) могут использоваться для хранения календарного времени. В этом случае хранящиеся в них данные интерпретируются как время, прошедшее с 0 часов 1 января 1970 года.

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

Система всегда содержит, по крайней мере, одни часы с идентификатором CLOCK_REALTIME (системные часы). Значение этих часов интерпретируется как календарное время, то есть время (в секундах и наносекундах), истекшее с 0 часов 1 января 1970 года.

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

Функция clock_settime() позволяет установить показания часов, функция clock_gettime()- опросить показания часов, а clock_getres() - узнать разрешающую способность часов. Все три функции работают с высокой точностью, так используют структуру timespec. Отметим, однако, результаты измерения времени не могут быть точнее, чем разрешающая способность часов.

Изменять характеристики аппаратных часов, например, изменять их разрешение (программировать часы), можно в процессе инициализации системы, если это позволяет аппаратура.

Таймеры

Программные таймеры позволяют запланировать выполнение какой-либо деятельности в определенный момент времени в будущем. Для создания таймера используется функция timer_create(). Одним из аргументов этой функции является структура sigevent, которая определяет вид оповещения о срабатывании таймера (например, посылка сигнала или выполнение указанной функции).

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

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

Дополнительные возможности

Функции nanosleep() и sleep() позволяют приостановить текущий поток управления, либо на указанный интервал времени, либо до поступления сигнала.

Функция nanosleep()является более точной, чем функция sleep(). Функция sleep() позволяет указывать время только с точностью до секунды, тогда как nanosleep() работает с точностью, которая обеспечивается разрешающей способностью часов.

Как известно, земной шар разделен на часовые пояса, в каждом из которых действует свое поясное время. Местное время (время, используемое в данной местности) может отличаться от поясного. На летний период во многих государствах, как правило, часы переводятся на 1 ч вперед (т. н. летнее время).

Если компьютер взаимодействует с другими компьютерами, которые находятся в других часовых поясах и используют другое местное время, то вместо местного времени удобно использовать общее для разных часовых поясов время. В качестве такого времени используется всемирное или мировое время - среднее солнечное время начального меридиана. За начальный меридиан условно принимается меридиан обсерватории в Гринвиче (Великобритания). Это время обозначается GMT или UTC. Хотя между GMT и UTC есть определенная разница, но она не учитывается операционной системой.

Местное (локальное) время описывается разницей с UTC. Эта разница может меняться в зависимости от времени года в связи с переходом на летнее время.

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

Операции ввода/вывода

Базовые операции ввода/вывода, а также асинхронный ввод/вывод реализованы в соответствии со стандартом POSIX, который обеспечивает единообразный доступ к устройствам различных типов.

Потоки ввода/вывода и форматированный ввод/вывод реализован в соответствии со стандартом С.

Устройства и файлы

Устройства и файлы являются основными понятиями системы ввода/вывода. Устройства делятся на физические (например, последовательный и параллельный порт, диск) и логические (например, программные каналы, сокеты).

Для ввода (чтения) информации из устройства и вывода ее в устройство используется понятие файла. Одним устройствам (например, последовательному порту) соответствует один файл, другим (например, диску) - несколько файлов. Файлы, соответствующие устройствам первого типа, называются специальными файлами.

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

Программный канал представляет собой логическое устройство, предназначенное для передачи данных между потоками управления. Данные, записанные в программный канал, считываются оттуда в порядке поступления (First-In-First-Out, первым записан - первым прочитан). Существует 2 типа программных каналов: именованные и неименованные. Первым соответствуют файлы типа FIFO, вторым - файлы типа PIPE.

Базовые операции ввода и вывода

Для выполнения базовых операций предназначены следующие функции:

 

close()

закрытие файла,

 

creat()

создание файла,

 

dup(), dup2()

дублирование дескриптора файла,

 

fcntl(), ioctl()

управление файлом,

 

lseek()

позиционирование файла,

 

open()

открытие файла,

 

read()

чтение файла,

 

write()

запись в файл.

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

Описатель файла содержит также текущую позицию (точку) в файле, которая измеряется в байтах относительно начала файла. Она указывает, к какой части файла будет относиться следующая операция read() или write().

После открытия текущая позиция устанавливается на начало файла. После успешного завершения операции read() или write() текущая позиция в файле продвигается вперед на количество прочитанных или записанных байтов. Изменить текущую позицию в файле можно функцией lseek().

Непредусмотренная стандартом POSIX функция ioctl() позволяет использовать особенности аппаратуры.

Асинхронные операции ввода и вывода

Для выполнения асинхронных операций ввода/вывода предназначены следующие функции.

 

aio_read()

асинхронное чтение;

 

aio_write()

асинхронная запись;

 

lio_listio()

запуск операций асинхронного ввода/вывода по списку.

 

aio_suspend()

ожидание завершения операции асинхронного ввода/вывода;

 

aio_error()

опрос кода ошибки асинхронной операции ввода/вывода;

 

aio_return()

опрос кода возврата асинхронной операции ввода/вывода;

 

aio_cancel()

отмена запроса на асинхронный ввод/вывод;

 

aio_fsync()

асинхронная операция синхронизации файла (обеспечение целостности файла или данных);

Функций read() или write() приостанавливают выполнение потока управления до завершения операции. Асинхронные операции ввода/вывода (aio_read(), aio_write(), lio_listio()) позволяют продолжить выполнение потока управления "параллельно" с операцией ввода/вывода.

Заявки на ввод/вывод обслуживаются в соответствии с ее приоритетом. Этот приоритет не может быть выше, чем приоритет потока подавшего заявку (но может быть меньше его).

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

Целостность файлов и данных

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

Для решения этой проблемы прикладная программа может либо потребовать обеспечения целостности данных или файла при выполнении каждой операции ввода/вывода, либо время от времени вызывать одну из функций: fsync(), fdatasync() или aio_fsync(), которые обеспечиваю целостность данных или файла.

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

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

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

Файловые системы

Дерево каталогов

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

Каждый каталог, кроме корневого, содержится в каком-то другом каталоге. Таким образом, файлы и каталоги образуют древовидную структуру, корнем которой является корневой каталог. Находящиеся в одном каталоге файлы и каталоги имеют уникальные имена. Длина имени файла или каталога ограничена {NAME_MAX} символами.

Находящиеся в разных каталогах файлы и каталоги могут иметь одинаковые имена. В силу этого для идентификации файлов и каталогов используются полные или маршрутные (pathname) имена.

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

Типы файловых систем

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

Корневая файловая система содержит корневой каталог, а также каталог /dev, который содержит все специальные файлы. При монтировании корневой каталог файловой системы помещается в корневой каталог корневой файловой системы (иначе говоря, точка монтирования всегда находится в корневом каталоге).

При конфигурировании операционной системы можно указать файловые системы, которые нужно установить. Эти файловые системы будут установлены при инициализации системы.

Файловые системы делятся на локальные и удаленные. Локальные файловые системы обеспечивают доступ к файлам, находящимся на данном компьютере. Удаленные файловые системы обеспечивают доступ к файлам, находящимся на другом компьютере (плате).

Операционная система поддерживает локальные файловые системы VFAT и TAR, а также удаленные файловые системы NFS и FTP.

Файловая система VFAT

Файловая система VFAT может использоваться для локальных устройств, предназначенных для хранения информации и обеспечивающих прямой доступ. Обмен данными (чтение/запись) между устройством и оперативной памятью производятся драйверами блочных устройств, входящих в состав ППМ. Единицей обмена является блок. С точки зрения файловой системы устройство представляет собой последовательность блоков данных постоянной длины. Такие устройства называются блочными. Таким образом, номенклатура устройств, поддерживаемых файловой системой VFAT на данном компьютере, определяется ППМ.

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

Перед (первым) использованием (логического) устройства его необходимо форматировать. При форматировании на устройстве создаются основные структуры файловой системы. К ним в первую очередь относятся таблица FAT и корневой каталог.

Файловая система TAR

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

Файловая система NFS

Файловая система NFS (Network File System - сетевая файловая система) предоставляет доступ к файлам на удаленном компьютере. Удаленный компьютер, который предоставляет доступ к своим файлам, называется сервером. Компьютер, на котором установлена файловая система NFS, является клиентом. Взаимодействие между клиентом и сервером происходит по NFS-протоколу.

На сервере указываются каталоги, к которым возможен доступ по NFS-протоколу (в случае Линукса для этого используется файл /etc/exports), а также компьютеры, которым разрешен, и которым запрещен доступ (в случае Линукса для этого файлы etc/hosts.allow и /etc/hosts.deny).

При установке файловой системы NFS указывается: адрес сервера, имя каталога на сервере, точка установки.

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

Файловая система типа NFS может использоваться как чтения, так и для записи данных.

Файловая система FTP

Файловая система FTP предоставляет доступ к файлам на удаленном компьютере. Для передачи данных файловая система использует протокол FTP (File Transfer Protocol - протокол передачи файлов). Имя и пароль, указывается при установке (монтировании) файловой системы.

При установке (монтировании) файловой системы создается каталог (соответствующий точке монтирования), который содержит файлы и каталоги, находящиеся в исходном каталоге пользователя (home directory) на удаленном компьютере (FTP-сервере).

Файловая система типа FTP может использоваться только для чтения (но не для записи) данных.

Взаимодействие с сетью

Сетевое программное обеспечение базируется на использовании семейства протоколов TCP/IP, применяемого для передачи данных в сети Интернет.

Важная особенность семейства протоколов TCP/IP - обеспечение межсетевого взаимодействия. Они позволяют интегрировать разнородные сети, содержащие различные компьютеры, работающие под управлением различных операционных систем. Для передачи данных из одной сети в другую используются шлюзы (gateways) - компьютеры, подключенные одновременно к двум или большему числу сетей. Другими словами протоколы семейства TCP/IP дают возможность объединить несколько различных (локальных) сетей в одну общую сеть.

Основные протоколы

Адресация

Для идентификации (определения) компьютера в сети протоколы семейства TCP/IP используют IP-адрес (сетевой адрес) - 32-битное (4-байтное) целое число. Для представления IP-адресов используют также точечную десятичную нотацию. В этом случае значение каждого байта адреса записывается в виде десятичного числа от 0 до 255. Числа отделяются друг от друга символом "точка". Например, 172.16.10.2.

IP-адрес состоит из номера сети и номера компьютера в сети. Если компьютер подсоединен одновременно к нескольким сетям, то он имеет несколько IP-адресов (по одному для каждой сети). Иначе говоря, адресом обладает каждый интерфейс (например, карта Ethernet) компьютера с сетью. Сетевой адрес компьютера (IP-адрес) определяется на этапе конфигурирования ОС.

Протокол ARP

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

Непосредственная передача данных от одного компьютера к другому возможна только в пределах одной сети (иначе требуется посредничество одного или нескольких шлюзов). В этом случае для передачи используются физические адреса (MAC-адреса), а не логические (IP-адреса). Так как логические адреса назначаются, вообще говоря, независимо от MAC-адресов (MAC-адреса назначаются производителями аппаратуры), то для передачи данных нужно уметь преобразовывать IP-адреса в MAC-адреса. Для этой цели и предназначен ARP-протокол (Address Resolution Protocol).

Маршрутизация

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

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

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

Протокол IP

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

Протокол UDP

Протокол UDP (User Datagram Protocol - протокол пользовательских датаграмм) также как и протокол TCP, является надстройкой над протоколом IP. Так при разработке протокола UDP ставилась задача сократить накладные расходы, то отличия протоколов UDP и IP не столь уж велики. Протокол UDP также не гарантирует доставку пакетов и передает данные без установления соединения (каждый пакет пересылается независимо от остальных). Прикладная программа должна сама обеспечивать надежную доставку данных своими средствами (если это требуется).

Используемый UDP адрес получателя состоит из адреса компьютера и номера порта (16 бит), который определяет конкретного получателя на указанном компьютере. При использовании точечной нотации порт указывается после адреса компьютера через двоеточие, например, 183.232.171.241:8080.

Протокол TCP

Протокол TCP (Transmission Control Protocol) также как и протокол UDP, является надстройкой над протоколом IP. Он обеспечивает надежную передачу данных с установлением логического соединения между источником и получателем в виде потока данных (а не в виде пакетов).

Большие возможности TCP (по сравнению с IP и UDP) требуют большой производительности процессора и большой пропускной способности сети. Внутренняя структура модуля TCP гораздо сложнее структуры модуля UDP.

Протокол TCP использует тот же формат для адреса получателя и отправителя, что и UDP, а именно адрес состоит из адреса компьютера и номера порта (16 бит), который определяет конкретного получателя на указанном компьютере.

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

Программный интерфейс

Сокеты обеспечивают программный интерфейс с протоколами семейства TCP/IP. Они позволяют посылать и принимать данные по сети. Сокеты являются конечными точками путей, по которым пересылаются пакеты или потоки данных. Имеется два тип сокетов - потоковые сокеты и дейтаграммные сокеты. Потоковые сокеты используют протокол TCP и называются также TCP-сокетами, дейтаграммные сокеты используют протокол UDP и называются также UDP-сокетами.

Прикладные протоколы

Протокол Telnet

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

Протокол RPC

Протокол RPC (Remote Procedure Call - удаленный вызов процедур) предназначен для выполнения процедур (функций) на удаленном компьютере. Протокол разработан компанией SUN и используется в Интернете.

Протокол RPC используется сетевой файловой системой NFS, а также агентом удаленного отладчика.

При конфигурировании системы пользователь указывает, будет ли использоваться протокол RPC. Если используется файловая система NFS или удаленный отладчик, протокол RPC должен быть включен в образ системы.

Протоколы SLIP и PPP

Протоколы SLIP и PPP предназначены для передачи пакетов данных по последовательным линиям.

Протокол SLIP (Serial Line Internet Protocol - Интернет протокол для последовательных линий) более старый и не является стандартом Интернета (хотя имеется RFC1055 A non-standard for transmission of IP datagrams over serial lines). Протокол SLIP довольно прост. Он пересылает IP пакеты, отделяя их друг от друга символом END (19210).

Протокол PPP (The Point-to-Point Protocol - протокол точка-точка) более новый и является стандартом Интернета (RFC1661).

Многопроцессорные системы

Операционная система содержит средства поддержки многопроцессорных комплексов на MIPS-совместимых процессорах. Их можно использовать для комплексов, состоящих из нескольких плат, взаимодействующих по шине VME. Каждая плата содержит процессор и память. Часть этой памяти доступна только данному процессору (локальная память), другая часть - всем процессорам (общая память). Для посылки прерываний друг другу процессоры используют так называемые "почтовые ящики" - регистры, адресуемые через шину VME. Каждый "почтовый ящик" находится на плате одного из процессоров. Запись в "почтовый ящик" вызывает прерывание соответствующего процессора.

Операционная система обеспечивает взаимодействие потоков управления, выполняющихся на разных процессорах, распределение общей памяти, ведение словаря объектов на общей памяти, а также эмуляцию Ethernet на общей памяти.

Взаимодействие потоков управления

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

Семафоры и очереди сообщений на общей памяти аналогичны POSIX (именованным) семафорам и очередям сообщений, хотя имеются и некоторые отличия

Для семафоров и очередей сообщений на общей памяти используются те же функции, что и для обычных (POSIX) семафоров и очередей сообщений. Благодаря этому программу для многопроцессорного комплекса можно в начале разрабатывать и отлаживать на однопроцессорной ЭВМ, а затем (внеся лишь небольшие поправки в аргументы функций создания семафоров и/или очередей сообщений) отлаживать и использовать на многопроцессорном комплексе.

Распределение памяти

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

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

Пулы памяти помогают избежать фрагментации памяти, а так же облегчают процесс отладки. Если каждый поток управления использует свой пул памяти, то уменьшается "вероятность" того, что переменные одного потока управления будут по ошибке испорчены другим потоком управления.

Словарь объектов в общей памяти

Словарь объектов предназначен для учета следующих объектов в общей памяти:

Словарь содержит набор структур, каждая из которых описывает один объект. Cтруктура содержит следующие сведения об объекте:

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

Эмуляция Ethernet на общей памяти

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

Такой подход позволяет использовать программное обеспечение, разработанное для карты Ethernet, в первую очередь стек протоколов TCP/IP, широко применяемый в Интернет. Таким образом, процессоры на шине VME могут взаимодействовать друг с другом, используя интерфейс передачи данных по сети (аппарат сокетов). Для выхода в локальную или глобальную сеть достаточно одной карты, принадлежащей одному процессорному модулю. Этот модуль используется как шлюз другими процессорными модулями.

Отметим, что эмулятор Ethernet не зависит от других средств межпроцессорного обмена (семафоров, очередей сообщений и др.)

Конфигурирование

Конфигурирование ОС тесно связано с созданием образа ОС, включением в него прикладной программы, а также с инициализацией ОС.

Средства конфигурирования позволяют настроить операционную систему

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

Головным модулем является ос2000.с. Этот модуль получает управление после загрузки ОС. Он производит инициализацию аппаратуры и операционной системы, а затем запускает корневой поток управления прикладной программы и, если требуется командный интерпретатор. В частности ос2000.с содержит в себе модуль initos.c, который инициализирует ОС и обеспечивает конфигурирование аппаратно независимой части ОС.

Условная компиляция модуля initos.c управляется DEFINE-переменными, определяемыми в модуле configos.h. Наиболее удобный способ определения конфигурации - формирование configos.h диалоговой программой.

Настройка на конкретную аппаратуру производится с помощью с помощью конфигурирования ППМ. Каждый ППМ имеет собственные средства конфигурирования.

Средства отладки

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

К средствам отладки относятся также средства протоколирования, которые описаны отдельно.

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

Командный интерпретатор

Командный интерпретатор shell предназначен для интерактивной работы. Для взаимодействия с интерпретатором (для ввода команд и получения результатов) используется консоль. В качестве консоли может быть использован алфавитно-цифровой терминал или telnet соединение. Командный интерпретатор является реентерабельной программой и поэтому можно использовать несколько экземпляров интерпретатора.

Командный интерпретатор позволяет:

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

Локальный отладчик

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

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

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

Динамический загрузчик

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

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

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

Протоколирование

Средства протоколирования аналогичны бортовому самописцу. Они фиксируют события, произошедшие при выполнении программы. Анализ протокола производится после выполнения программы на инструментальной машине специальной программой - "Трассировщиком".

Протоколирование используется для отладки программ и получения временных характеристик.

Интерфейс со средствами протоколирования, базируется на стандарте POSIX 1003.1 2001 г.

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

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

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

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

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

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

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

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