Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/externals/ptl/src/Threading.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

  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