код спинлока при условии отсутствии коллизии выполнится быстрее... нет?
Захват спинлока это наверное 2 инструкции. Выполняется действительно быстро. Но это вообще никому не интересно. Гораздо интереснее другое. Чтобы захватить спинлок, надо переключиться на DISPATCH_LEVEL. В этом вся суть.
(click to show)
Если говорить о тонкостях, я лично не измерял сколько времени уходит на переключение Irql, но думается, что операция эта уже не такая быстрая как захват спинлока (без конкуренции). Достоверно известно (мне лично), что переключение Irql на разных платформах может происходить абсолютно по-разному. Но всё это тоже абсолютно не интересно
Зайдём не со стороны каких-то изысканий в плане производительности, а со стороны реальной практики.
Люди во всём мире со времён зарождения Irql всячески пытаются выполнять работу на PASSIVE_LEVEL. Пишут статьи, заметки, которые обосновывают такой подход. Говорят о том, что на DISPATCH'е не доступен ввод/вывод (например файловый), что не нужно примерять на себя костюм планировщика и работать на его Irql'е, когда есть другие варианты, что не нужно пользоваться опасными методами, когда есть безопасные. Ведь в конце концов вы не знаете на какой машине, при какой нагрузке будет выполняться ваш код, и следовательно никак не можете посчитать время, которое вы проведёте под спинлоком. А ведь оно ограничено. Майкрософт распинается, придумывает рабочий поток, рабочие элементы, пишет разные статьи, best practice, всё для людей, чтоб только люди смогли обеспечить выполнение своего кода на PASSIVE_LEVEL. Люди переходят с DIRQL на DISPATCH при помощи DPC. С DISPATCH_LEVEL на PASSIVE_LEVEL. Вроде мир движется, вроде работает всё.
Тут появляется некий мега-кодер (назовём так этого абстрактного злодея). Сидит он дома и пишет на своей "коленке" мега-код. Есть у него там обычный список с какими-то данными. Есть так же пара функций, которые вызываются операционной системой на PASSIVE_LEVEL. Казалось бы, ну как здесь можно намудрить, PASSIVE_LEVEL, все удобства, бери какой-нибудь Fast Mutex (для примера) и работай спокойно. Никаких тормозов никогда в жизни не было бы. Вместо этого мега-кодер решает, что Fast Mutex будет не так круто. Берёт спинлок, задирает себя до dispatch'а (практически до небес) и копается со своими данными как ребёнок в песочнице. Вопрос: кого за ним выслать? Дурку, чтоб подлечили или священника, чтоб грехи отпустил?
Суть в том что никогда не нужно самому залезать на DISPATCH_LEVEL.
Если серьёзно, навскидку, я вижу одну явную ситуацию, когда стороннему драйверу нормально работать на диспаче - это когда его вызвали на диспаче.
И то, если возможно, нормальные люди откладывают выполнение полезных действий на потом, дабы перепланироваться на PASSIVE_LEVEL. Справедливости ради надо сказать, что отложить какие-то полезные действия можно не всегда. Понятное дело что если "полезные действия" - это записать несколько байтов, то откладывать такое нет ни малейшего смысла.
Мораль: спинлок в качестве блокировки подойдёт только тогда, когда абсолютно невозможно применить что-то другое (когда ситуация такая, что больше нечего применить).