Warning, file /include/Geant4/G4Threading.hh was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035 #ifndef G4Threading_hh
0036 #define G4Threading_hh 1
0037
0038 #include "G4Types.hh"
0039 #include "globals.hh"
0040
0041 #include <chrono>
0042 #include <condition_variable>
0043 #include <future>
0044 #include <mutex>
0045 #include <thread>
0046 #include <vector>
0047
0048
0049
0050 #define G4THREADSLEEP(tick) \
0051 std::this_thread::sleep_for(std::chrono::seconds(tick))
0052
0053
0054 template <typename _Tp>
0055 using G4Future = std::future<_Tp>;
0056 template <typename _Tp>
0057 using G4SharedFuture = std::shared_future<_Tp>;
0058 template <typename _Tp>
0059 using G4Promise = std::promise<_Tp>;
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081 using G4Mutex = std::mutex;
0082 using G4RecursiveMutex = std::recursive_mutex;
0083
0084
0085 #define G4MUTEX_INITIALIZER \
0086 {}
0087 #define G4MUTEXINIT(mutex) \
0088 ; \
0089 ;
0090 #define G4MUTEXDESTROY(mutex) \
0091 ; \
0092 ;
0093
0094
0095 namespace G4ThisThread
0096 {
0097 using namespace std::this_thread;
0098 }
0099
0100
0101
0102 template <typename _Tp>
0103 using G4Promise = std::promise<_Tp>;
0104 template <typename _Tp>
0105 using G4Future = std::future<_Tp>;
0106 template <typename _Tp>
0107 using G4SharedFuture = std::shared_future<_Tp>;
0108
0109
0110 using G4ThreadFunReturnType = void*;
0111 using G4ThreadFunArgType = void*;
0112 using thread_lock =
0113 G4int (*)(G4Mutex*);
0114 using thread_unlock =
0115 G4int (*)(G4Mutex*);
0116
0117
0118
0119
0120
0121
0122
0123 template <typename _Tp>
0124 G4Mutex& G4TypeMutex()
0125 {
0126 static G4Mutex _mutex;
0127 return _mutex;
0128 }
0129
0130
0131
0132
0133
0134
0135
0136
0137 template <typename _Tp>
0138 G4RecursiveMutex& G4TypeRecursiveMutex()
0139 {
0140 static G4RecursiveMutex _mutex;
0141 return _mutex;
0142 }
0143
0144 #if defined(G4MULTITHREADED)
0145
0146
0147
0148
0149
0150 using G4Thread = std::thread;
0151 using G4NativeThread = std::thread::native_handle_type;
0152
0153
0154 # define G4MUTEXLOCK(mutex) \
0155 { \
0156 (mutex)->lock(); \
0157 }
0158 # define G4MUTEXUNLOCK(mutex) \
0159 { \
0160 (mutex)->unlock(); \
0161 }
0162
0163
0164 # define G4THREADJOIN(worker) (worker).join()
0165
0166
0167 using G4Pid_t = std::thread::id;
0168
0169
0170
0171 template <typename _Worker, typename _Func, typename... _Args>
0172 void G4THREADCREATE(_Worker*& worker, _Func func, _Args... args)
0173 {
0174 *worker = G4Thread(func, std::forward<_Args>(args)...);
0175 }
0176
0177
0178
0179
0180
0181 using G4Condition = std::condition_variable;
0182 # define G4CONDITION_INITIALIZER \
0183 {}
0184 # define G4CONDITIONWAIT(cond, lock) (cond)->wait(*lock);
0185 # define G4CONDITIONWAITLAMBDA(cond, lock, lambda) (cond)->wait(*lock, lambda);
0186 # define G4CONDITIONNOTIFY(cond) (cond)->notify_one();
0187 # define G4CONDITIONBROADCAST(cond) (cond)->notify_all();
0188
0189
0190
0191
0192
0193 #else
0194
0195
0196
0197
0198
0199 class G4DummyThread
0200 {
0201 public:
0202 using native_handle_type = G4int;
0203 using id = std::thread::id;
0204
0205 public:
0206
0207 G4DummyThread() {}
0208
0209 template <typename _Func, typename... _Args>
0210 G4DummyThread(_Func func, _Args&&... _args)
0211 {
0212 func(std::forward<_Args>(_args)...);
0213 }
0214
0215 public:
0216 native_handle_type native_handle() const { return native_handle_type(); }
0217 G4bool joinable() const { return true; }
0218 id get_id() const noexcept { return std::this_thread::get_id(); }
0219 void swap(G4DummyThread&) {}
0220 void join() {}
0221 void detach() {}
0222
0223 public:
0224 static unsigned int hardware_concurrency() noexcept
0225 {
0226 return std::thread::hardware_concurrency();
0227 }
0228 };
0229
0230
0231 using G4Thread = G4DummyThread;
0232 using G4NativeThread = G4DummyThread::native_handle_type;
0233
0234
0235 # define G4MUTEXLOCK(mutex) \
0236 ; \
0237 ;
0238 # define G4MUTEXUNLOCK(mutex) \
0239 ; \
0240 ;
0241
0242
0243 # define G4THREADJOIN(worker) \
0244 ; \
0245 ;
0246
0247 using G4Pid_t = G4int;
0248
0249
0250
0251 template <typename _Worker, typename _Func, typename... _Args>
0252 void G4THREADCREATE(_Worker*& worker, _Func func, _Args... args)
0253 {
0254 *worker = G4Thread(func, std::forward<_Args>(args)...);
0255 }
0256
0257 using G4Condition = G4int;
0258 # define G4CONDITION_INITIALIZER 1
0259 # define G4CONDITIONWAIT(cond, mutex) G4ConsumeParameters(cond, mutex);
0260 # define G4CONDITIONWAITLAMBDA(cond, mutex, lambda) \
0261 G4ConsumeParameters(cond, mutex, lambda);
0262 # define G4CONDITIONNOTIFY(cond) G4ConsumeParameters(cond);
0263 # define G4CONDITIONBROADCAST(cond) G4ConsumeParameters(cond);
0264
0265 #endif
0266
0267
0268
0269
0270 using G4ThreadId = G4Thread::id;
0271
0272
0273
0274 namespace G4Threading
0275 {
0276 enum
0277 {
0278 SEQUENTIAL_ID = -2,
0279 MASTER_ID = -1,
0280 WORKER_ID = 0,
0281 GENERICTHREAD_ID = -1000
0282 };
0283
0284 G4Pid_t G4GetPidId();
0285 G4int G4GetNumberOfCores();
0286 G4int G4GetThreadId();
0287 G4bool IsWorkerThread();
0288 G4bool IsMasterThread();
0289 void G4SetThreadId(G4int aNewValue);
0290 G4bool G4SetPinAffinity(G4int idx, G4NativeThread& at);
0291 void SetMultithreadedApplication(G4bool value);
0292 G4bool IsMultithreadedApplication();
0293 G4int WorkerThreadLeavesPool();
0294 G4int WorkerThreadJoinsPool();
0295 G4int GetNumberOfRunningWorkerThreads();
0296 }
0297
0298 #endif