Доброе время суток! В многопроцессорной среде при срабатывании прерывания есть ли какая-то уверенность, что управление обработчиком не будет передано планировщиком другому процессору? И как можно этой уверенности добиться? Ясно, что в самом начале обработчика можно вызвать KeSetAffinityThread, но нет никакой гарантии, что до окончания выполнения этой функции управление не получит другой проц. Как это можно побороть?
вообще то на эту тему лучше почитать Рихтера. А вообще, привязка к процессору должна помочь. как так упраление не получит другой проц, конечно получит, в этом и смысл многопроцессорности, но есть такая фишка, как интерлоки, или как там это называется, сам я с ними дело неимел, с кучей процев, но, к примеру, если интересно, как это организовано в драйвере, распотроши sable драйвер, тот , что 1С обманывает, там есть код для этого дела, который #UD перехватывает, да и глянь.
> вообще то на эту тему лучше почитать Рихтера. а что именно из Рихтера? Да именно такая технология и интересует. Нет ли способа проще - на уровне нескольких вызовов яункций ядра? Может, кто знает?
Если в обработчике прерывания irql > DISPATCH_LEVEl, то во время его работы на другой проц нить переключиться не может. Если irql ниже, то можно просто его поднять.
Если прерывание вызвано командой CD01 или F1, то irql=PASSIVE_LEVEL, если вызвано аппаратно (срабатыванием бряка на Dr регистрах, или флагом трассировки), то irql > DISPATCH_LEVEL
А каким способом в обработчике можно определить, на каком проце произошло прерывание? В тек эта информация не помещается?
Wolfgang по логике вещей, прерывание может произойти в контексте какого либо процесса, а там дальше найти и глядеть в kprcb. там и будет видно Хотя, может могу и ошибаться.
суть в том, что теоретически, пока я это делаю, управление может получить другой проц... в общем, пока я не придумал ничего более универсального, чем определение для каждого проца переходников типа push 000100b ; маска проца jmp my_handler с последующим извлечением из стека уже внутри общего обработчика и вызовом KeSetAffinityThread, но хочется как-то изящнее
Процедура ISR выполняется на уровне DIRQL, который больше DISPATCH_LEVEL => планировщик никоим образом не всплывает "Программирование драйверов Windows" Спин-блокировка является, по сути, объектом типа мьютекс, однако с более более широкими полномочиями. Когла фрагмент кода... собирается обратиться к одной из «охраняемых» структур данных, он должен сначала выполнить запрос на владение спин блокировкой. Так как только один из процессоров в каждый момент времени имеет право собственности на объект спин-блокировки, то таким образом и обеспечивается разделение доступа к охраняемым данным между потоками, работающими на разных процессорах... А это, что касаемо разделяемых ресурсов, только учти, что KeAcquireSpinLock вызывается при IRQL<=DISPATCH_LEVEL. И в ISR его лучше не использовать, иначе надо понижать IRQL. К тому же рекомендуется использовать DPC очередь для обработки IRP, когда IRQL понижается, а в ISR только эту очередь организовывать. Вообще, если хочешь узнать про работу с прерываниями возми книгу Солдатова, хоть на форуме о ней не очень лесно отозвались, IMHO отличное дополнение к знаменитым урокам Four-F