Introducción a los bloqueos de número
Los bloqueos de número son mecanismos de sincronización definidos por el kernel, solo en modo kernel, exportados como un tipo opaco: KSPIN_LOCK. Se puede usar un bloqueo de número para proteger los datos compartidos o los recursos del acceso simultáneo. Cuando se ejecuta en IRQL <= DISPATCH_LEVEL, un controlador puede usar KeAcquireInStackQueuedSpinLock y KeReleaseInStackQueuedSpinLock para adquirir y liberar el bloqueo de número como un bloqueo de número en cola.
Como alternativa, los autores de llamadas que se ejecutan en IRQL >= DISPATCH_LEVEL pueden llamar a KeAcquireSpinLockAtDpcLevel y KeReleaseSpinLockFromDpcLevel para mejorar el rendimiento del controlador.
Muchos componentes usan bloqueos de número, incluidos los controladores. Cualquier tipo de controlador puede usar uno o varios bloqueos de giro ejecutivo. Por ejemplo, la mayoría de los sistemas de archivos usan una cola de trabajo interbloqueada en la extensión de dispositivo del controlador del sistema de archivos (FSD) para almacenar IRP procesadas tanto por las rutinas de devolución de llamada del subproceso de trabajo del sistema de archivos como por el FSD. Una cola de trabajo interbloqueada está protegida por un bloqueo de giro ejecutivo, que resuelve la contención entre el FSD que intenta insertar IRP en la cola y cualquier subproceso que intente quitar IRP simultáneamente. Como otro ejemplo, el controlador del controlador de disquete del sistema usa dos bloqueos de giro ejecutivo. Un bloqueo de giro ejecutivo protege una cola de trabajo interbloqueada compartida con el subproceso dedicado al dispositivo de este controlador; el otro protege un objeto de temporizador compartido por tres rutinas de controlador.
Los bloqueos de giro en cola proporcionan un mejor rendimiento que los bloqueos de giro normales para bloqueos de contención elevados en máquinas multiprocesador. Para obtener más información, consulte Bloqueos de número en cola. Los controladores también pueden usar KeAcquireSpinLock y KeReleaseSpinLock para adquirir y liberar un bloqueo de giro como un bloqueo de giro normal.
Para sincronizar el acceso a estructuras de datos simples, los controladores pueden usar cualquiera de las rutinas ExInterlockedXxx para garantizar el acceso atómico a la estructura de datos. Los controladores que usan estas rutinas no necesitan adquirir ni liberar explícitamente el bloqueo de giro.
Cada controlador que tiene un ISR usa un bloqueo de giro de interrupción para proteger los datos o hardware compartidos entre su ISR y sus rutinas synchCritSection a las que se suele llamar desde sus rutinas StartIo y DpcForIsr. Un bloqueo de número de interrupción está asociado al conjunto de objetos de interrupción creados cuando el controlador llama a Io Conectar Interrupt, como se describe en Registro de un ISR.
Siga estas instrucciones para usar bloqueos de número en los controladores:
Proporcione el almacenamiento de los datos o recursos protegidos por un bloqueo de número y para el bloqueo de número correspondiente en la memoria de espacio del sistema residente (grupo no paginado, como se muestra en la figura Espacios de memoria virtual y memoria física). Un controlador debe proporcionar el almacenamiento para los bloqueos de giro ejecutivo que use. Sin embargo, un controlador de dispositivo no necesita proporcionar el almacenamiento para un bloqueo de giro de interrupción a menos que tenga un ISR multivector o tenga más de un ISR, como se describe en Registro de un ISR.
Llame a KeInitializeSpinLock para inicializar cada bloqueo de giro para el que el controlador proporciona almacenamiento antes de usarlo para sincronizar el acceso a los datos compartidos o al recurso que protege.
Llame a cada rutina de soporte técnico que use un bloqueo de giro en un IRQL adecuado, generalmente en <= DISPATCH_LEVEL para bloqueos de giro ejecutivo o en <= DIRQL para un bloqueo de número de interrupción asociado a los objetos de interrupción del controlador.
Implemente rutinas para que se ejecuten lo antes posible mientras contienen un bloqueo de giro. Ninguna rutina debe contener un bloqueo de giro durante más de 25 microsegundos.
Nunca implemente rutinas que realicen cualquiera de las siguientes acciones al mantener un bloqueo de giro:
Causa excepciones de hardware o genera excepciones de software.
Intente acceder a la memoria paginable.
Realice una llamada recursiva que provocaría un interbloqueo o podría provocar que un bloqueo de número se mantenga durante más de 25 microsegundos.
Intente adquirir otro bloqueo de giro si lo hace podría provocar un interbloqueo.
Llame a una rutina externa que infrinja cualquiera de las reglas anteriores.