KeSetSystemGroupAffinityThread 関数 (wdm.h)
KeSetSystemGroupAffinityThread ルーチンは、呼び出し元スレッドのグループ番号とアフィニティ マスクを変更します。
構文
void KeSetSystemGroupAffinityThread(
[in] PGROUP_AFFINITY Affinity,
[out, optional] PGROUP_AFFINITY PreviousAffinity
);
パラメーター
[in] Affinity
呼び出し元 スレッドの新 しいグループ番号とグループ相対アフィニティ マスクを指定するGROUP_AFFINITY構造体へのポインター。
[out, optional] PreviousAffinity
呼び出し元によって割り当てられた GROUP_AFFINITY 構造体へのポインター。ルーチンは、呼び出し元スレッドの以前のグループ アフィニティに関する情報を書き込みます。 呼び出し元は、後でこのポインターを KeRevertToUserGroupAffinityThread ルーチンへの入力パラメーターとして使用して、前のスレッド アフィニティを復元できます。 KeSetSystemGroupAffinityThread は、有効なグループ アフィニティではありませんが、KeRevertToUserGroupAffinityThread にとって特別な意味を持つ値をこの構造体に書き込む場合がよくあります。 後続の KeSetSystemGroupAffinityThread 呼び出しでは、これらの特別な値へのポインターを Affinity パラメーターとして指定しないでください。
必要に応じて、呼び出し元は KeSetSystemGroupAffinityThread を複数回呼び出すことによって、スレッド アフィニティを複数回変更できます。 これらの呼び出しの最初の間に、呼び出し元は、元のスレッド アフィニティをキャプチャして後で復元できるように、PreviousAffinity に NULL 以外の値を指定する必要があります。 ただし、 KeSetSystemGroupAffinityThread の後の呼び出しでは、オプションとして PreviousAffinity = NULL を設定できます。 詳細については、「解説」を参照してください。
戻り値
なし
解説
このルーチンは、呼び出し元スレッドのグループ番号とグループ相対アフィニティ マスクを変更します。 Affinity パラメーターは、GROUP_AFFINITY構造体を指します。 この構造体のグループ番号とアフィニティ マスクは、スレッドを実行できるプロセッサのセットを識別します。 成功した場合、ルーチンは、このセット内のプロセッサで実行するようにスレッドをスケジュールします。
PreviousAffinity パラメーターが NULL 以外の場合、ルーチンは、呼び出しの開始時に有効だった前のグループ アフィニティに関する情報を、PreviousAffinity が指すGROUP_AFFINITY構造体に保存します。 前のスレッド アフィニティを復元するために、呼び出し元は KeRevertToUserGroupAffinityThread ルーチンへの入力パラメーターとして、この構造体へのポインターを指定できます。
マルチプロセッサ システムでは、ユーザー モード スレッドのコンテキストで実行されるカーネル モード ドライバー ルーチンで、スレッドのグループ アフィニティを一時的に変更するために KeSetSystemGroupAffinityThread を呼び出す必要がある場合があります。 ルーチンが終了する前に、 KeRevertToUserGroupAffinityThread を呼び出して、スレッドのアフィニティ マスクを元の値に復元する必要があります。
プロセスは、一度に複数のグループに対してアフィニティを持つことができます。 ただし、スレッドは、いつでも 1 つのグループにのみ割り当てることができます。 そのグループは常にスレッドのプロセスのアフィニティ内にあります。 スレッドは、 KeSetSystemGroupAffinityThread を呼び出すことによって、割り当てられているグループを変更できます。
KeSetSystemGroupAffinityThread は、グループ番号とアフィニティ マスクを*Affinity で指定された値に変更します。これは、次の条件に該当する場合に限ります。
- グループ番号は有効です。
- アフィニティ マスクは有効です (つまり、グループ内の論理プロセッサに対応するマスク ビットのみが設定されます)。
- アフィニティ マスクで指定されているプロセッサの少なくとも 1 つがアクティブです。
さらに、以前のグループ アフィニティがユーザー モードでスレッドに割り当てられた場合、 KeSetSystemGroupAffinityThread はグループ番号と *PreviousAffinity のアフィニティ マスクの両方に 0 を書き込みます。 グループ番号とアフィニティ マスクの両方が 0 である GROUP_AFFINITY 構造体に応答して、 KeRevertToUserGroupAffinityThread は現在のユーザー モード スレッド アフィニティを復元します。 KeSetSystemGroupAffinityThread 呼び出しと KeRevertToUserGroupAffinityThread 呼び出しの間でユーザー モード スレッド アフィニティが変更された場合、最新のユーザー モード アフィニティがスレッドに割り当てられます。 (アプリケーションは SetThreadGroupAffinity などの関数を呼び出して、スレッドのユーザー モード グループ アフィニティを変更できます)。
*Affinity の新しいアフィニティ マスクが有効となる前に、 KeSetSystemGroupAffinityThread は、現在アクティブでないプロセッサに対応するアフィニティ マスク ビットを削除 (ゼロに設定) します。 後続の KeSetSystemGroupAffinityThread 呼び出しでは、ルーチンが *PreviousAffinity に書き込む値に、この方法で変更されたアフィニティ マスクが含まれている可能性があります。
関連ルーチン KeSetSystemAffinityThreadEx は呼び出し元スレッドのアフィニティ マスクを変更しますが、このルーチンは KeSetSystemGroupAffinityThread とは異なり、グループ番号を入力パラメーターとして受け入れません。 Windows 7 以降、 KeSetSystemAffinityThreadEx は、アフィニティ マスクがグループ 0 のプロセッサを参照していることを前提としています。これは、グループをサポートしていない以前のバージョンの Windows でのこのルーチンの動作と互換性があります。 この動作により、 KeSetSystemAffinityThreadEx を呼び出し、グループ指向機能を使用しない既存のドライバーが、2 つ以上のグループを持つマルチプロセッサ システムで正しく実行されるようになります。 ただし、Windows 7 以降のバージョンの Windows オペレーティング システムでグループ指向機能を使用するドライバーでは、KeSetSystemAffinityThreadEx ではなく KeSetSystemGroupAffinityThread を呼び出す必要があります。
KeSetSystemGroupAffinityThread および KeRevertToUserGroupAffinityThread では、さまざまな呼び出しパターンがサポートされています。 次の図に、2 つの例を示します。
次の図は、 KeSetSystemGroupAffinityThread を 3 回呼び出してスレッド アフィニティを変更し、 KeRevertToUserGroupAffinityThread を呼び出して元のスレッド アフィニティを復元するドライバー スレッドを表しています。
前の図では、"Set affinity" というラベルの 3 つのボックスは KeSetSystemGroupAffinityThread の呼び出しであり、"Revert affinity" というラベルのボックスは KeRevertToUserGroupAffinityThread の呼び出しです。 最初の KeSetSystemGroupAffinityThread 呼び出しでは、 PreviousAffinity 出力ポインターを使用して元のスレッド アフィニティを保存します。 次の 2 回の KeSetSystemGroupAffinityThread の呼び出し (アスタリスクでマーク) では、呼び出し元は PreviousAffinity を NULL に設定します。 スレッドが終了する前に、 KeRevertToUserGroupAffinityThread を呼び出して、最初の KeSetSystemGroupAffinityThread 呼び出しによって保存されたスレッド アフィニティを復元します。
次の図は、 KeSetSystemGroupAffinityThread 呼び出しと KeRevertToUserGroupAffinityThread 呼び出しのペアが入れ子になっている、やや異なる呼び出しパターンを示しています。 この図では、ドライバー スレッドで KeSetSystemGroupAffinityThread を呼び出すたびに PreviousAffinity 出力パラメーターを使用して前のスレッド アフィニティを保存し、これらの各呼び出しは、保存されたスレッド アフィニティを復元する KeRevertToUserGroupAffinityThread の呼び出しとペアになっています。
前の図では、ドライバー スレッドの関数 A が関数 B を 2 回呼び出しています。 関数 A へのエントリでは、スレッドにユーザー モード アプリケーションによって割り当てられたアフィニティが引き続き存在するとします。 したがって、関数 A の KeSetSystemGroupAffinityThread 呼び出しでは、元のユーザー モードのスレッド アフィニティが保存されます。 関数 B の最初の呼び出し中に、 KeSetSystemGroupAffinityThread は、ドライバーによって割り当てられたスレッド アフィニティを関数 A に保存し、 KeRevertToUserGroupAffinityThread への対応する呼び出しによってこのアフィニティが復元されます。 B が戻った後、A の KeRevertToUserGroupAffinityThread は、元のユーザー モードのスレッド アフィニティを復元します。 B への 2 回目の呼び出しの間に、 KeSetSystemGroupAffinityThread 呼び出しによって元のユーザー モードのスレッド アフィニティが保存され、対応する KeRevertToUserGroupAffinityThread 呼び出しによってこのアフィニティが復元されます。 この例のポイントは、呼び出し元 (関数 A) が B を呼び出す前にスレッド アフィニティをドライバー定義の値に変更したかどうかを関数 B が認識する必要がないということです。
KESetSystemGroupAffinityThread が IRQL <= APC_LEVELで呼び出され、呼び出しが成功した場合、新しいグループ アフィニティはすぐに有効になります。 呼び出しが返されると、呼び出し元のスレッドは、新しいグループ アフィニティで指定されたプロセッサで既に実行されています。 KeSetSystemGroupAffinityThread が IRQL = DISPATCH_LEVELで呼び出され、呼び出しが成功した場合、保留中のプロセッサ変更は、呼び出し元が IRQL を下げるまで延期DISPATCH_LEVEL。
Windows 11 および Windows Server 2022 以降では、プロセッサ数が 64 を超えるシステムでは、プロセスとスレッドのアフィニティは、既定ですべてのプロセッサ グループにわたって、システム内のすべてのプロセッサにまたがっています。 複数のプロセッサ グループに対してスレッドのシステム グループ アフィニティを設定するには、 PsSetSystemMultipleGroupAffinityThread を使用します。
要件
要件 | 値 |
---|---|
サポートされている最小のクライアント | Windows 7 以降で使用できます。 |
対象プラットフォーム | ユニバーサル |
Header | wdm.h (Wdm.h、Wdm.h、Ntifs.h を含む) |
Library | NtosKrnl.lib |
[DLL] | NtosKrnl.exe |
IRQL | <= DISPATCH_LEVEL (「解説」セクションを参照)。 |
DDI コンプライアンス規則 | HwStorPortProhibitedDDIs(storport), PowerIrpDDis(wdm) |