동기화 예제

다음 예제에서는 동기화와 관련하여 미니 드라이버가 수행해야 하는 작업을 보여 줍니다. 동기화를 사용하지 않아야 하는 경우의 예제를 포함합니다.

  • 예제 1: 작동하는 ISR이 있는 미니 드라이버

    스트림 클래스 동기화가 켜져 있으면 KeSynchronizeExecution을 사용하여 모든 미니 드라이버 진입점이 발생된 IRQL에서 호출됩니다. 즉, 미니 드라이버가 코드를 실행할 때 어댑터의 IRQ 수준과 모든 하위 IRQ 수준이 마스킹됩니다. 따라서 미니 드라이버는 이 모드에서 적은 양의 작업만 수행해야 합니다.

    미니 드라이버는 일반적으로 발생된 IRQL에서 10~20 마이크로초 이상 걸리는 코드를 실행해서는 안 됩니다. stream.sys 디버그 빌드를 사용하는 경우 스트림 클래스는 발생된 IRQL에 소요된 시간을 기록하고 드라이버가 너무 많은 시간을 소비하는 경우 어설션합니다. 미니 드라이버가 요청에 대해 하드웨어 DMA 등록을 프로그래밍해야 하거나 ISR에서 포트를 읽어야 하는 경우 일반적으로 발생된 IRQL에서 모든 처리를 수행할 수 있습니다.

    미니 드라이버가 PIO를 통해 데이터를 전송하는 미니 드라이버와 같이 몇 마이크로초 이상 걸리는 처리를 수행해야 하는 경우 미니 드라이버는 StreamClassCallAtNewPriority를 사용하여 DISPATCH_LEVEL 콜백을 예약해야 합니다. 콜백에서 미니 드라이버는 처리를 수행하는 데 최대 1/2~1밀리초가 걸릴 수 있습니다. 이 모드에서 기억해야 할 한 가지는 DISPATCH_LEVEL 콜백이 ISR과 동기화되지 않는다는 것입니다.

    미니 드라이버가 ISR뿐만 아니라 콜백 중에 리소스(예: 포트 또는 큐)에 액세스할 때 하드웨어가 안정적으로 유지되는 경우 이러한 동기화 부족은 문제가 되지 않습니다. 그러나 불안정성이 문제가 될 수 있는 경우 미니 드라이버는 StreamClassCallAtNewPriority를 사용하여 DISPATCH_LEVEL 콜백이 ISR에서 사용하는 리소스와 공유되는 리소스에 영향을 주는 높은 우선 순위 콜백을 예약해야 합니다.

    높은 우선 순위 콜백은 KeSynchronizeExecution을 호출하는 것과 같습니다. KeSynchronizeExecution을 사용하려면 Minidriver에서 StreamClassCallAtNewPriority가 참조하지 않는 여러 매개 변수를 참조해야 하지만 일반적으로 두 매개 변수는 동일한 동작을 발생시킵니다.

    미니 드라이버가 1/2~1밀리초가 넘는 코드를 실행해야 하거나 PASSIVE_LEVEL(예: 초기화 시) 서비스를 호출해야 하는 경우 StreamClassCallAtNewPriority를 LOW 우선 순위로 설정하여 PASSIVE_LEVEL 작업자 스레드를 획득할 수 있습니다. 우선 순위가 낮은 콜백은 아무것도 동기화되지 않으며, 우선 순위가 낮은 콜백을 실행할 때 미니 드라이버는 새 요청(ReadyForNextRequest NotificationType 매개 변수가 보류 중이라고 가정) 또는 ISR 호출을 받을 수 있습니다.

  • 예제 2: ISR이 없는 미니 드라이버

    스트림 클래스 동기화가 켜져 있으면 미니 드라이버의 진입점은 모두 DISPATCH_LEVEL 호출됩니다. 미니 드라이버는 우선 순위를 조정할 필요 없이 최대 1/2~1밀리초 동안 처리할 수 있습니다. 미니드라이버에서 1/2밀리초 이상 걸리는 코드를 실행해야 하거나 PASSIVE_LEVEL(예: 초기화 시) 서비스를 호출해야 하는 경우 LOW 우선 순위를 가진 StreamClassCallAtNewPriority 를 사용하여 PASSIVE_LEVEL 작업자 스레드를 가져올 수 있습니다. 우선 순위가 낮은 콜백은 아무것도 동기화되지 않으며 우선 순위가 낮은 콜백을 실행할 때 미니 드라이버는 새 요청(ReadyForNextRequest NotificationType 매개 변수가 보류 중이라고 가정)을 받을 수 있습니다.

  • Stream 클래스 동기화를 사용하지 않아야 하는 경우

    다음은 스트림 클래스 동기화를 사용하지 않아야 하는 상황의 예입니다. 여기에는 다음이 포함됩니다.

    • 드라이버가 자주(미니 드라이버가 수신하는 요청의 약 20% 이상) 1밀리초 이상 소요되는 처리를 수행해야 하거나 Microsoft DirectDraw 서비스와 같은 PASSIVE_LEVEL 서비스를 자주 호출해야 하는 경우 디버그 버전의 stream.sys 사용하는 경우 스트림 클래스는 이러한 경우를 모두 어설션하고 동기화가 켜진 상태에서 검색되면 중지됩니다.

    • 미니 드라이버가 연결된 하드웨어가 없는 필터인 경우 동기화할 기본 하드웨어가 없고 미니 드라이버가 일반적으로 많은 처리를 수행하기 때문에 이러한 미니 드라이버는 PASSIVE_LEVEL 실행되어야 합니다. 이 경우 스트림 클래스 동기화를 사용하여 오버헤드를 낭비하는 것보다 사용자 고유의 동기화를 수행하는 것이 더 쉽습니다. 필요한 경우 뮤텍스를 사용하여 큐를 보호합니다.

      동기화 코드의 버그를 찾기 어려울 수 있으며, 특정 환경(예: 다중 프로세서 시스템에서 실행되는 NT 기반 운영 체제)에서는 많은 시간 동안의 스트레스 후에만 버그가 표시될 수 있습니다. 공급업체에 대한 경험을 바탕으로 대부분의 공급업체가 디버그할 수 있는 기능이나 욕구가 있는 것은 아닙니다. 완전 비동기 WDM 디바이스 드라이버를 작성하는 데 익숙한 드라이버 작성자만 자체 동기화를 시도해야 합니다.

    • 미니 드라이버가 실제 하드웨어의 동기화에 대해 크게 걱정하지 않고 PASSIVE_LEVEL 다음 계층으로 요청을 호출하고 일반적으로 DISPATCH_LEVEL 콜백을 수신하는 버스 기반 버스 유형 드라이버(예: USB 또는 1394 주변 드라이버)인 경우.