Inconsistency of the request process (not the process)?

On Windows, you can call SetProcessAffinityMask for the process and SetThreadAffinityMask for the thread. However, only Windows discovers GetProcessAffinityMask, and not a similar API for individual process threads.

I have a multi-threaded program that links individual threads to processors at runtime. When I run it, I would like (from the outside) to ask which threads are running on those processors to make sure that it is working correctly. For this, I wrote a small command line utility. But I cannot find a way to find which processor or core (s) are bound to a separate thread.

This, apparently, should be possible; I saw descriptions of the adplus online debugging utility, capable of showing pstack-like output to show thread similarity. And Process Explorer displays the โ€œThemesโ€ tab on multiprocessor machines, which shows the โ€œperfect processorโ€ thread.

Does anyone know how to request this information?

+4
source share
3 answers

You can do this with two calls to SetThreadAffinityMask . This function returns the original bond mask for the processed stream descriptor.

So ... make one call using a mask that establishes proximity to one CPU, and then make a second call to restore the original mask.

Here is the complete C / C ++ source code, including error checking:

 DWORD GetThreadAffinityMask(HANDLE thread) { DWORD mask = 1; DWORD old = 0; // try every CPU one by one until one works or none are left while(mask) { old = SetThreadAffinityMask(thread, mask); if(old) { // this one worked SetThreadAffinityMask(thread, old); // restore original return old; } else { if(GetLastError() != ERROR_INVALID_PARAMETER) return 0; // fatal error, might as well throw an exception } mask <<= 1; } return 0; } 

This code checks one processor at a time until the proximity property is set (in this case, we now know the original mask!) Or until the initial 1 is shifted from DWORD . If a processor that is unavailable is requested, the function does not work with ERROR_INVALID_PARAMETER , and we just try the following. Usually the first processor will work, so it is quite efficient.

If the function fails with anything other than ERROR_INVALID_PARAMETER , this means that we either do not have sufficient access rights to the descriptor, or the system has some real problems because it cannot fulfill our request. Therefore, in this case, it makes no sense to continue.

+6
source

Call NtQueryInformationThread, ThreadBasicInformation :

 typedef struct _THREAD_BASIC_INFORMATION { NTSTATUS ExitStatus; PTEB TebBaseAddress; CLIENT_ID ClientId; ULONG_PTR AffinityMask; KPRIORITY Priority; LONG BasePriority; } THREAD_BASIC_INFORMATION, *PTHREAD_BASIC_INFORMATION; 

AFAIK there is no documented way of obtaining affinity for a stream.

+5
source

a faster way is to call GetCurrentProcessorNumber see msdn , which will return the number of the processor the current thread was working with during the call to this function.

C # code:

 /// <summary> /// Retrieves the number of the processor the current thread was running on <para/> /// during the call to this function. /// </summary> /// <returns>The function returns the current processor number.</returns> [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] internal static extern int GetCurrentProcessorNumber(); 
0
source

All Articles