"Валерий Аджиев "Мифы о безопасном ПО: уроки знаменитых катастроф" [V]" - читать интересную книгу автора

другому режиму и потому не подлежала рациональной оценке, операторше не
пришло в голову.

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


Программная блокировка и ее последствия

Рассмотрим еще один инцидент с Therac-25, которому суждено было стать
последним. Он произошел в Yakima Valley Memorial Hospital (штат Вашингтон)
в январе 1987 г. Пациенту было предписано сначало проделать два
рентгеновских снимка с дозой в 4 и 3 рад соответственно, а затем
произвести в фотонном режиме облучение в 86 рад. Все это и было выполнено,
однако, как потом было установлено, пациент получил переоблучение фотонной
дозой до 10000 рад.
(Установлено было "потом", а не сразу оператор, сделав снимки, забыл
вынуть рентгеновскую пленку из-под пациента, из-за чего у него на консоли
горели все те же 7 рад; однако, и правильная индикация уже выданной дозы
была бы здесь как в буквальном смысле слова мертвому припарки).

Что же произошло? Выявленная в итоге расследования проблема выходит
далеко за пределы частного случая еще одной программистской ошибки. В
данном случае не сработала блокировка, реализованная программно
позволившая прибору действовать (испускать поток фотонов) при ошибочной
установке параметров.
Ситуация возникла в момент, когда введенные параметры уже
верифицированы подпрограммой Datent и монитор Treat в соответствии со
значением переменной Tphase = 3 вызвал подпрограмму Set Up Test.

Во время установки и подгонки параметров подпрограмма Set Up Test
вызывается несколько сотен раз пока все параметры не будут установлены и
верифицированы, о чем эта подпрограмма судит по нулевому значению
разделяемой переменной F$mal. Если же значение ненулевое цикл повторяется.
F$mal, в свою очередь, устанавливается подпрограммой Chkcol (Check
Collimator) из критической задачи Housekeeper, проверяющей, все ли с
коллиматором нормально; а вызывает Chkcol другая подпрограмма задачи
Housekeeper под названием Lmtchk (analog-to-digital limit checking), и
вызов этот происходит, только если значение разделяемой переменной Class3
ненулевое. А ненулевым его делает как раз сама Set Up Test, которая (пока
F$mal=0) каждый раз выполняет над Class3 операцию инкремента.

Эта переменная однобайтовая, следовательно каждый 256-й проход
заставляет ее сбрасываться в ноль. А ведь этот ноль свидетельство, что все
параметры, наконец, установлены. Если повезет, что именно в этот момент
оператор нажмет клавишу "set" для запуска установки коллиматора в