Menyiapkan dan Menggunakan Antrean Yang Saling Diblokir

Driver baru harus menggunakan kerangka kerja antrean IRP batal aman di preferensi metode yang diuraikan di bagian ini.

Driver dengan utas atau driver khusus perangkat yang menggunakan utas pekerja eksekutif, seperti sebagian besar FSD sistem, adalah jenis driver yang paling mungkin untuk mengelola antrean internal run-time IRP mereka sendiri dalam antrean yang saling diblokir. Semua driver PnP, termasuk driver WDM, juga harus mengantre runtime integrasi tertentu secara internal sambil melakukan transisi PnP dan status daya.

Biasanya, driver ini menyiapkan antrean yang saling terhubung dua arah; setiap IRP berisi anggota jenis LIST_ENTRY, yang dapat digunakan driver untuk menautkan IRP dua kali lipat yang saat ini disimpan. Driver tidak dapat mengantre ulang IRP untuk mencoba kembali jika menyiapkan antrean yang ditautkan secara senyap.

Driver harus mengatur antrean yang saling diblokir pada inisialisasi perangkat. Gambar berikut mengilustrasikan antrean yang saling terhubung dua kali lipat, rutinitas dukungan yang harus dipanggil driver untuk mengatur antrean seperti itu, dan satu set rutinitas ExInterlockedXxx yang dapat dipanggil driver untuk memasukkan RUNPS ke dalam dan menghapus RUNPS dari antrean.

diagram yang mengilustrasikan menggunakan antrean yang saling diblokir.

Seperti yang ditunjukkan oleh gambar ini, driver harus menyediakan penyimpanan untuk antrean itu sendiri dan untuk yang berikut ini untuk menyiapkan antrean yang saling terhubung dua kali lipat:

Sebagian besar driver yang menggunakan antrean yang saling ditautkan ganda menyediakan penyimpanan yang diperlukan dalam ekstensi perangkat objek perangkat yang dibuat driver. Antrean dan kunci putar eksekutif dapat berada di ekstensi pengontrol (jika driver menggunakan objek pengontrol) atau di kumpulan yang tidak di-patahkan yang dialokasikan oleh driver.

Saat driver menerima permintaan I/O, driver dapat memasukkan IRP ke dalam antreannya dengan memanggil salah satu rutinitas dukungan berikut jika ListHead berjenis LIST_ENTRY, seperti yang ditunjukkan pada gambar sebelumnya:

ExInterlockedInsertTailList untuk menempatkan IRP di akhir antrean

ExInterlockedInsertHeadList untuk menempatkan IRP di bagian depan antrean. Driver biasanya memanggil rutinitas ini hanya ketika mereka harus mencoba kembali permintaan tertentu.

Driver harus meneruskan pointer ke IRP (ListEntry), serta penunjuk ListHead dan kunci putar eksekutif (Lock) yang sebelumnya diinisialisasi, ke masing-masing rutinitas Daftar ExInterlockedInsertXxx ini. Hanya penunjuk ke ListHead dan Lock yang diperlukan ketika driver menghapus antrean IRP dengan memanggil ExInterlockedRemoveHeadList. Untuk mencegah kebuntuan, pengemudi tidak boleh memegang ExecutiveSpinLock yang diteruskan ke rutinitas Xxx ExInterlocked.

Karena antrean yang saling terhubung dilindungi oleh kunci putaran eksekutif, pengemudi dapat memasukkan RUNPS ke dalam antrean yang dua kali ditautkan dan menghapusnya dengan cara yang aman multiprosesor dari rutinitas driver apa pun yang berjalan pada kurang dari atau sama dengan IRQL = DISPATCH_LEVEL.

Antrean dengan ListHead jenis LIST_ENTRY, seperti yang ditunjukkan pada gambar sebelumnya, adalah daftar dua kali lipat yang ditautkan. Satu dengan ListHead jenis SLIST_HEADER adalah daftar yang ditautkan secara berurutan. Driver menginisialisasi ListHead untuk antrean tertaut yang ditautkan secara berurutan dengan memanggil ExInitializeSListHead.

Driver yang tidak pernah mencoba kembali operasi I/O dapat menggunakan ExInterlockedPushEntrySList dan ExInterlockedPopEntrySList untuk mengelola antrean IRP secara internal dalam antrean yang ditautkan secara berurutan dan saling ditautkan. Setiap driver yang menggunakan jenis antrean yang saling diblokir ini juga harus menyediakan penyimpanan residen untuk ListHead jenis SLIST_HEADER dan untuk ExecutiveSpinLock, seperti yang ditunjukkan pada gambar sebelumnya. Ini harus menginisialisasi kunci putar dan mengatur antreannya sebelum memanggil ExInterlockedPushEntrySList untuk memasukkan entri awal ke dalam antreannya.

Untuk informasi selengkapnya, lihat Mengelola Prioritas Perangkat Keras dan Kunci Spin. Untuk persyaratan IRQL untuk rutinitas dukungan tertentu, lihat halaman referensi rutin.