В прошлый раз, когда я писал о Real-Time Java Specification, я дал ссылочку на список материалов от разработчиков виртуальной машины Ovm. За прошедшее время удалось прочесть большую статью A Real-Time Java Virtual Machine with Applications in Avionics оттуда. Сама статья для меня оказалась мало полезной и не очень интересной, т.к. ни виртуальными машинами для Java, ни Real-Time Java я не занимаюсь. Хотя любопытно было узнать, что под управлением этого Ovm люди умудрились запустить небольшой беспилотник. Но две вещи запомнились.
Во-первых, интересным образом разработчики Ovm поступили с многопоточностью и диспетчеризацией потоков. Поскольку Ovm работает на одной нити ОС, то всю диспетчеризацию Java-потоков Ovm делает сама. И для того, чтобы прерывать текущий поток и передавать управление другому потоку они сделали следующее: при трансляции Java-исходников просто напросто добавляются специальные вызовы в код (называемые Poll Check-ами). Т.е. если изначально программист написал что-то вроде:
void someMethod() { ... while(...) { ... } } |
То во время трансляции он будет преобразован в:
void someMethod() { POOLCHECK(); ... while(...) { ... POOLCHECK(); } } |
А внутри конструкции POOLCHEK происходит проверка необходимости передиспетчеризации нитей. Т.е. не внешний по отношению к коду диспетчер определяет, пора ли текущую нить прервать, а сама текущая нить время от времени озадачивается вопросом “А не пора ли дать управление кому-нибудь другому?”
Во-вторых, разработка Ovm шла еще до появления Java 1.5 с аннотациями, поэтому каких-то специальных средств связать метаинформацию с кодом у разработчиков Ovm не было. И они поступили очень остроумно, на мой взгляд – задействовали для этих целей инструкцию throws:
void storeCheck(VM_Address src, int offset, VM_Address tgt) throws PragmaNoPollcheck, PragmaNoBarriers, PragmaInline { int sb = src.asInt() >>> blockShift; int tb = tgt.asInt() >>> blockShift; if (sb != tb) storeCheckSlow(sb, tb); } |
Здесь PragmaNoPollcheck, PragmaNoBarriers и PragmaInline – это не имена исключений, которые могут выбрасываться из метода, а инструкции для Ovm-овского компилятора.
Забавный подход. Который демонстрирует, что любые штатные возможности могут использованны самым непредсказуемым образом (здесь я с ностальгией вспоминаю игрушку Lode Runner, реализованную на алфавитно-цифровых дисплеях Robotron 1715).