Bagikan melalui


Panduan Menulis Rutinitas DPC

Ingatlah poin-poin berikut saat menulis rutinitas DpcForIsr atau CustomDpc :

  • Rutinitas DpcForIsr atau CustomDpc harus menyinkronkan aksesnya ke perangkat fisik, dan ke informasi status bersama atau sumber daya apa pun yang dikelola driver, dengan rutinitas driver lainnya yang mengakses perangkat atau lokasi memori yang sama.

    Jika rutinitas DpcForIsr atau CustomDpc berbagi perangkat atau status dengan ISR, DpcForIsr harus memanggil KeSynchronizeExecution, menyediakan alamat rutinitas SynchCritSection yang disediakan driver yang memprogram perangkat atau mengakses status bersama. Untuk informasi selengkapnya, lihat Menggunakan Bagian Penting.

    Jika rutinitas DpcForIsr atau CustomDpc berbagi status atau sumber daya, seperti antrean interlock atau objek timer, dengan rutinitas selain ISR, ia harus melindungi status atau sumber daya bersama dengan kunci spin eksekutif yang diinisialisasi driver. Untuk informasi selengkapnya, lihat Kunci Putar.

  • Rutinitas DpcForIsr dan CustomDpc berjalan pada IRQL = DISPATCH_LEVEL, yang membatasi serangkaian rutinitas dukungan yang dapat mereka panggil.

    Misalnya, rutinitas DpcForIsr dan CustomDpc tidak dapat mengakses atau mengalokasikan memori yang dapat dipaginasi, dan mereka tidak dapat menunggu objek dispatcher kernel diatur ke status sinyal. Di sisi lain, mereka dapat memperoleh dan melepaskan kunci spin eksekutif driver dengan KeAcquireSpinLockAtDpcLevel dan KeReleaseSpinLockFromDpcLevel, yang berjalan lebih cepat daripada KeAcquireSpinLock dan KeReleaseSpinLock.

    Meskipun rutinitas DPC tidak dapat melakukan pemblokiran panggilan, DPC dapat mengantre item kerja untuk dijalankan dalam utas pekerja sistem yang berjalan di IRQL sama dengan PASSIVE_LEVEL. Item kerja dapat melakukan pemblokiran panggilan yang menunggu objek dispatcher. Untuk mengantre item kerja, rutinitas DpcForIsr biasanya memanggil rutinitas seperti IoQueueWorkItem, dan rutinitas CustomDpc biasanya memanggil rutinitas ExQueueWorkItem .

  • Rutinitas DpcForIsr dan CustomDpc biasanya bertanggung jawab untuk memulai operasi I/O berikutnya pada perangkat.

    Untuk driver perangkat fisik tingkat terendah yang menggunakan I/O langsung, tanggung jawab ini dapat mencakup penggunaan rutin SynchCritSection untuk memprogram perangkat untuk mentransfer lebih banyak data untuk memenuhi IRP saat ini sebelum driver memanggil IoStartNextPacket.

  • Rutinitas DpcForIsr dan CustomDpc harus berjalan hanya untuk jangka waktu singkat, dan harus mendelegasikan pemrosesan sebanyak mungkin ke utas pekerja.

    Meskipun rutinitas DPC berjalan pada prosesor, semua utas dicegah berjalan pada prosesor yang sama. Rutinitas DPC lain yang diantrekan dan siap dijalankan dapat diblokir agar tidak dijalankan hingga rutinitas DPC saat ini selesai. Untuk menghindari penurunan respons sistem, rutinitas DPC yang khas harus berjalan tidak lebih dari 100 mikrodetik setiap kali dipanggil. Jika tugas memerlukan lebih dari 100 mikro detik dan harus dijalankan pada IRQL yang sama dengan DISPATCH_LEVEL, rutinitas DPC harus berakhir setelah 100 mikro detik dan menjadwalkan satu atau beberapa rutinitas CustomTimerDpc untuk menyelesaikan tugas di lain waktu. Untuk informasi selengkapnya tentang rutinitas CustomTimerDpc , lihat Objek Timer dan DPC.

    Rutinitas DPC hanya boleh melakukan tugas yang harus berjalan pada DISPATCH_LEVEL, lalu mendelegasikan pekerjaan terkait interupsi yang tersisa ke utas yang berjalan di IRQL = PASSIVE_LEVEL. Misalnya, rutinitas DPC dapat mengantre item kerja untuk dijalankan dalam utas pekerja sistem.

    Rutinitas DPC yang memanggil rutinitas KeStallExecutionProcessor untuk menunda eksekusi tidak boleh menentukan penundaan lebih dari 100 mikrodetik.

    Gunakan alat analisis performa di WDK untuk mengevaluasi waktu eksekusi rutinitas DPC. Misalnya yang menggunakan alat Tracelog untuk memantau waktu eksekusi DPC, lihat Contoh 15: Mengukur Waktu DPC/ISR.

  • Jika driver menggunakan DMA dan rutinitas AdapterControl-nya mengembalikan KeepObject atau DeallocateObjectKeepRegisters (dengan demikian mempertahankan saluran pengontrol DMA sistem atau adaptor master bus untuk operasi transfer tambahan), rutinitas DpcForIsr atau CustomDpc bertanggung jawab untuk merilis objek adaptor atau register peta dengan FreeAdapterChannel atau FreeMapRegisters sebelum menyelesaikan IRP saat ini dan mengembalikan kontrol.

  • Jika driver perangkat fisik tingkat terendah menyiapkan objek pengontrol untuk menyinkronkan operasi I/O melalui pengontrol ke perangkat yang terpasang, rutinitas DpcForIsr atau CustomDpc bertanggung jawab untuk merilis objek pengontrol menggunakan IoFreeController sebelum menyelesaikan IRP saat ini dan mengembalikan kontrol.

  • Rutinitas DpcForIsr dan CustomDpc umumnya bertanggung jawab untuk mencatat kesalahan perangkat apa pun yang terjadi selama pemrosesan permintaan tertentu, mencoba kembali permintaan saat ini jika perlu dan memungkinkan, dan untuk mengatur blok status I/O dan memanggil IoCompleteRequest untuk IRP saat ini.

  • Jika dukungan driver dan perangkat tumpang tindih operasi I/O, driver harus mengikuti aturan untuk menangani operasi I/O yang tumpang tindih.

  • Rutinitas DpcForIsr atau CustomDpc dari driver apa pun biasanya menyelesaikan pemrosesan I/O hanya untuk subset kode kontrol I/O publik yang harus didukung driver. Secara khusus, rutinitas DPC menyelesaikan operasi untuk permintaan kontrol perangkat dengan karakteristik berikut:

    • Permintaan yang mengubah status perangkat fisik

    • Permintaan yang memerlukan pengembalian informasi yang secara inheren volatil tentang perangkat fisik