Objek Semaphore

Setiap driver dapat menggunakan objek semaphore untuk menyinkronkan operasi antara utas yang dibuat driver dan rutinitas driver lainnya. Misalnya, utas khusus driver mungkin menempatkan dirinya ke dalam status tunggu ketika tidak ada permintaan I/O yang luar biasa untuk driver, dan rutinitas pengiriman driver mungkin mengatur semaphore ke status Sinyal tepat setelah mereka mengantre IRP.

Rutinitas pengiriman driver tingkat tertinggi, yang dijalankan dalam konteks utas yang meminta operasi I/O, mungkin menggunakan semaphore untuk melindungi sumber daya yang dibagikan di antara rutinitas pengiriman. Rutinitas pengiriman driver tingkat bawah untuk operasi I/O sinkron juga dapat menggunakan semaphore untuk melindungi sumber daya yang dibagikan di antara subset rutinitas pengiriman atau dengan utas yang dibuat driver.

Setiap driver yang menggunakan objek semaphore harus memanggil KeInitializeSemaphore sebelum menunggu atau melepaskan semaphore. Gambar berikut menggambarkan bagaimana driver dengan utas dapat menggunakan objek semaphore.

diagram yang mengilustrasikan menunggu objek semaphore.

Seperti yang ditunjukkan oleh gambar sebelumnya, driver seperti itu harus menyediakan penyimpanan untuk objek semaphore, yang seharusnya menjadi residen. Driver dapat menggunakan ekstensi perangkat dari objek perangkat yang dibuat driver, ekstensi pengontrol jika menggunakan objek pengontrol, atau kumpulan yang tidak dialokasikan oleh driver.

Ketika rutinitas AddDevice driver memanggil KeInitializeSemaphore, itu harus meneruskan pointer ke penyimpanan residen pengemudi untuk objek semaphore. Selain itu, pemanggil harus menentukan Hitungan untuk objek semaphore, seperti yang ditunjukkan pada gambar sebelumnya, yang menentukan status awalnya (bukan nol untuk Sinyal).

Pemanggil juga harus menentukan Batas untuk semaphore, yang dapat berupa salah satu dari berikut ini:

  • Batas = 1

    Ketika semaphore ini diatur ke status Signaled, satu utas yang menunggu semaphore diatur ke status Signaled menjadi memenuhi syarat untuk eksekusi dan dapat mengakses sumber daya apa pun yang dilindungi oleh semaphore.

    Jenis semaphore ini juga disebut semaphore biner karena utas memiliki atau tidak memiliki akses eksklusif ke sumber daya yang dilindungi semaphore.

  • Batas > 1

    Ketika semaphore ini diatur ke status Sinyal, beberapa utas yang menunggu objek semaphore diatur ke status Sinyal menjadi memenuhi syarat untuk eksekusi dan dapat mengakses sumber daya apa pun yang dilindungi oleh semaphore.

    Jenis semaphore ini disebut semaphore penghitungan karena rutinitas yang mengatur semaphore ke status Signaled juga menentukan berapa banyak alur tunggu yang dapat mengubah statusnya dari menunggu menjadi siap. Jumlah utas tunggu tersebut dapat menjadi Batas yang ditetapkan saat semaphore diinisialisasi atau beberapa angka kurang dari Batas prasetel ini.

Beberapa perangkat atau driver perantara memiliki satu utas yang dibuat driver; bahkan lebih sedikit memiliki satu set utas yang mungkin menunggu semaphore diperoleh atau dirilis. Beberapa driver yang disediakan sistem menggunakan objek semaphore, dan, dari yang melakukannya, bahkan lebih sedikit menggunakan semaphore biner. Meskipun semaphore biner mungkin tampak mirip dalam fungsionalitas dengan objek mutex, semaphore biner tidak memberikan perlindungan bawaan terhadap kebuntuan yang dimiliki objek mutex untuk utas sistem yang berjalan di mesin SMP.

Setelah driver dengan semaphore yang diinisialisasi dimuat, driver dapat menyinkronkan operasi pada semaphore yang melindungi sumber daya bersama. Misalnya, driver dengan utas khusus perangkat yang mengelola antrean IRP, seperti driver pengontrol floppy sistem, mungkin menyinkronkan antrean IRP pada semaphore, seperti yang ditunjukkan pada gambar sebelumnya:

  1. Utas memanggil KeWaitForSingleObject dengan penunjuk ke penyimpanan yang disediakan driver untuk objek semaphore yang diinisialisasi untuk menempatkan dirinya ke dalam status tunggu.

  2. RUNPS mulai masuk yang memerlukan operasi I/O perangkat. Rutinitas pengiriman driver memasukkan setiap IRP tersebut ke dalam antrean yang saling terkunci di bawah kontrol spin-lock dan memanggil KeReleaseSemaphore dengan pointer ke objek semaphore, peningkatan prioritas yang ditentukan driver untuk utas (Tahapan, seperti yang ditunjukkan pada gambar sebelumnya), Penyesuaian 1 yang ditambahkan ke Hitungan semaphore saat setiap IRP diantrekan, dan Boolean Wait diatur ke FALSE. Jumlah semaphore nonzero mengatur objek semaphore ke status Sinyal, sehingga mengubah status alur tunggu menjadi siap.

  3. Kernel mengirimkan utas untuk dieksekusi segera setelah prosesor tersedia: yaitu, tidak ada utas lain dengan prioritas yang lebih tinggi saat ini dalam keadaan siap dan tidak ada rutinitas mode kernel untuk dijalankan pada IRQL yang lebih tinggi.

    Utas menghapus IRP dari antrean yang saling mengunci di bawah kontrol spin-lock, meneruskannya ke rutinitas driver lain untuk pemrosesan lebih lanjut, dan memanggil KeWaitForSingleObject lagi. Jika semaphore masih diatur ke status Signaled (yaitu, Count-nya tetap nonzero, menunjukkan bahwa lebih banyak IRP berada dalam antrean yang saling di-interlock driver), kernel kembali mengubah status utas dari menunggu hingga siap.

    Dengan menggunakan semaphore penghitungan dengan cara ini, utas driver seperti itu "tahu" ada IRP yang akan dihapus dari antrean yang saling mengunci setiap kali utas dijalankan.

Untuk info khusus untuk mengelola IRQL saat memanggil KeReleaseSemaphore, lihat bagian Keterangan ke KeReleaseSemaphore.

Setiap rutinitas driver standar yang berjalan pada IRQL yang lebih besar dari PASSIVE_LEVEL tidak dapat menunggu interval nonzero pada objek dispatcher apa pun tanpa menurunkan sistem; lihat Objek Dispatcher Kernel untuk detailnya. Namun, rutinitas seperti itu dapat memanggil KeReleaseSemaphore saat berjalan di IRQL kurang dari atau sama dengan DISPATCH_LEVEL.

Untuk ringkasan IRQL tempat rutinitas driver standar dijalankan, lihat Mengelola Prioritas Perangkat Keras. Untuk persyaratan IRQL dari rutinitas dukungan tertentu, lihat halaman referensi rutinitas.