Función KeSetSystemGroupAffinityThread (wdm.h)

La rutina KeSetSystemGroupAffinityThread cambia el número de grupo y la máscara de afinidad del subproceso que realiza la llamada.

Sintaxis

void KeSetSystemGroupAffinityThread(
  [in]            PGROUP_AFFINITY Affinity,
  [out, optional] PGROUP_AFFINITY PreviousAffinity
);

Parámetros

[in] Affinity

Puntero a una estructura de GROUP_AFFINITY que especifica el nuevo número de grupo y la máscara de afinidad relativa al grupo para el subproceso que llama.

[out, optional] PreviousAffinity

Puntero a una estructura de GROUP_AFFINITY asignada por el autor de la llamada en la que la rutina escribe información sobre la afinidad de grupo anterior del subproceso que realiza la llamada. El autor de la llamada puede usar posteriormente este puntero como parámetro de entrada para la rutina KeRevertToUserGroupAffinityThread para restaurar la afinidad de subproceso anterior. Con frecuencia, KeSetSystemGroupAffinityThread escribe valores en esta estructura que no son afinidades de grupo válidas, pero que tienen un significado especial para KeRevertToUserGroupAffinityThread. No proporcione punteros a estos valores especiales como parámetros affinity en llamadas a KeSetSystemGroupAffinityThread posteriores.

Si es necesario, el autor de la llamada puede cambiar la afinidad de subproceso más de una vez llamando a KeSetSystemGroupAffinityThread varias veces. Durante la primera de estas llamadas, el autor de la llamada debe especificar un valor distinto de NULL para PreviousAffinity para que la afinidad de subproceso original se pueda capturar y restaurar posteriormente. Sin embargo, las llamadas posteriores a KeSetSystemGroupAffinityThread pueden, como opción, establecer PreviousAffinity = NULL. Para obtener más información, vea la sección Comentarios.

Valor devuelto

None

Observaciones

Esta rutina cambia el número de grupo y la máscara de afinidad relativa al grupo del subproceso que realiza la llamada. El parámetro Affinity apunta a una estructura GROUP_AFFINITY . El número de grupo y la máscara de afinidad de esta estructura identifican un conjunto de procesadores en los que se puede ejecutar el subproceso. Si se ejecuta correctamente, la rutina programa el subproceso para que se ejecute en un procesador de este conjunto.

Si el parámetro PreviousAffinity no es NULL, la rutina guarda información sobre la afinidad de grupo anterior, que estaba en vigor al principio de la llamada, en la estructura de GROUP_AFFINITY a la que apunta PreviousAffinity . Para restaurar la afinidad de subproceso anterior, el autor de la llamada puede proporcionar el puntero a esta estructura como parámetro de entrada a la rutina KeRevertToUserGroupAffinityThread .

En un sistema multiprocesador, una rutina de controlador en modo kernel que se ejecuta en el contexto de un subproceso en modo de usuario podría necesitar llamar a KeSetSystemGroupAffinityThread para cambiar temporalmente la afinidad de grupo del subproceso. Antes de que se cierre la rutina, debe llamar a KeRevertToUserGroupAffinityThread para restaurar la máscara de afinidad del subproceso a su valor original.

Un proceso puede tener afinidad para más de un grupo a la vez. Sin embargo, un subproceso solo se puede asignar a un grupo en cualquier momento. Ese grupo siempre está en la afinidad del proceso del subproceso. Un subproceso puede cambiar el grupo al que está asignado llamando a KeSetSystemGroupAffinityThread.

KeSetSystemGroupAffinityThread cambia el número de grupo y la máscara de afinidad a los valores especificados en *Affinity solo si se cumple lo siguiente:

  • El número de grupo es válido.
  • La máscara de afinidad es válida (es decir, solo se establecen los bits de máscara que corresponden a procesadores lógicos del grupo).
  • Al menos uno de los procesadores especificados en la máscara de afinidad está activo.
Si no se cumple alguna de estas condiciones, el número de grupo y la máscara de afinidad del subproceso permanecen sin cambios. Si PreviousAffinity no es NULL, la rutina escribe cero en el número de grupo y la máscara de afinidad en **PreviousAffinity*.

Además, KeSetSystemGroupAffinityThread escribe cero en el número de grupo y la máscara de afinidad en *PreviousAffinity si la afinidad de grupo anterior se asignó al subproceso en modo de usuario. En respuesta a una estructura de GROUP_AFFINITY en la que el número de grupo y la máscara de afinidad son cero, KeRevertToUserGroupAffinityThread restaura la afinidad de subproceso del modo de usuario actual. Si la afinidad de subproceso en modo de usuario cambia entre las llamadas KeSetSystemGroupAffinityThread y KeRevertToUserGroupAffinityThread , la afinidad de modo de usuario más reciente se asigna al subproceso. (Una aplicación puede llamar a una función como SetThreadGroupAffinity para cambiar la afinidad de grupo en modo de usuario de un subproceso).

Antes de que la nueva máscara de afinidad en *Affinity surta efecto, KeSetSystemGroupAffinityThread quita (establece en cero) los bits de máscara de afinidad que corresponden a los procesadores que no están activos actualmente. En una llamada a KeSetSystemGroupAffinityThread posterior, el valor que la rutina escribe en *PreviousAffinity podría contener una máscara de afinidad modificada de esta manera.

Una rutina relacionada, KeSetSystemAffinityThreadEx, cambia la máscara de afinidad del subproceso de llamada, pero esta rutina, a diferencia de KeSetSystemGroupAffinityThread, no acepta un número de grupo como parámetro de entrada. A partir de Windows 7, KeSetSystemAffinityThreadEx supone que la máscara de afinidad hace referencia a procesadores del grupo 0, que es compatible con el comportamiento de esta rutina en versiones anteriores de Windows que no admiten grupos. Este comportamiento garantiza que los controladores existentes que llaman a KeSetSystemAffinityThreadEx y que no usen características orientadas a grupos se ejecutarán correctamente en sistemas multiprocesador que tengan dos o más grupos. Sin embargo, los controladores que usan cualquier característica orientada a grupos en Windows 7 y versiones posteriores del sistema operativo Windows deben llamar a KeSetSystemGroupAffinityThread en lugar de KeSetSystemAffinityThreadEx.

KeSetSystemGroupAffinityThread y KeRevertToUserGroupAffinityThread admiten una variedad de patrones de llamada. En los diagramas siguientes se muestran dos ejemplos.

El diagrama siguiente representa un subproceso de controlador que llama a KeSetSystemGroupAffinityThread tres veces para cambiar la afinidad de subproceso y, a continuación, llama a KeRevertToUserGroupAffinityThread para restaurar la afinidad de subproceso original.

Diagrama que ilustra varias llamadas para establecer afinidad.

En el diagrama anterior, los tres cuadros etiquetados como "Establecer afinidad" son llamadas a KeSetSystemGroupAffinityThread y el cuadro con la etiqueta "Revertir afinidad" es una llamada a KeRevertToUserGroupAffinityThread. La primera llamada a KeSetSystemGroupAffinityThread usa el puntero de salida PreviousAffinity para guardar la afinidad de subproceso original. En las dos siguientes llamadas a KeSetSystemGroupAffinityThread (marcados con asteriscos), el autor de la llamada establece PreviousAffinity en NULL. Antes de salir del subproceso, llama a KeRevertToUserGroupAffinityThread para restaurar la afinidad de subproceso guardada por la primera llamada KeSetSystemGroupAffinityThread .

En el diagrama siguiente se muestra un patrón de llamada algo diferente en el que se anidan los pares de KeSetSystemGroupAffinityThread y KeRevertToUserGroupAffinityThread . En este diagrama, cada llamada a KeSetSystemGroupAffinityThread en el subproceso del controlador usa el parámetro de salida PreviousAffinity para guardar la afinidad de subproceso anterior y cada una de estas llamadas se empareja con una llamada a KeRevertToUserGroupAffinityThread que restaura la afinidad de subproceso guardada.

Diagrama que ilustra las llamadas anidadas para establecer y restaurar la afinidad.

En el diagrama anterior, la función A del subproceso del controlador llama a la función B dos veces. Supongamos que, en la entrada a la función A, el subproceso todavía tiene la afinidad asignada por la aplicación en modo de usuario. Por lo tanto, la llamada KeSetSystemGroupAffinityThread en la función A guarda la afinidad de subproceso original en modo de usuario. Durante la primera llamada a la función B, KeSetSystemGroupAffinityThread guarda la afinidad de subproceso asignada por el controlador en la función A y la llamada correspondiente a KeRevertToUserGroupAffinityThread restaura esta afinidad. Después de que B devuelva, KeRevertToUserGroupAffinityThread en A restaura la afinidad de subproceso original en modo de usuario. Durante la segunda llamada a B, la llamada KeSetSystemGroupAffinityThread guarda la afinidad de subproceso original en modo de usuario y la llamada correspondiente a KeRevertToUserGroupAffinityThread restaura esta afinidad. El punto de este ejemplo es que la función B no necesita saber si el autor de la llamada (función A) cambió la afinidad de subproceso a un valor definido por el controlador antes de llamar a B.

Si se llama a KeSetSystemGroupAffinityThread en IRQL <= APC_LEVEL y la llamada se realiza correctamente, la nueva afinidad de grupo surte efecto inmediatamente. Cuando se devuelve la llamada, el subproceso que realiza la llamada ya se está ejecutando en un procesador especificado en la nueva afinidad de grupo. Si se llama a KeSetSystemGroupAffinityThread en IRQL = DISPATCH_LEVEL y la llamada se realiza correctamente, el cambio de procesador pendiente se aplaza hasta que el autor de la llamada reduce el IRQL por debajo de DISPATCH_LEVEL.

A partir de Windows 11 y Windows Server 2022, en un sistema con más de 64 procesadores, las afinidades de procesos y subprocesos abarcan todos los procesadores del sistema, en todos los grupos de procesadores, de forma predeterminada. Para establecer la afinidad de grupo del sistema de un subproceso en varios grupos de procesadores, use PsSetSystemMultipleGroupAffinityThread.

Requisitos

Requisito Value
Cliente mínimo compatible Disponible a partir de Windows 7.
Plataforma de destino Universal
Encabezado wdm.h (include Wdm.h, Wdm.h, Ntifs.h)
Library NtosKrnl.lib
Archivo DLL NtosKrnl.exe
IRQL <= DISPATCH_LEVEL (vea la sección Comentarios).
Reglas de cumplimiento de DDI HwStorPortProhibitedDIs(storport), PowerIrpDDis(wdm)

Consulte también

GROUP_AFFINITY

KeRevertToUserGroupAffinityThread

KeSetSystemAffinityThreadEx

PsSetSystemMultipleGroupAffinityThread