Ynicky пишет: To alman.
Я вижу следующее изменение процессора.
В области доп. регистров назначается регистр задачи.
Доп. регистры не переключаются между задачами.
Задачи не используют доп. регистры (только ОС).
Добавляются 16 регистровых окон по 16 регистров для стека возвратов
и 16 окон по 16 регистров - для РОН (больше не влезет в существующую м/с).
Такую реализацию на существующей архитектуре процессора вполне можно сделать.
На 16 задачах вполне можно написать специализированную операционную систему. Даже не придётся использовать трюки с помещением нескольких драйверов в одну задачу.
Можно ли не переключать доп. регистры между задачами?
Да, конечно.
Есть некоторый момент с обработчиками прерываний. В простейшем случае обработчик прерывания посылает сообщение драйверу. Благодаря единой точке входа значительно упрощается написание драйверов - любой драйвер можно рассматривать как цикл, блокирующийся в ожидании сообщения. Если пришло сообщение о прерывании - обрабатываем его, если пришло сообщение с командами (например чтение/запись) от другой задачи (ядра системы или прикладной задачи), то обрабатываем его. Таким образом внутри драйвера не нужно сихронизировать структуры данных - они обрабатываются последовательно.
В оригинальной спецификации L4-X2 источник прерывания определяется номером задачи. В случае ST16 номер прерывания можно закодировать в первом регистре буфера сообщений.
Ещё один весьма важный момент. Команды для захвата и освобождения буфера сообщения могут быть не симметричы. Например, вот случай симметрии:
инструкиця LockMessage
код работы с регистрами буфера сообщений
инсрукция UnlockMessage
В этом случае освобождается тот же самый буфер сообщений, который был аллокирован командой выделения буфера. Однако, в реальном системном вызове работа с буфером сообщений не столь наглядна.
Инструкция
ExchangeMessage имеет три аргумента - получатель сообщения, источник сообщения и таймаут (возможно, под это дело можно задействовать дополнительные регистры, или поместить аргументы непосредственно за кодом инструкции, или ещё как-то). Получатель и источник описывают фазы, которые присутствуют в команде. Таким образом инструкция ExchangeMessage может иметь следующие логические формы:
ExchangeMessage - содержит фазу передачи и фазу приёма.
SendMessage - содержит только фазу передачи (в качестве задачи-источника указан 0)
ReceiveMessage - содержит только фазу приёма (в качестве задачи-приёмника указан 0)
(На самом деле форм чуть больше, но не хочется усложнять пример - остальные формы вытекают из этих и не противоречат описанным)
Например, схема библиотечной функции, которая производит обращение к ядру.
инструкция LockMessage
код установки регистров буфера сообщений
инструкция ExchangeMessage
код чтения регистров буфера сообщений
инструкция UnlockMessage
Инструкция ExchangeMessage переключает контекст, перекоммутируя буфер сообщения задаче обработчику. Момент в том, что в процессе обработки сообщения назад может вернуться другой буфер. По большому счёту программисту не важно, какой именно буфер сообщения вернул системный вызов - UnlockMessage просто осободит активный буфер.
Однако, сообщение может не иметь фазы приёма или фазы передачи - именно этот момент демонстриует отсутствие симметричности. Например, задаче необходимо лишь передать сообщение, но не нужен ответ. Если ExchangeMessage не имеет фазы приёма, то после завершения команды у задачи не будет назначенного буфера и его не придётся освобожать. Верно и наоборот - если сообщение имеет только фазу приёма, то перед вызовом команды не нужно захватывать буфер, но после приёма и обработки сообщения буфер необходимо отпустить. Таким образом следующие виды команд вполне допустимы и имеют смысл:
Только передача сообщения
инструкция LockMessage
код установки регистров буфера сообщений
инструкция ExchangeMessage без фазы приёма
Только приём сообщения
инструкция ExchangeMessage без фазы передачи
код чтения регистров буфера сообщений
инструкция UnlockMessage