Bagikan melalui


Pengantar Objek Dispatcher Kernel

Kernel mendefinisikan sekumpulan jenis objek yang disebut objek dispatcher kernel, atau hanya objek dispatcher. Objek dispatcher mencakup objek timer, objek peristiwa, objek semaphore, objek mutex, dan objek utas.

Driver dapat menggunakan objek dispatcher sebagai mekanisme sinkronisasi dalam konteks utas nonarbitrer saat mengeksekusi di IRQL sama dengan PASSIVE_LEVEL.

Status Objek Dispatcher

Setiap jenis objek dispatcher yang ditentukan kernel memiliki status yang diatur ke Sinyal atau diatur ke Tidak Diberi Sinyal.

Sekelompok utas dapat menyinkronkan operasinya jika satu atau beberapa utas memanggil KeWaitForSingleObject, KeWaitForMutexObject, atau KeWaitForMultipleObjects. Fungsi-fungsi ini mengambil penunjuk objek dispatcher sebagai input dan menunggu sampai rutinitas atau utas lain mengatur satu atau beberapa objek dispatcher ke status Sinyal.

Ketika utas memanggil KeWaitForSingleObject untuk menunggu objek dispatcher (atau KeWaitForMutexObject untuk mutex), utas dimasukkan ke dalam status tunggu sampai objek dispatcher diatur ke status Sinyal. Utas dapat memanggil KeWaitForMultipleObjects untuk menunggu salah satu, atau untuk semua, dari sekumpulan objek dispatcher yang akan diatur ke Signaled.

Setiap kali objek dispatcher diatur ke status Sinyal, kernel mengubah status utas apa pun yang menunggu objek tersebut siap. (Timer sinkronisasi dan peristiwa sinkronisasi adalah pengecualian untuk aturan ini; ketika peristiwa sinkronisasi atau timer disinyalkan, hanya satu utas tunggu yang diatur ke status siap. Untuk informasi selengkapnya, lihat Objek Timer dan DPC dan Objek Peristiwa.) Utas dalam status siap akan dijadwalkan untuk berjalan sesuai dengan prioritas utas run-time saat ini dan ketersediaan prosesor saat ini untuk utas apa pun dengan prioritas tersebut.

Kapan Driver Dapat Menunggu Objek Dispatcher?

Secara umum, driver dapat menunggu objek dispatcher diatur hanya jika setidaknya salah satu keadaan berikut ini benar:

  • Driver dijalankan dalam konteks utas nonarbitrer.

    Artinya, Anda dapat mengidentifikasi utas yang akan memasuki status tunggu. Dalam praktiknya, satu-satunya rutinitas driver yang dijalankan dalam konteks utas nonarbitrer adalah rutinitas DriverEntry, AddDevice, Reinitialize, dan Unload dari driver apa pun, ditambah rutinitas pengiriman driver tingkat tertinggi. Semua rutinitas ini dipanggil langsung oleh sistem.

  • Driver melakukan permintaan I/O yang sepenuhnya sinkron.

    Artinya, tidak ada driver yang mengantrekan operasi apa pun saat menangani permintaan I/O, dan tidak ada driver yang kembali sampai driver di bawahnya selesai menangani permintaan.

Selain itu, driver tidak dapat memasuki status tunggu jika dijalankan pada atau di atas IRQL sama dengan DISPATCH_LEVEL.

Berdasarkan batasan ini, Anda harus menggunakan aturan berikut:

  • Rutinitas DriverEntry, AddDevice, Reinitialize, dan Unload dari driver apa pun dapat menunggu objek dispatcher.

  • Rutinitas pengiriman driver tingkat tertinggi dapat menunggu objek dispatcher.

  • Rutinitas pengiriman driver tingkat bawah dapat menunggu objek pengiriman, jika operasi I/O sinkron, seperti membuat, membersihkan, mematikan, dan menutup operasi, beberapa operasi kontrol I/O perangkat, dan beberapa operasi PnP dan daya.

  • Rutinitas pengiriman driver tingkat bawah tidak dapat menunggu objek dispatcher untuk penyelesaian operasi I/O asinkron.

  • Rutinitas driver yang dijalankan pada atau di atas IRQL DISPATCH_LEVEL tidak boleh menunggu objek dispatcher diatur ke status Sinyal.

  • Driver tidak boleh mencoba menunggu objek dispatcher diatur ke status Diberi sinyal untuk penyelesaian operasi transfer ke atau dari perangkat halaman.

  • Rutinitas pengiriman driver yang melayani permintaan baca/tulis umumnya tidak dapat menunggu objek dispatcher diatur ke status Sinyal.

  • Rutinitas pengiriman untuk permintaan kontrol I/O perangkat dapat menunggu objek dispatcher diatur ke status Sinyal hanya jika jenis transfer untuk kode kontrol I/O METHOD_BUFFERED.

  • Driver miniport SCSI tidak boleh menggunakan objek dispatcher kernel. Driver miniport SCSI hanya boleh memanggil Rutinitas Pustaka Port SCSI.

Setiap rutinitas driver standar lainnya dijalankan dalam konteks utas arbitrer: bahwa dari utas apa pun yang terjadi saat rutinitas driver dipanggil untuk memproses operasi antrean atau untuk menangani gangguan perangkat. Selain itu, sebagian besar rutinitas driver standar dijalankan pada IRQL yang dinaikkan, baik di DISPATCH_LEVEL, atau untuk driver perangkat, di DIRQL.

Jika perlu, driver dapat membuat utas khusus perangkat, yang dapat menunggu rutinitas lain driver (kecuali rutinitas ISR atau SynchCritSection ) untuk mengatur objek dispatcher ke status Sinyal dan mengatur ulang ke status Not-Signaled.

Sebagai pedoman umum, jika Anda mengharapkan bahwa driver perangkat baru Anda sering kali perlu mengulur waktu lebih dari 50 mikrodetik saat menunggu perubahan status perangkat selama operasi I/O, pertimbangkan untuk menerapkan driver dengan utas khusus perangkat. Jika driver perangkat juga merupakan driver tingkat tertinggi, pertimbangkan untuk menggunakan utas pekerja sistem dan menerapkan satu atau beberapa rutinitas panggilan balik worker-thread. Lihat PsCreateSystemThread dan Mengelola Antrean Yang Saling Di-interlock dengan Utas Driver-Created.