Ваш подход в корне ошибочен. Прерывания носят асинхронный характер; даже если вы закроете гонку между возвратом прерывания и отложенным рабочим элементом, вы можете получить ту же гонку, если прерывание задержано. Рассмотрим:
- ПОЛЬЗОВАТЕЛЬ: установить X = 1
- ПРЕРЫВАНИЕ: График работы
- ПОЛЬЗОВАТЕЛЬ: установить X = 2
- ЧАСТЬ РАБОТЫ: Читать X
против
- ПОЛЬЗОВАТЕЛЬ: установить X = 1
- ПРЕРЫВАНИЕ: (задерживается из-за аппаратной странности ...)
- ПОЛЬЗОВАТЕЛЬ: установить X = 2
- ПРЕРЫВАНИЕ: График работы
- РАБОЧАЯ ОЧЕРЕДЬ: Читать X
Тот же результат, нет? Так что даже не пытайтесь.
Более того, прерывания могут возникать даже в коде ядра. Если приложение находится в середине системного вызова, который не блокирует и не изменяет память, оно должно завершить этот вызов, прежде чем оно позволит вам заблокировать. Заставить его прерваться в состояние, угрожающее тупиками; код ядра может содержать спин-блокировку или иным образом не находиться в безопасном состоянии для планирования.
Обратите внимание, что именно поэтому обработчики прерываний не могут спать - они заставляют свой вызывающий контекст спать, когда он может быть не готов к этому. Это именно то, что вы пытаетесь сделать.
Короче говоря, гонка, о которой вы думаете, не может быть решена; по сути, ваш элемент рабочей очереди просто добавляет задержку к обработчику прерываний, который уже имеет некоторую непредсказуемую величину задержки. Таким образом, пользовательский процесс всегда будет иметь окно, в котором он может связываться со своей памятью. Кроме того, пользовательский процесс может не находиться в состоянии, в котором он может быть прерван.
Так что не беспокойтесь об этом - просто убедитесь, что пользовательский процесс не может саботировать вещи таким образом, который разрушает всю систему, и оставьте для себя уверенность, что он не саботирует сам вплоть до пользовательский процесс (т. е. скажите разработчику пользовательского процесса не связываться с этой памятью, если он хочет, чтобы аппаратное обеспечение работало должным образом).