1 /* 2 Copyright (c) 2005-2020 Intel Corporation 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 #ifndef tbb_tests_harness_concurrency_H 18 #define tbb_tests_harness_concurrency_H 19 20 #if _WIN32||_WIN64 21 #include "tbb/machine/windows_api.h" 22 #elif __linux__ 23 #include <unistd.h> 24 #include <sys/sysinfo.h> 25 #include <string.h> 26 #include <sched.h> 27 #elif __FreeBSD__ 28 #include <unistd.h> 29 #include <errno.h> 30 #include <string.h> 31 #include <sys/param.h> // Required by <sys/cpuset.h> 32 #include <sys/cpuset.h> 33 #endif 34 35 #include <limits.h> 36 37 namespace Harness { 38 static int maxProcs = 0; GetMaxProcs()39 static int GetMaxProcs() { 40 if ( !maxProcs ) { 41 #if _WIN32||_WIN64 42 SYSTEM_INFO si; 43 GetNativeSystemInfo(&si); 44 maxProcs = si.dwNumberOfProcessors; 45 #elif __linux__ 46 maxProcs = get_nprocs(); 47 #else /* __FreeBSD__ */ 48 maxProcs = sysconf(_SC_NPROCESSORS_ONLN); 49 #endif 50 } 51 return maxProcs; 52 } 53 LimitNumberOfThreads(int max_threads)54 int LimitNumberOfThreads(int max_threads) { 55 ASSERT( max_threads >= 1 , "The limited number of threads should be positive." ); 56 maxProcs = GetMaxProcs(); 57 if ( maxProcs < max_threads ) 58 // Suppose that process mask is not set so the number of available threads equals maxProcs 59 return maxProcs; 60 61 #if _WIN32||_WIN64 62 ASSERT( max_threads <= 64 , "LimitNumberOfThreads doesn't support max_threads to be more than 64 on Windows." ); 63 DWORD_PTR mask = 1; 64 for ( int i = 1; i < max_threads; ++i ) 65 mask |= mask << 1; 66 bool err = !SetProcessAffinityMask( GetCurrentProcess(), mask ); 67 #else /* !WIN */ 68 #if __linux__ 69 typedef cpu_set_t mask_t; 70 #if __TBB_MAIN_THREAD_AFFINITY_BROKEN 71 #define setaffinity(mask) sched_setaffinity(0 /*get the mask of the calling thread*/, sizeof(mask_t), &mask) 72 #else 73 #define setaffinity(mask) sched_setaffinity(getpid(), sizeof(mask_t), &mask) 74 #endif 75 #else /* __FreeBSD__ */ 76 typedef cpuset_t mask_t; 77 #if __TBB_MAIN_THREAD_AFFINITY_BROKEN 78 #define setaffinity(mask) cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_TID, -1, sizeof(mask_t), &mask) 79 #else 80 #define setaffinity(mask) cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID, -1, sizeof(mask_t), &mask) 81 #endif 82 #endif /* __FreeBSD__ */ 83 mask_t newMask; 84 CPU_ZERO(&newMask); 85 86 int maskSize = (int)sizeof(mask_t) * CHAR_BIT; 87 ASSERT_WARNING( maskSize >= maxProcs, "The mask size doesn't seem to be big enough to call setaffinity. The call may return an error." ); 88 89 ASSERT( max_threads <= (int)sizeof(mask_t) * CHAR_BIT , "The mask size is not enough to set the requested number of threads." ); 90 for ( int i = 0; i < max_threads; ++i ) 91 CPU_SET( i, &newMask ); 92 int err = setaffinity( newMask ); 93 #endif /* !WIN */ 94 ASSERT( !err, "Setting process affinity failed" ); 95 96 return max_threads; 97 } 98 99 } // namespace Harness 100 101 #endif /* tbb_tests_harness_concurrency_H */ 102