Mutex Cepat dan Mutex Yang Dijaga
Dimulai dengan Windows 2000, driver dapat menggunakan mutex cepat jika memerlukan bentuk pengecualian timbul overhead rendah untuk kode yang berjalan di IRQL <= APC_LEVEL. Mutex cepat dapat melindungi jalur kode yang harus dimasukkan hanya oleh satu utas pada satu waktu. Untuk memasukkan jalur kode yang dilindungi, utas memperoleh mutex. Jika utas lain telah memperoleh mutex, eksekusi utas saat ini ditangguhkan hingga mutex dirilis. Untuk keluar dari jalur kode yang dilindungi, utas merilis mutex.
Dimulai dengan Windows Server 2003, driver juga dapat menggunakan mutex yang dijaga. Mutex yang dijaga adalah pengganti drop-in untuk mutex cepat tetapi memberikan performa yang lebih baik. Seperti mutex cepat, mutex yang dijaga dapat melindungi jalur kode yang harus dimasukkan hanya oleh satu utas pada satu waktu. Namun, kode yang menggunakan mutex yang dijaga berjalan lebih cepat daripada kode yang menggunakan mutex cepat.
Dalam versi Windows sebelum Windows 8, mutex yang dijaga diimplementasikan secara berbeda dari mutex cepat. Jalur kode yang dilindungi oleh mutex cepat berjalan di IRQL = APC_LEVEL. Jalur kode yang dilindungi oleh mutex yang dijaga berjalan di IRQL <= APC_LEVEL tetapi dengan semua APC dinonaktifkan. Dalam versi Windows sebelumnya ini, akuisisi mutex yang dijaga adalah operasi yang lebih cepat daripada akuisisi mutex cepat. Namun, kedua jenis muteks ini bersifat identik dan tunduk pada batasan yang sama. Secara khusus, rutinitas kernel yang ilegal untuk dipanggil di IRQL = APC_LEVEL tidak boleh dipanggil dari jalur kode yang dilindungi oleh mutex cepat atau mutex yang dijaga.
Dimulai dengan Windows 8, mutex yang dijaga diimplementasikan sebagai mutex cepat. Dalam jalur kode yang dilindungi oleh mutex yang dijaga atau mutex cepat, Driver Verifier memperlakukan panggilan ke rutinitas kernel seperti yang terjadi di IRQL = APC_LEVEL. Seperti pada versi Windows sebelumnya, panggilan yang ilegal di APC_LEVEL ilegal dalam jalur kode yang dilindungi oleh muteks yang dijaga atau mutex cepat.
Mutex Cepat
Mutex cepat diwakili oleh struktur FAST_MUTEX . Driver mengalokasikan penyimpanannya sendiri untuk struktur FAST_MUTEX dan kemudian memanggil rutinitas ExInitializeFastMutex untuk menginisialisasi struktur.
Utas memperoleh mutex cepat dengan melakukan salah satu hal berikut:
Memanggil rutinitas ExAcquireFastMutex . Jika mutex telah diperoleh oleh utas lain, eksekusi utas panggilan ditangguhkan hingga muteks tersedia.
Memanggil rutinitas ExTryToAcquireFastMutex untuk mencoba memperoleh mutex cepat tanpa menangguhkan utas saat ini. Rutinitas segera kembali, terlepas dari apakah mutex telah diperoleh. ExTryToAcquireFastMutex mengembalikan TRUE jika berhasil memperoleh mutex untuk pemanggil; jika tidak, ia mengembalikan FALSE.
Utas memanggil ExReleaseFastMutex untuk merilis mutex cepat yang diperoleh oleh ExAcquireFastMutex atau ExTryToAcquireFastMutex.
Jalur kode yang dilindungi oleh mutex cepat berjalan di IRQL = APC_LEVEL. ExAcquireFastMutex dan ExTryToAcquireFastMutex meningkatkan IRQL saat ini ke APC_LEVEL, dan ExReleaseFastMutex memulihkan IRQL asli. Dengan demikian, semua APC dinonaktifkan sementara utas memegang mutex cepat.
Jika jalur kode dijamin selalu berjalan di APC_LEVEL, driver dapat memanggil ExAcquireFastMutexUnsafe dan ExReleaseFastMutexUnsafe untuk memperoleh dan melepaskan mutex cepat. Rutinitas ini tidak mengubah IRQL saat ini dan hanya dapat digunakan dengan aman ketika IRQL saat ini APC_LEVEL.
Mutex cepat tidak dapat diperoleh secara rekursif. Jika utas yang sudah memegang mutex cepat mencoba memperolehnya, utas tersebut akan mengalami kebuntuan. Mutex cepat hanya dapat digunakan dalam kode yang berjalan di IRQL <= APC_LEVEL.
Mutex Yang Dijaga
Mutex yang dijaga, yang tersedia dimulai dengan Windows Server 2003, melakukan fungsi yang sama seperti mutex cepat tetapi dengan performa yang lebih tinggi.
Dimulai dengan Windows 8, mutex yang dijaga dan mutex cepat diimplementasikan secara identik.
Dalam versi Windows sebelum Windows 8, mutex yang dijaga diimplementasikan secara berbeda dari mutex cepat. Memperoleh mutex cepat meningkatkan IRQL saat ini menjadi APC_LEVEL, sementara memperoleh mutex yang dijaga memasuki wilayah yang dijaga, yang merupakan operasi yang lebih cepat. Untuk informasi selengkapnya tentang wilayah yang dijaga, lihat Wilayah Penting dan Wilayah yang Dijaga.
Mutex yang dijaga diwakili oleh struktur KGUARDED_MUTEX . Driver mengalokasikan penyimpanannya sendiri untuk struktur KGUARDED_MUTEX dan kemudian memanggil rutinitas KeInitializeGuardedMutex untuk menginisialisasi struktur.
Utas memperoleh mutex yang dijaga dengan melakukan salah satu hal berikut:
Memanggil KeAcquireGuardedMutex. Jika mutex telah diperoleh oleh utas lain, eksekusi utas panggilan ditangguhkan hingga muteks tersedia.
Memanggil KeTryToAcquireGuardedMutex untuk mencoba memperoleh mutex yang dijaga tanpa menangguhkan utas saat ini. Rutinitas segera kembali, terlepas dari apakah mutex telah diperoleh. KeTryToAcquireGuardedMutex mengembalikan TRUE jika berhasil memperoleh mutex untuk pemanggil; jika tidak, ia mengembalikan FALSE.
Utas memanggil KeReleaseGuardedMutex untuk merilis mutex terjaga yang diperoleh oleh KeAcquireGuardedMutex atau KeTryToAcquireGuardedMutex.
Utas yang menyimpan mutex yang dijaga secara implisit berjalan di dalam wilayah yang dijaga. KeAcquireGuardedMutex dan KeTryToAcquireGuardedMutex memasuki wilayah yang dijaga, sementara KeReleaseGuardedMutex keluar darinya. Semua APC dinonaktifkan saat utas memegang mutex yang dijaga.
Jika jalur kode dijamin berjalan dengan semua APC dinonaktifkan, driver dapat menggunakan KeAcquireGuardedMutexUnsafe dan KeReleaseGuardedMutexUnsafe untuk memperoleh dan melepaskan mutex yang dijaga. Rutinitas ini tidak memasuki atau keluar dari wilayah yang dijaga dan hanya dapat digunakan di dalam wilayah yang sudah ada atau di IRQL = APC_LEVEL.
Mutex yang dijaga tidak dapat diperoleh secara rekursif. Jika utas yang sudah memegang mutex yang dijaga mencoba memperolehnya, utas tersebut akan mengalami kebuntuan. Mutex yang dijaga hanya dapat digunakan dalam kode yang berjalan di IRQL <= APC_LEVEL.