Ядро должно доставить сигнал в пользовательское пространство. Вы правы, что это не происходит само по себе на оборудовании. Вот почему обработка сигналов может учитывать красную зону пользовательского пространства, sigaltstack
и действия по умолчанию, если не зарегистрирован обработчик.
Как только ядро получит управление, оно может доставить сигнал в user-space (или выполните действие по умолчанию, игнорируя его или завершая процесс).
Если сигнал был отправлен процессом, запущенным на другом ядре, процессу, запущенному на this core, то, вероятно, он доставляется в пользовательское пространство из обработчика IPI или просто при следующем прерывании таймера или системном вызове, который дает ядру возможность проверить наличие ожидающего сигнала.
Когда IPI обработчик прерываний готовится вернуться в пользовательское пространство, он замечает, что есть ожидающее прерывание для процесса, к которому он собирается вернуться. (Либо с особым случаем для одного типа IPI, либо с помощью планировщика, поскольку мы все равно находимся в ядре). Вместо использования iret
для возврата к кадру прерывания, выдвинутому аппаратными средствами для асинхронного c прерывания, ядро вместо этого может iret
по адресу обработчика сигнала пользовательского пространства.
Весь смысл использования IPI (если это то, что делает Linux) состоит в том, чтобы передать управление ядру раньше, а не просто ждать, пока оно заметит ожидающий сигнал при следующем вызове schedule()
.
Если процесс, которому отправляется сигнал, в настоящее время не запущен ни на одном ядре, он либо пробуждает процесс, если есть свободный ЦП, либо сигнал просто остается там для этой задачи, пока планировщик на каком-то ядре решает запустить его на этом ядре. В этот момент он заметит и доставит ожидающий сигнал.