Geant4 Cross Reference |
1 // 1 // 2 // MIT License 2 // MIT License 3 // Copyright (c) 2020 Jonathan R. Madsen 3 // Copyright (c) 2020 Jonathan R. Madsen 4 // Permission is hereby granted, free of charg 4 // Permission is hereby granted, free of charge, to any person obtaining a copy 5 // of this software and associated documentati 5 // of this software and associated documentation files (the "Software"), to deal 6 // in the Software without restriction, includ 6 // in the Software without restriction, including without limitation the rights 7 // to use, copy, modify, merge, publish, distr 7 // to use, copy, modify, merge, publish, distribute, sublicense, and 8 // copies of the Software, and to permit perso 8 // copies of the Software, and to permit persons to whom the Software is 9 // furnished to do so, subject to the followin 9 // furnished to do so, subject to the following conditions: 10 // The above copyright notice and this permiss 10 // The above copyright notice and this permission notice shall be included in 11 // all copies or substantial portions of the S 11 // all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED 12 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPR 12 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT 13 // LIMITED TO THE WARRANTIES OF MERCHANTABILIT 13 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 14 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SH 14 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 15 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 15 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 16 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARIS 16 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 17 // WITH THE SOFTWARE OR THE USE OR OTHER DEALI 17 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 18 // 18 // 19 // ------------------------------------------- 19 // --------------------------------------------------------------- 20 // Tasking class implementation 20 // Tasking class implementation 21 // 21 // 22 // Threading.cc 22 // Threading.cc 23 // 23 // 24 24 25 #include "PTL/Threading.hh" 25 #include "PTL/Threading.hh" 26 << 26 #include "PTL/Types.hh" 27 #include "PTL/ConsumeParameters.hh" << 27 #include "PTL/Utility.hh" 28 #include "PTL/Macros.hh" << 29 28 30 #if defined(PTL_WINDOWS) 29 #if defined(PTL_WINDOWS) 31 # include <windows.h> << 30 # include <Windows.h> 32 #endif 31 #endif 33 32 34 #if defined(PTL_MACOS) 33 #if defined(PTL_MACOS) 35 # include <sys/sysctl.h> 34 # include <sys/sysctl.h> 36 #endif 35 #endif 37 36 38 #if defined(PTL_LINUX) 37 #if defined(PTL_LINUX) 39 # include <fstream> 38 # include <fstream> 40 # include <set> << 41 #endif 39 #endif 42 40 43 #include <cstddef> << 41 using namespace PTL; 44 #include <thread> << 45 42 46 //============================================ 43 //======================================================================================// 47 44 48 namespace 45 namespace 49 { 46 { 50 thread_local int ThreadID = PTL::Threading::MA << 47 thread_local int ThreadID = Threading::MASTER_ID; >> 48 51 } // namespace 49 } // namespace 52 50 53 //============================================ 51 //======================================================================================// 54 52 55 namespace PTL << 56 { << 57 Pid_t 53 Pid_t 58 GetPidId() << 54 Threading::GetPidId() 59 { 55 { 60 // In multithreaded mode return Thread ID 56 // In multithreaded mode return Thread ID 61 return std::this_thread::get_id(); 57 return std::this_thread::get_id(); 62 } 58 } 63 59 64 //============================================ 60 //======================================================================================// 65 61 66 unsigned 62 unsigned 67 GetNumberOfCores() << 63 Threading::GetNumberOfCores() 68 { 64 { 69 return std::thread::hardware_concurrency() 65 return std::thread::hardware_concurrency(); 70 } 66 } 71 67 72 //============================================ 68 //======================================================================================// 73 69 74 unsigned 70 unsigned 75 GetNumberOfPhysicalCpus() << 71 Threading::GetNumberOfPhysicalCpus() 76 { 72 { 77 #if defined(PTL_MACOS) 73 #if defined(PTL_MACOS) 78 int count; 74 int count; 79 size_t count_len = sizeof(count); 75 size_t count_len = sizeof(count); 80 sysctlbyname("hw.physicalcpu", &count, &co 76 sysctlbyname("hw.physicalcpu", &count, &count_len, nullptr, 0); 81 return static_cast<unsigned>(count); 77 return static_cast<unsigned>(count); 82 #elif defined(PTL_LINUX) 78 #elif defined(PTL_LINUX) 83 unsigned core_id_count = 0; 79 unsigned core_id_count = 0; 84 std::ifstream ifs("/proc/cpuinfo"); 80 std::ifstream ifs("/proc/cpuinfo"); 85 if(ifs) 81 if(ifs) 86 { 82 { 87 std::set<std::string> core_ids; 83 std::set<std::string> core_ids; 88 while(true) 84 while(true) 89 { 85 { 90 std::string line = {}; 86 std::string line = {}; 91 getline(ifs, line); 87 getline(ifs, line); 92 if(!ifs.good()) 88 if(!ifs.good()) 93 break; 89 break; 94 if(line.find("core id") != std::st 90 if(line.find("core id") != std::string::npos) 95 { 91 { 96 for(std::string itr : { "core 92 for(std::string itr : { "core id", ":", " ", "\t" }) 97 { 93 { 98 static auto _npos = std::s 94 static auto _npos = std::string::npos; 99 auto _pos = _npos; 95 auto _pos = _npos; 100 while((_pos = line.find(it 96 while((_pos = line.find(itr)) != _npos) 101 line = line.replace(_p 97 line = line.replace(_pos, itr.length(), ""); 102 } 98 } 103 core_ids.insert(std::move(line << 99 core_ids.insert(line); 104 } 100 } 105 } 101 } 106 core_id_count = static_cast<unsigned>( 102 core_id_count = static_cast<unsigned>(core_ids.size()); 107 if(core_id_count > 0) 103 if(core_id_count > 0) 108 return core_id_count; 104 return core_id_count; 109 } 105 } 110 return GetNumberOfCores(); 106 return GetNumberOfCores(); 111 #else 107 #else 112 return GetNumberOfCores(); 108 return GetNumberOfCores(); 113 #endif 109 #endif 114 } 110 } 115 111 116 //============================================ 112 //======================================================================================// 117 113 118 void 114 void 119 SetThreadId(int value) << 115 Threading::SetThreadId(int value) 120 { 116 { 121 ThreadID = value; 117 ThreadID = value; 122 } 118 } 123 119 124 int 120 int 125 GetThreadId() << 121 Threading::GetThreadId() 126 { 122 { 127 return ThreadID; 123 return ThreadID; 128 } 124 } 129 125 130 //============================================ 126 //======================================================================================// 131 127 132 bool 128 bool 133 SetPinAffinity(int _cpu) << 129 Threading::SetPinAffinity(int _cpu) 134 { 130 { 135 #if defined(__linux__) || defined(_AIX) 131 #if defined(__linux__) || defined(_AIX) 136 cpu_set_t _cpu_set{}; 132 cpu_set_t _cpu_set{}; 137 CPU_ZERO(&_cpu_set); 133 CPU_ZERO(&_cpu_set); 138 if(_cpu >= 0) 134 if(_cpu >= 0) 139 CPU_SET(_cpu, &_cpu_set); 135 CPU_SET(_cpu, &_cpu_set); 140 return (pthread_setaffinity_np(pthread_sel 136 return (pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &_cpu_set) == 0); 141 #else // Not available for Mac, WIN,... 137 #else // Not available for Mac, WIN,... 142 ConsumeParameters(_cpu); 138 ConsumeParameters(_cpu); 143 return true; 139 return true; 144 #endif 140 #endif 145 } 141 } 146 142 147 //============================================ 143 //======================================================================================// 148 144 149 bool 145 bool 150 SetThreadPriority(int _prio) << 146 Threading::SetThreadPriority(int _prio) 151 { 147 { 152 #if defined(__linux__) || defined(_AIX) 148 #if defined(__linux__) || defined(_AIX) 153 return (pthread_setschedprio(pthread_self( 149 return (pthread_setschedprio(pthread_self(), _prio) == 0); 154 #else // Not available for Mac, WIN,... 150 #else // Not available for Mac, WIN,... 155 ConsumeParameters(_prio); 151 ConsumeParameters(_prio); 156 return true; 152 return true; 157 #endif 153 #endif 158 } 154 } 159 155 160 //============================================ 156 //======================================================================================// 161 157 162 bool 158 bool 163 SetPinAffinity(int _cpu, NativeThread& _t) << 159 Threading::SetPinAffinity(int _cpu, NativeThread& _t) 164 { 160 { 165 #if defined(__linux__) || defined(_AIX) 161 #if defined(__linux__) || defined(_AIX) 166 cpu_set_t _cpu_set{}; 162 cpu_set_t _cpu_set{}; 167 CPU_ZERO(&_cpu_set); 163 CPU_ZERO(&_cpu_set); 168 CPU_SET(_cpu, &_cpu_set); 164 CPU_SET(_cpu, &_cpu_set); 169 return (pthread_setaffinity_np(static_cast 165 return (pthread_setaffinity_np(static_cast<pthread_t>(_t), sizeof(cpu_set_t), 170 &_cpu_set) 166 &_cpu_set) == 0); 171 #else // Not available for Mac, WIN,... 167 #else // Not available for Mac, WIN,... 172 ConsumeParameters(_cpu, _t); 168 ConsumeParameters(_cpu, _t); 173 return true; 169 return true; 174 #endif 170 #endif 175 } 171 } 176 172 177 //============================================ 173 //======================================================================================// 178 174 179 bool 175 bool 180 SetThreadPriority(int _prio, NativeThread& _t) << 176 Threading::SetThreadPriority(int _prio, NativeThread& _t) 181 { 177 { 182 #if defined(__linux__) || defined(_AIX) 178 #if defined(__linux__) || defined(_AIX) 183 return (pthread_setschedprio(static_cast<p 179 return (pthread_setschedprio(static_cast<pthread_t>(_t), _prio) == 0); 184 #else 180 #else 185 ConsumeParameters(_prio, _t); 181 ConsumeParameters(_prio, _t); 186 return true; 182 return true; 187 #endif 183 #endif 188 } 184 } 189 185 190 //============================================ 186 //======================================================================================// 191 << 192 } // namespace PTL << 193 187