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