Этой обзорной статьёй я открываю серию статей, посвящённых языку Активный Оберон и операционной системе A2, написанной на этом языке.
Итак, встречайте — Активный Оберон
Первая публикация по Активному Оберону появилась в 1997 году, но понятно, что язык и его реализация появились несколько раньше. За эти годы произошло много изменений в языке, переработана среда времени выполнения, написана операционная система A2…
Особенностью языка, отличающей его от других языков программирования, является концепция Активных Объектов — объектов, инкапсулирующих поток выполнения. Активный Оберон расширяет язык Оберон, вводя объектный тип Объект, понятие Активность, связанная с объектом (поток), а также механизмы синхронизации и защиты от одновременного доступа. Реализация таких механизмов на уровне языка позволяет упростить разработку и реализацию многопоточных приложений и снижает количество ошибок, связанных с проблемой защиты и синхронизации.
В секции импорта подключаемые модули могут иметь псевдонимы, различные модули могут иметь один и тот же псевдоним, формируя из нескольких модулей некое подобие пространства имён. В таких модулях имена экспортированных сущностей не должны пересекаться.
Например:
IMPORT Example := Example1, Example := Example2;
В Активном Обероне реализованы улучшенные массивы (математические и тензорные), структурные массивы (объекты, совместимые с улучшенными массивами), комплексные типы, операции для объектов, улучшенных массивов и комплексных типов, делегаты, совместимые как с процедурами модуля так и с методами объекта. Вместо множественного наследования используется концепция множественного наследования интерфейсов.
Синтаксис языка в процессе развития практически не изменяется — вместо этого вводятся семантические модификаторы, изменяя семантику синтаксических конструкций, присутствующих в языке. Список модификаторов заключаются в фигурные скобки {}.
Так, для описания делегата используется модификатор процедуры DELEGATE:
Example1 : PROCEDURE{DELEGATE, REALTIME} ( VAR parameter : LONGINT ) : BOOLEAN;
В примере описана процедурная переменная Example1, указывающую на делегат — процедуру или метод реального времени, принимающие переменную типа длинное целое по ссылке и возвращающие значение логического типа.
Методы описываются внутри объекта. Все методы в Активном Обероне являются виртуальными. Методы, перед именем которых стоит знак & являются конструкторами и вызываются автоматически при создании объекта. Компилятор выбирает требуемый конструктор по сигнатуре вызова встроенной процедуры NEW, предназначенной для создания сущностей ссылочного типа. Объекты и методы могут также иметь модификаторы ABSTRACT и FINAL с понятной семантикой. Операции (операторы) могут описываться как на уровне объекта, так и на уровне модуля, за исключением некоторых операторов, описываемых только на уровне объекта (по крайней мере в текущей реализации).
Активные Объекты и модель многопоточности
Объект может иметь тело — завершающий блок операторов, выполняемый после инициализации объекта. Если тело объекта помечено модификатором ACTIVE (возможно с указанием приоритета), то такой объект называется активным. Как уже говорилось, активность (поток) инкапсулирована в объекте и создаётся в момент инстанцирования активного объекта. Активность существует пока выполняется тело активного объекта. Активный объект продолжает существовать, пока существует его активность, даже если на него нет ссылок, после чего он становится пассивным и может быть утилизирован в обычном порядке.
Коммуникация между активностями производится через вызовы методов активных и не активных объектов.
Защита от одновременного доступа к состояниям объекта осуществляется поддержкой на уровне языка монопольных областей (exclusive regions) — последовательности операторов, заключённых в операторные скобки BEGIN… END, помеченные модификатором EXCLUSIVE, — соответствующих концепции критических областей Бринча Хансена. Если монопольная область охватывает всё тело объекта, он называется монопольным и совмещает концепцию критических областей Хансена с концепцией процедуры монитора Хоара. В отличии от процедур монитора Хоара, методы объекта не обязаны быть монопольными, и могут наблюдать не синхронизированные состояния объекта. Модуль считается объектом с одним экземпляром. Компилятор и среда времени выполнения гарантируют, что в монопольной области может находиться не более одной активности одновременно.
Таким образом, модель защиты в Активном Обероне — монитор, размещенный в экземпляре объекта (instance-based monitor).
Главная идея монитора в том, что с ним связан инвариант — выражение, определяющее внутреннее, непротиворечивое состояние и доказывающее правильность его поведения. Инициализаторы объекта устанавливают инвариант, а монопольные методы его поддерживают.
Для синхронизации в Активном Обероне используется оператор AWAIT, тогда, как большинство реализаций мониторов используют условные переменные Хоара на основе очередей Хансена. Оператор AWAIT принимает в качестве аргумента логическое условие продолжения выполнения, в случае несоблюдение которого активность приостанавливается, а захваченная монопольная область освобождается до момента, когда условие выражения станет истинным. Активность продолжит работу когда снова сможет войти в отпущенную ранее монопольную секцию. Условия продолжения пересчитываются только когда какая-либо активность выходит из монопольной секции.
Пример описания активного объекта и использования монопольной секции:
TYPE
Timer* = OBJECT
VAR
timer: Objects.Timer;
handler: Objects.EventHandler;
timeout, running: BOOLEAN;
PROCEDURE &Init*;
BEGIN
NEW(timer);
timeout := FALSE;
running := TRUE;
END Init;
PROCEDURE SetTimeout*(h: Objects.EventHandler; ms: LONGINT);
BEGIN
handler := h;
Objects.SetTimeout(timer, HandleTimeout, ms)
END SetTimeout;
PROCEDURE CancelTimeout*;
BEGIN
Objects.CancelTimeout(timer);
END CancelTimeout;
PROCEDURE HandleTimeout;
BEGIN {EXCLUSIVE}
timeout := TRUE
END HandleTimeout;
PROCEDURE Finalize*;
BEGIN {EXCLUSIVE}
Objects.CancelTimeout(timer);
running := FALSE
END Finalize;
BEGIN {ACTIVE}
WHILE running DO
LOOP
BEGIN {EXCLUSIVE}
AWAIT(timeout OR ~running);
IF ~running THEN
EXIT
END;
timeout := FALSE
END;
handler()
END
END
END Timer;
Управление памятью.
В Активном Обероне применяется автоматическое управление памятью, с использованием сборщика мусора реального времени. Это значит, что активности реального времени могут приостанавливать процесс сборки мусора. В участках кода реального времени запрещены операции выделения памяти за этим следит компилятор. Процедуры, методы и активности реального времени помечаются модификатором REALTIME. Не все реализации компилятора и среды выполнения поддерживают процессы реального времени.
Переменные, помеченные модификатором UNTRACED относятся к нетрассируемым указателям и не отслеживаются механизмами автоматического управления памятью.
В языке синтаксически поддерживается оператор DISPOSE, но его реализация может отсутствовать.
На этом я завершаю обзорную статью языка Активный Оберон, начать знакомство рекомендую с классического Оберона.
Ссылки:
- Багтрекер, исходный код ОС A2, включая компилятор Активного Оберона. Также в репозитории находятся варианты A2, запускаемые под Windows и *nix
- Документация и инструкции
- Форум поддержки
- Критика языка Оберон от отцов-основателей. Выдержка из диссертации Патрика Реали, создателя многопоточного компилятора языка Активный Оберон, JVM, работающей поверх рантайма ОС A2 и внёсшего значительный вклад в развитие Оберон-Технологий.
Комментарии (41)
CONSTantius
27.05.2015 16:43+9В Активном Обероне применяется автоматическое управление памятью, с использованием сборщика мусора реального времени. Это значит, что активности реального времени могут приостанавливать процесс сборки мусора. В участках кода реального времени запрещены операции выделения памяти за этим следит компилятор. Процедуры, методы и активности реального времени помечаются модификатором REALTIME. Не все реализации компилятора и среды выполнения поддерживают процессы реального времени.
Вот это действительно круто. Я время от времени думаю, почему в Rust не хотят сделать аннотаций «не выделяет память», чтобы как раз помечать функции, безопасные для использования в контексте какого-нибудь обработчика сигналов, например.
Ну и вообще, ради этого параграфа стоило прочитать публикацию. Только что узнал об Обероне больше, чем за последнюю неделю общения с его пользователями (не с вами).
Ещё: так работает любой Оберон, или именно Активный?
Правильно я понимаю, что язык по сути неотделим от среды исполнения, которая, можно сказать, является одновременно ОС и IDE? У меня сложилось впечатление, что Оберон-Система — это вот про это.
Можно ли использовать Активный Оберон (или любой Оберон) на Линуксе?valexey
27.05.2015 16:50+2Ещё: так работает любой Оберон, или именно Активный?
Именно Активный. Active Oberon это отдельный ЯП, дальнейшее развитие системы и языка в стенах Швейцарской высшей технической школы Цюриха
Использова Active Oberon в линуксе или винде можно, примерно также как можно использовать смалтолк/squeak. Хотя Kemet лучше расскажет, возможно там есть реализации которые не тащат с собой например всю среду.
В плане любых оберонов — там разное бывает. Во-первых есть реализации ОС Оберон в виде приложения (не эмулятора, а именно приложения, опять же, привет smalltalk/squeak только с учетом того, что Оберон компиляется в реальные машкоды целевой архитектуры, например x86 — никаких эмуляторов). А во-вторых довольно много самых разных компиляторов оберона и оберона-2, как в x86, так и в Си например.
То есть Оберон (не Active — про Active я лично просто не в курсе) бывает без среды под винду или линукс. В качестве IDE были какие-то плагины к eclipse, ну или можно использовать Sublime Text. Мною к sublime был даже плагин писан для того, чтобы было удобней код набирать (в частности ключевые слова там становились КАПСОМ автоматом, не нужно никаких шифтов жать).
Kemet Автор
27.05.2015 17:00+2Сборщик мусора реального времени есть для среды времени выполнения Активного Оберона ( в варианте реализации этой среды в ОС A2, в которой есть подсистема реального времени ) и для классического Оберона в реализации XOberon — ОСРВ на базе Oberon System
Для функционирования программ на Активном Обероне достаточно использовать среду времени выполнения (RTL):
Trace.Mod — Low-level trace output based on KernelLog
*.Machine.Mod — Bootstrapping, configuration and machine interface
Heaps.Mod — Heap management and garbage collector
Modules.Mod — Modules and types
Objects.Mod — Active object runtime support
Kernel.Mod — Implementation-independent kernel interface
Использовать АО(Активный Оберон) на ОС, отличных от A2, можно посредством вариантов A2, работающих поверх Windows, Unix/Linux/Darwin — там вся A2, за исключением железа, но работают и сетевые протоколы и сервисы и медиа. Можно собрать консольную программу, оставив рантайм и свой код.
Из других Оберонов под Линукс можно использовать OO2C или XDSCONSTantius
27.05.2015 17:04+1А моя консольная программа будет линковаться к рантайму как к динамической библиотеке? Или там что-то похожее на большую виртуальную машину типа Java?
Kemet Автор
27.05.2015 17:15+4Пока статическая линковка всех модулей.
Но эта статически собранная программа может загружать динамические модули, то есть можно написать некий стартер, которому в качестве параметров передавать команды для запуска приложений.
Но лучше использовать UnixAos полностью
Kemet Автор
27.05.2015 17:10+2Забыл, есть ещё Oxford Oberon-2 Compiler, который в том числе и под Линукс
Googolplex
27.05.2015 18:05+3Я время от времени думаю, почему в Rust не хотят сделать аннотаций «не выделяет память», чтобы как раз помечать функции
На самом деле, кода в Rust ещё использовалась концепция typestate, почти так оно и было. Потом от typestate отказались, потому что она приводит к проблемам с композицей (вот здесь есть ещё информация). Та же самая штука была с pure-функциями (они тоже были, и от них тоже отказались).
CONSTantius
27.05.2015 17:02+23- Сделать виртуалов
- Неделю писать с них всякий неадекват
- Написать нормальный пост с настоящего пользователя
- На контрасте получить отличные оценки (ура, не все пользователи Оберона — сумасшедшие фрики!)
- PROFIT
Это шутка, конечно.NeoCode
27.05.2015 17:07+6Кстати, а где они, наши виртуальчики? Наконец-то нормальный пост, интересно что бы они сказали, а их нету…
Kemet Автор
27.05.2015 19:49+1Добавил в статью ссылку на форум поддержки, там, в принципе, есть ссылки на свежие сборки нативной A2, WinAOS, UnixAos
shiko_1st
27.05.2015 21:23У меня только один вопрос — кто-то запилил уже нормальную IDE, или это все так и осталось на уровне наколенных поделок?
valexey
27.05.2015 21:32Смотря что под нормальной IDE подразумевать :-) Вот Sublime Text — это нормальная IDE? А допустим гошная LiteIDE? А Code::Blocks? А vim? А CLion?
Скажи что нужно, расскажем что есть, а чего нет, но что есть вместо этого.shiko_1st
27.05.2015 21:54Сейчас у меня есть куча древнего кода на Oberon 2, который можно компилить только при помощи кросс-компилятора под MC68332 из совершенно эзотерической среды этого самого Oberon под Win (где половина операций по средней кнопке мыши). Поэтому правки кода я делаю в pspad, а для компиляции запускаю среду. Учитывая, что ничего нового на этом разрабатываться уже не будет никогда, хотелось бы просто автоматизировать компиляцию.
valexey
27.05.2015 22:10Погоди, а это не ты ли на RSDN с годик назад искал какого-нибудь оберонщика на тему правки древних-древних сырцов оберона? ( http://rsdn.ru/forum/job/5715649.all )
Вообще, полагаю, можно сделать так, чтобы Оберон среда запускалась, что-то делала (аргументы что именно делать — передавать в виде аргументов, или же таки через файл) и сразу вырубалась. Какая именно версия используется?shiko_1st
27.05.2015 22:21Кореш мой писал. Да, речь шла про этот код. Собственно, с кодом разобрались еще в ноябре прошлого года, в целом все под контролем.
Версия 2.4.5, если я ничего не путаю. Как версию можно узнать точно, не совсем понятно.
Может, поможет дата создания oberon.exe — 1997 год.
SergioShpadi
28.05.2015 12:59+4Вот спасибо. После просмотра нормального примера кода на Обероне без однобуквенных имен переменных и процедур, не такими уж и плохими кажутся BEGIN-END вместо скобок
Kemet Автор
28.05.2015 13:12+2Пожалуйста. Также, в Активном Обероне ( как и в Zonnon'е ) ключевые слова можно писать в нижнем регистре
Kemet Автор
29.05.2015 10:51+2Добавил в статью выдержку из диссертации Патрика Реали, создателя многопоточного компилятора Активного Оберона, JVM для A2 и вообще внёсшего существенный вклад в Оберон-Технологии. Критика Языка Оберон от отцов-основателей, «чтобы в корне пресечь кривотолки»
CONSTantius
29.05.2015 12:59-1Многопоточный компилятор — это мощно. Хочется сказать, беспрецедентно. Для каких-то ещё языков были многопоточные компиляторы?
pehat
Астрологи объявили неделю Оберона?
Yuuri
Срач в комментах утроился, ага. К счастью, Kemet — вроде бы новый человек, и будем надеяться, что тут обсуждение выйдет более продуктивным.
valexey
Да, это реальный человек, не очередной виртуал.
Насколько я знаю, в его компании промышленно используют Active Oberon (а еще Модулу-3 например).
mayorovp
Ну, Активный Оберон, в отличии от Великого Оберона, интересен скорее наличием фич, чем их отсутствием.
Я бы не стал смешивать эти языки.