Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Um item de trabalho é uma tarefa que um driver executa em uma função de retorno de chamada de evento EvtWorkItem. Essas funções são executadas de forma assíncrona, em IRQL = PASSIVE_LEVEL, no contexto de um thread de trabalho do sistema.
Os drivers baseados em estrutura geralmente usam itens de trabalho se uma função EvtInterruptDpc ou EvtDpcFunc, que é executada em IRQL = DISPATCH_LEVEL, deve realizar processamento adicional em IRQL = PASSIVE_LEVEL.
Em outras palavras, um driver poderá usar itens de trabalho se uma função executada em IRQL = DISPATCH_LEVEL deve chamar uma função que só pode ser chamada em IRQL = PASSIVE_LEVEL.
Normalmente, a função de retorno de chamada EvtInterruptDpc ou EvtDpcFunc do driver cria um objeto de item de trabalho e o adiciona à fila de itens de trabalho do sistema. Posteriormente, uma thread de trabalho do sistema remove o objeto da fila e chama a função de retorno de chamada EvtWorkItem do item de trabalho.
Drivers de exemplo que usam itens de trabalho
Drivers de exemplo baseados em estrutura que usam itens de trabalho incluem 1394, AMCC5933, PCIDRV e Toaster.
configurar um item de trabalho
Para configurar um item de trabalho, o driver deve:
Crie o item de trabalho.
O driver chama WdfWorkItemCreate para criar um objeto de item de trabalho e identificar uma função de retorno de chamada EvtWorkItem que processará o item de trabalho.
Armazene informações sobre o item de trabalho.
Normalmente, os drivers usam a memória de contexto do objeto de item de trabalho para armazenar informações sobre a tarefa que a função de retorno de chamada EvtWorkItem deve executar. Quando a função de retorno de chamada EvtWorkItem é chamada, ela pode recuperar as informações acessando essa memória de contexto. Para obter informações sobre como alocar e acessar a memória de contexto, consulte Espaço de contexto de objeto da estrutura.
Adicione o item de trabalho à fila de itens de trabalho do sistema.
Seu driver chama WdfWorkItemEnqueue, que adiciona o item de trabalho do driver à fila de itens de trabalho.
Quando o driver chama WdfWorkItemCreate, ele deve fornecer um identificador para um objeto de dispositivo de estrutura ou um objeto de fila de estrutura. Quando o sistema exclui esse objeto, ele também exclui todos os itens de trabalho existentes associados ao objeto. O objeto de item de trabalho será descartado, e seu retorno de chamada associado de item de trabalho será limpo antes que o retorno de chamada EvtCleanupCallback do objeto pai seja invocado.
Para obter mais informações sobre as regras de limpeza de uma hierarquia de objetos de estrutura, consulte Framework Object Life Cycle.
Usar a função de retorno de chamada de item de trabalho
Depois que o item de trabalho for adicionado à fila de itens de trabalho, ele permanecerá lá até que um thread de trabalho do sistema fique disponível. A thread de trabalho do sistema remove o item de trabalho da fila e, em seguida, chama a função de retorno de chamada EvtWorkItem do driver, passando o objeto de item de trabalho como entrada.
Normalmente, a função de retorno de chamada EvtWorkItem executa as seguintes etapas:
Obtém informações fornecidas pelo driver sobre o item de trabalho acessando a memória de contexto do objeto de item de trabalho.
Executa a tarefa especificada. Se necessário, a função de retorno de chamada pode chamar WdfWorkItemGetParentObject para determinar o objeto pai do item de trabalho.
Chama WdfObjectDelete para excluir o objeto de item de trabalho ou, se o driver colocar o item de trabalho novamente na fila, indica que o manipulador para o item de trabalho agora está disponível para reutilização.
A tarefa executada pela função de retorno de chamada de cada item de trabalho deve ser relativamente curta. O sistema operacional fornece um número limitado de threads de trabalho do sistema, de modo que o driver pode impedir o desempenho do sistema se usar funções de retorno de chamada de item de trabalho para executar tarefas demoradas.
criando e excluindo itens de trabalho
Os drivers podem usar uma das duas técnicas a seguir para criar e excluir itens de trabalho:
Use cada item de trabalho uma vez: crie o item de trabalho quando precisar e exclua-o imediatamente após ele ser usado.
Essa técnica é útil para drivers que exigem uso pouco frequente (menos de uma vez por minuto) de um pequeno número de itens de trabalho.
Por exemplo, a função de retorno de chamada EvtInterruptDpc de um driver pode chamar WdfWorkItemCreate e então WdfWorkItemEnqueue, e a função de retorno de chamada EvtWorkItem do item de trabalho pode chamar WdfObjectDelete.
Se o driver seguir esse cenário e se sua função de retorno de chamada EvtInterruptDpc receber um valor de retorno STATUS_INSUFFICIENT_RESOURCES de WdfWorkItemCreate, o driver deverá ser capaz de adiar o trabalho necessário até que os recursos do sistema (normalmente memória) fiquem disponíveis.
Crie um ou mais itens de trabalho que o driver reinclui na fila conforme necessário.
Essa técnica é útil para drivers que usam itens de trabalho com frequência (mais de uma vez por minuto) ou se a função de retorno de chamada EvtInterruptDpc do driver não pode lidar facilmente com um valor de retorno STATUS_INSUFFICIENT_RESOURCES de WdfWorkItemCreate.
O sistema não aloca uma thread de trabalho para um item de trabalho até que o driver chame WdfWorkItemEnqueue. Portanto, mesmo que os threads de trabalho do sistema sejam um recurso limitado, a criação de itens de trabalho ao inicializar um dispositivo consome uma pequena quantidade de memória, mas não afeta de outra forma o desempenho do sistema.
As etapas a seguir descrevem um cenário possível:
- A função de retorno de chamada EvtDriverDeviceAdd do driver chama WdfWorkItemCreate para obter um identificador de item de trabalho.
- A função de retorno de chamada EvtInterruptDpc do driver cria uma lista de ações que a função de retorno de chamada EvtWorkItem deve executar e, em seguida, chama WdfWorkItemEnqueue utilizando o identificador da etapa 1.
- A função de retorno de chamada EvtWorkItem do driver executa a lista de ações e define um sinalizador para indicar que a função de retorno de chamada foi executada.
Posteriormente, sempre que a função de retorno de chamada EvtInterruptDpc do driver for chamada, ela deverá determinar se a função de retorno de chamada EvtWorkItem foi executada. Se a função de retorno de chamada EvtWorkItem não tiver sido executada, a função de retorno de chamada EvtInterruptDpc não chamará WdfWorkItemEnqueue, pois o item de trabalho ainda está na fila. Nesse caso, a função de retorno de chamada EvtInterruptDpc apenas atualiza a lista de ações para a função de retorno de chamada EvtWorkItem.
Cada item de trabalho está associado a um dispositivo ou uma fila. Quando o dispositivo ou fila associado é removido, a estrutura exclui todos os itens de trabalho associados, portanto, se você estiver usando essa técnica, o driver não precisará chamar WdfObjectDelete.
Talvez alguns drivers precisem chamar WdfWorkItemFlush para esvaziar seus itens de trabalho da fila de itens de trabalho. Para obter um exemplo de uso de WdfWorkItemFlush, consulte a página de referência do método.
Se o driver chamar WdfObjectDelete em um item de trabalho pendente, o resultado dependerá do estado do item de trabalho:
| Estado do item de trabalho | Resultado |
|---|---|
| Criado, mas não enfileirado | O item de trabalho é limpo imediatamente. |
| Enfileirado | Chamada para WdfObjectDelete aguarda até que o item de trabalho conclua a execução e, em seguida, o item de trabalho é limpo. |
| Executando | Se o driver chamar WdfObjectDelete de dentro de EvtWorkItem (no mesmo thread), WdfObjectDelete retornará imediatamente. Depois que evtWorkItem for concluído, o item de trabalho será limpo. Caso contrário, WdfObjectDelete aguarda a conclusão do EvtWorkItem. |