Обработчики прерываний часто манипулируют данными, используемыми также и ядром системы. Это требует синхронизации доступа к разделяемым данным. В традиционных системах UNIX ядро обеспечивает ее, повышая уровень приоритета прерываний (ipl) для блокирования тех прерываний, которые в состоянии получить доступ к таким данным. Часто объекты защищаются от прерываний, хотя обращение к ним со стороны каких-либо прерываний мало реально. Например, очередь спящих процессов должна быть защищена от прерываний, хотя большинству из них нет необходимости обращаться к этой очереди. Эта модель обладает несколькими существенными недостатками. Во многих системах процедура увеличения или уменьшения уровня ipl является весьма затратной и требует выполнения нескольких инструкций. Прерывания представляют собой важные и обычно экстренные события, поэтому их блокирование уменьшает производительность системы в большинстве случаев. В многопроцессорных системах эта проблема еще актуальнее, так как ядру системы приходится защищать намного большее количество объектов и обычно приходится блокировать прерывания на всех имеющихся процессорах.
В операционной системе Solaris традиционная модель прерываний и синхронизации заменена новой технологией, увеличивающей производительность, в первую очередь, на многопроцессорных системах [11], [17]. Новая модель не использует уровни ipl для защиты от прерываний. Вместо этого применяется набор различных объектов ядра для осуществления синхронизации, таких как взаимные исключения или семафоры. Для обработки прерываний используется набор нитей ядра. Такие нити прерываний могут быть созданы «на лету»; им будет назначен более высокий приоритет выполнения, чем у любых других существующих нитей. Нити прерываний используют те же основные элементы синхронизации, что и любые другие нити, и, следовательно, могут блокироваться в тех случаях, когда необходимый им ресурс занят другой нитью. Ядро блокирует обработку прерываний только при возникновении малого количества исключительных ситуаций, например при попытке освободить mutex, защищающий очередь спящих процессов.
Хотя создание нитей ядра является относительно несложной процедурой, однако организация новой нити для каждого прерывания слишком накладна. Ядро содержит набор предварительно выделенных и частично инициализированных нитей. По умолчанию такой набор состоит из количества нитей, равного количеству уровней прерываний помноженному на количество процессоров плюс еще одна общая системная нить для таймера. Поскольку каждая нить требует около 8 Кбайт для хранения стека и данных, весь набор занимает значительное количество памяти. На системах, обладающих небольшим объемом памяти, имеет смысл уменьшить количество нитей в наборе, так как ситуация, когда необходимо будет одновременно обрабатывать все прерывания, маловероятна.
Нить HI выполняется на процессоре П1 в тот момент времени, когда он получает прерывание. Обработчик прерывания в первую очередь поднимает уровень ipl для предотвращения дальнейших прерываний того же или более низкого уровня (предохраняющая семантика системы UNIX). Далее происходит выделение нити прерывания Н2 из набора нитей и переключение контекста на нее. Пока нить Н2 выполняется, HI остается прикрепленной (pinned). Это означает, что она не может выполняться на другом процессоре. После завершения Н2 происходит обратное переключение контекста к нити HI, которая затем продолжает свою работу. Кстате, рекоммендую обратить внимание на технологию интелектуальный дом. Нить прерываний Н2 выполняется без полной инициализации. Это означает, что она не является полноценной нитью и не может быть вытеснена. Инициализация завершается только в том случае, если нить имеет причину для блокирования. Тогда она сохраняет свое состояние и становится независимой нитью, выполняющейся на любом свободном процессоре. Если нить Н2 заблокируется, управление возвратится к HI.