Utas Pekerja Sistem

Driver yang memerlukan pemrosesan tertunda dapat menggunakan item kerja, yang berisi pointer ke rutinitas panggilan balik driver yang melakukan pemrosesan aktual. Driver mengantre item kerja, dan utas pekerja sistem menghapus item kerja dari antrean dan menjalankan rutinitas panggilan balik driver. Sistem mempertahankan kumpulan utas pekerja sistem ini, yang merupakan utas sistem yang masing-masing memproses satu item kerja pada satu waktu.

Driver mengaitkan rutinitas panggilan balik WorkItem dengan item kerja. Ketika utas pekerja sistem memproses item kerja, alur kerja memanggil rutinitas WorkItem terkait. Di Windows Vista dan versi Windows yang lebih baru, driver dapat mengaitkan rutinitas WorkItemEx dengan item kerja. WorkItemEx mengambil parameter yang berbeda dari parameter yang diambil WorkItem .

Rutinitas WorkItem dan WorkItemEx berjalan dalam konteks utas sistem. Jika rutinitas pengiriman driver dapat berjalan dalam konteks utas mode pengguna, rutinitas tersebut dapat memanggil rutinitas WorkItem atau WorkItemEx untuk melakukan operasi apa pun yang memerlukan konteks utas sistem.

Untuk menggunakan item kerja, driver melakukan langkah-langkah berikut:

  1. Mengalokasikan dan menginisialisasi item kerja baru.

    Sistem menggunakan struktur IO_WORKITEM untuk menahan item kerja. Untuk mengalokasikan struktur IO_WORKITEM baru dan menginisialisasinya sebagai item kerja, driver dapat memanggil IoAllocateWorkItem. Di Windows Vista dan versi Windows yang lebih baru, driver dapat mengalokasikan struktur IO_WORKITEM sendiri, dan memanggil IoInitializeWorkItem untuk menginisialisasi struktur sebagai item kerja. (Driver harus memanggil IoSizeofWorkItem untuk menentukan jumlah byte yang diperlukan untuk menyimpan item kerja.)

  2. Kaitkan rutinitas panggilan balik dengan item kerja, dan antrekan item kerja sehingga akan diproses oleh utas pekerja sistem.

    Untuk mengaitkan rutinitas WorkItem dengan item kerja dan mengantre item kerja, driver harus memanggil IoQueueWorkItem. Untuk mengaitkan rutinitas WorkItemEx dengan item kerja dan mengantre item kerja, driver harus memanggil IoQueueWorkItemEx.

  3. Setelah item kerja tidak lagi diperlukan, bebaskan.

    Item kerja yang dialokasikan oleh IoAllocateWorkItem harus dikosongkan oleh IoFreeWorkItem. Item kerja yang diinisialisasi oleh IoInitializeWorkItem harus tidak diinisialisasi oleh IoUninitializeWorkItem sebelum dapat dikosongkan.

    Item kerja hanya dapat dibatalkan diinisialisasi atau dikosongkan ketika item kerja saat ini tidak diantrekan. Sistem menghapus antrean item kerja sebelum memanggil rutinitas panggilan balik item kerja, sehingga IoFreeWorkItem dan IoUninitializeWorkItem dapat dipanggil dari dalam panggilan balik.

DPC yang perlu memulai tugas pemrosesan yang memerlukan pemrosesan panjang atau yang melakukan panggilan pemblokiran harus mendelegasikan pemrosesan tugas tersebut ke satu atau beberapa item kerja. Saat DPC berjalan, semua utas dicegah untuk berjalan. Selain itu, DPC, yang berjalan di IRQL = DISPATCH_LEVEL, tidak boleh melakukan pemblokiran panggilan. Namun, utas pekerja sistem yang memproses item kerja berjalan di IRQL = PASSIVE_LEVEL. Dengan demikian, item kerja dapat berisi panggilan pemblokiran. Misalnya, utas pekerja sistem dapat menunggu pada objek dispatcher.

Karena kumpulan utas pekerja sistem adalah sumber daya terbatas, rutinitas WorkItem dan WorkItemEx hanya dapat digunakan untuk operasi yang membutuhkan waktu singkat. Jika salah satu rutinitas ini berjalan terlalu lama (jika berisi perulangan yang tidak terbatas, misalnya) atau menunggu terlalu lama, sistem dapat mengalami kebuntuan. Oleh karena itu, jika driver memerlukan pemrosesan tertunda dalam waktu lama, driver harus memanggil PsCreateSystemThread untuk membuat utas sistemnya sendiri.

Jangan panggil IoQueueWorkItem atau IoQueueWorkItemEx untuk mengantre item kerja yang sudah ada dalam antrean. Melakukannya dapat menyebabkan kerusakan struktur data sistem. Jika driver Anda mengantrekan item kerja yang sama setiap kali rutinitas driver tertentu berjalan, Anda dapat menggunakan teknik berikut untuk menghindari antrean item kerja untuk kedua kalinya jika sudah dalam antrean:

  • Pengemudi mempertahankan daftar tugas untuk rutinitas pekerja.
  • Daftar tugas ini tersedia dalam konteks yang disediakan untuk rutinitas pekerja. Rutinitas pekerja dan rutinitas driver apa pun yang mengubah daftar tugas menyinkronkan akses mereka ke daftar.
  • Setiap kali rutinitas pekerja berjalan, ia melakukan semua tugas dalam daftar, dan menghapus setiap tugas dari daftar saat tugas selesai.
  • Ketika tugas baru tiba, driver menambahkan tugas ini ke daftar. Driver mengantre item kerja hanya jika daftar tugas sebelumnya kosong.

Utas pekerja sistem menghapus item kerja dari antrean sebelum memanggil utas pekerja. Dengan demikian, utas driver dapat dengan aman mengantrekan item kerja lagi segera setelah utas pekerja mulai berjalan.