diff options
author | Xiangyang (Mark) Guo <xiangyang.guo@intel.com> | 2017-09-26 17:11:55 -0700 |
---|---|---|
committer | Jan Vorlicek <janvorli@microsoft.com> | 2017-09-27 02:11:55 +0200 |
commit | 73ef3c13c9b710cb04b67a904b098fb196c224c7 (patch) | |
tree | c112694a3b52eea9cfbceace9fbfc0dfda8b6145 /src/pal | |
parent | 44f570e6efc8e908cebaef8d98b36f1b0c6f5c4a (diff) | |
download | coreclr-73ef3c13c9b710cb04b67a904b098fb196c224c7.tar.gz coreclr-73ef3c13c9b710cb04b67a904b098fb196c224c7.tar.bz2 coreclr-73ef3c13c9b710cb04b67a904b098fb196c224c7.zip |
Add SetThreadIdealProcessorEx PAL API (#13606)
* add SetThreadIdealProcessorEx PAL API
* fix lpPreviousIdealProcessor
Diffstat (limited to 'src/pal')
-rw-r--r-- | src/pal/inc/pal.h | 9 | ||||
-rw-r--r-- | src/pal/src/numa/numa.cpp | 112 |
2 files changed, 121 insertions, 0 deletions
diff --git a/src/pal/inc/pal.h b/src/pal/inc/pal.h index 1f611d0922..1a1b6c8625 100644 --- a/src/pal/inc/pal.h +++ b/src/pal/inc/pal.h @@ -4847,6 +4847,15 @@ GetProcessAffinityMask( OUT PDWORD_PTR lpSystemAffinityMask ); +PALIMPORT +BOOL +PALAPI +SetThreadIdealProcessorEx( + IN HANDLE hThread, + IN PPROCESSOR_NUMBER lpIdealProcessor, + OUT PPROCESSOR_NUMBER lpPreviousIdealProcessor +); + // // The types of events that can be logged. // diff --git a/src/pal/src/numa/numa.cpp b/src/pal/src/numa/numa.cpp index 91cf6871c1..383fb0e3b0 100644 --- a/src/pal/src/numa/numa.cpp +++ b/src/pal/src/numa/numa.cpp @@ -867,3 +867,115 @@ VirtualAllocExNuma( return result; } + +/*++ +Function: + SetThreadIdealProcessorEx + +See MSDN doc. +--*/ +BOOL +PALAPI +SetThreadIdealProcessorEx( + IN HANDLE hThread, + IN PPROCESSOR_NUMBER lpIdealProcessor, + OUT PPROCESSOR_NUMBER lpPreviousIdealProcessor) +{ + PERF_ENTRY(SetThreadIdealProcessorEx); + ENTRY("SetThreadIdealProcessorEx(hThread=%p, lpIdealProcessor=%p)\n", hThread, lpIdealProcessor); + + CPalThread *pCurrentThread = InternalGetCurrentThread(); + CPalThread *pTargetThread = NULL; + IPalObject *pTargetThreadObject = NULL; + + PAL_ERROR palErr = + InternalGetThreadDataFromHandle(pCurrentThread, hThread, + 0, // THREAD_SET_CONTEXT + &pTargetThread, &pTargetThreadObject); + + if (NO_ERROR != palErr) + { + ERROR("Unable to obtain thread data for handle %p (error %x)!\n", hThread, + palErr); + return 0; + } + + pthread_t thread = pTargetThread->GetPThreadSelf(); + +#if HAVE_PTHREAD_GETAFFINITY_NP + int cpu = -1; + if ((lpIdealProcessor->Group < g_groupCount) && + (lpIdealProcessor->Number < MaxCpusPerGroup) && + (lpIdealProcessor->Reserved == 0)) + { + cpu = g_groupAndIndexToCpu[lpIdealProcessor->Group * MaxCpusPerGroup + lpIdealProcessor->Number]; + } + + if (cpu == -1) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + if (lpPreviousIdealProcessor != NULL) + { + cpu_set_t prevCpuSet; + CPU_ZERO(&prevCpuSet); + DWORD prevCpu = GetCurrentProcessorNumber(); + + int st = pthread_getaffinity_np(thread, sizeof(cpu_set_t), &prevCpuSet); + + if (st == 0) + { + for (int i = 0; i < g_possibleCpuCount; i++) + { + if (CPU_ISSET(i, &prevCpuSet)) + { + prevCpu = i; + break; + } + } + } + + _ASSERTE(prevCpu < g_possibleCpuCount); + lpPreviousIdealProcessor->Group = g_cpuToAffinity[prevCpu].Group; + lpPreviousIdealProcessor->Number = g_cpuToAffinity[prevCpu].Number; + lpPreviousIdealProcessor->Reserved = 0; + } + + cpu_set_t cpuSet; + CPU_ZERO(&cpuSet); + CPU_SET(cpu, &cpuSet); + + int st = pthread_setaffinity_np(thread, sizeof(cpu_set_t), &cpuSet); + + if (st != 0) + { + switch (st) + { + case EINVAL: + // There is no processor in the mask that is allowed to execute the + // process + SetLastError(ERROR_INVALID_PARAMETER); + break; + case ESRCH: + SetLastError(ERROR_INVALID_HANDLE); + break; + default: + SetLastError(ERROR_GEN_FAILURE); + break; + } + } + + BOOL success = (st == 0); + +#else // HAVE_PTHREAD_GETAFFINITY_NP + // There is no API to manage thread affinity, so let's ignore the request + BOOL success = FALSE; +#endif // HAVE_PTHREAD_GETAFFINITY_NP + + LOGEXIT("SetThreadIdealProcessorEx returns BOOL %d\n", success); + PERF_EXIT(SetThreadIdealProcessorEx); + + return success; +}
\ No newline at end of file |