VMC Version 2.0
Loading...
Searching...
No Matches
Classes | Macros | Typedefs
TMCAutoLock.h File Reference
#include <chrono>
#include <iostream>
#include <mutex>
#include <system_error>

Go to the source code of this file.

Classes

class  TMCTemplateAutoLock< _Mutex_t >
 

Macros

#define TMCMULTITHREADED   1
 TMCAutoLock.h.
 
#define TMCMUTEX_INITIALIZER    {}
 
#define TMCMUTEXLOCK(mutex)
 
#define TMCMUTEXUNLOCK(mutex)
 
#define _is_stand_mutex(_Tp)   (std::is_same<_Tp, TMCMutex>::value)
 
#define _is_recur_mutex(_Tp)   (std::is_same<_Tp, TMCRecursiveMutex>::value)
 
#define _is_other_mutex(_Tp)   (!_is_stand_mutex(_Tp) && !_is_recur_mutex(_Tp))
 

Typedefs

using TMCMutex = std::mutex
 
using TMCRecursiveMutex = std::recursive_mutex
 
using thread_lock = int(*)(TMCMutex *)
 
using thread_unlock = int(*)(TMCMutex *)
 
using TMCAutoLock = TMCTemplateAutoLock< TMCMutex >
 
using TMCRecursiveAutoLock = TMCTemplateAutoLock< TMCRecursiveMutex >
 
template<typename _Tp >
using TMCTAutoLock = TMCTemplateAutoLock< _Tp >
 

Macro Definition Documentation

◆ TMCMULTITHREADED

#define TMCMULTITHREADED   1

TMCAutoLock.h.

Definition of the TMCTemplateAutoLock and TMCImpMutexAutoLock classes

Author
I. Hrivnacova; IPN Orsay ============================================================================//

void print_threading() { #ifdef TMCMULTITHREADED std::cout << "\nUsing TMCMULTITHREADED version..." << std::endl; #else std::cout << "\nUsing G4SERIAL version..." << std::endl; #endif }

============================================================================//

typedef std::unique_lock<std::mutex> unique_lock_t; functions for casting G4AutoLock to std::unique_lock to demonstrate that G4AutoLock is NOT polymorphic void as_unique_lock(unique_lock_t* lock) { lock->lock(); } void as_unique_unlock(unique_lock_t* lock) { lock->unlock(); }

============================================================================//

void run(const uint64_t& n) { sync the threads a bit std::this_thread::sleep_for(std::chrono::milliseconds(10));

get two mutexes to avoid deadlock when l32 actually locks G4AutoLock l32(G4TypeMutex<int32_t>(), std::defer_lock); G4AutoLock l64(G4TypeMutex<int64_t>(), std::defer_lock);

when serial: will not execute std::unique_lock::lock() because it overrides the member function l32.lock(); regardless of serial or MT: will execute std::unique_lock::lock() because std::unique_lock::lock() is not virtual as_unique_lock(&l64);

std::cout << "Running iteration " << n << "..." << std::endl; }

============================================================================// execute some work template <typename thread_type = std::thread>> void exec(uint64_t n) { get two mutexes to avoid deadlock when l32 actually locks G4AutoLock l32(G4TypeMutex<int32_t>(), std::defer_lock); G4AutoLock l64(G4TypeMutex<int64_t>(), std::defer_lock);

std::vector<thread_type*> threads(n, nullptr); for(uint64_t i = 0; i < n; ++i) { threads[i] = new thread_type(); (threads[i]) = std::move(thread_type(run, i)); }

when serial: will not execute std::unique_lock::lock() because it overrides the member function l32.lock(); regardless of serial or MT: will execute std::unique_lock::lock() because std::unique_lock::lock() is not virtual as_unique_lock(&l64);

std::cout << "Joining..." << std::endl;

when serial: will not execute std::unique_lock::unlock() because it overrides the member function l32.unlock(); regardless of serial or MT: will execute std::unique_lock::unlock() because std::unique_lock::unlock() is not virtual as_unique_unlock(&l64);

NOTE ABOUT UNLOCKS: in MT, commenting out either l32.unlock(); or as_unique_unlock(&l64); creates a deadlock; in serial, commenting out as_unique_unlock(&l64); creates a deadlock but commenting out l32.unlock(); does not

clean up and join for(uint64_t i = 0; i < n; ++i) { threads[i]->join(); delete threads[i]; } threads.clear(); }

============================================================================//

int main() { print_threading();

uint64_t n = 30; std::cout << "\nRunning with real threads...\n" << std::endl; exec<std::thread>(n); std::cout << "\nRunning with fake threads...\n" << std::endl; exec<G4DummyThread>(n);

}

Definition at line 298 of file TMCAutoLock.h.

◆ TMCMUTEX_INITIALIZER

#define TMCMUTEX_INITIALIZER    {}

Definition at line 319 of file TMCAutoLock.h.

◆ TMCMUTEXLOCK

#define TMCMUTEXLOCK (   mutex)
Value:
{ \
(mutex)->lock(); \
}

Definition at line 324 of file TMCAutoLock.h.

◆ TMCMUTEXUNLOCK

#define TMCMUTEXUNLOCK (   mutex)
Value:
{ \
(mutex)->unlock(); \
}

Definition at line 328 of file TMCAutoLock.h.

◆ _is_stand_mutex

#define _is_stand_mutex (   _Tp)    (std::is_same<_Tp, TMCMutex>::value)

Definition at line 510 of file TMCAutoLock.h.

◆ _is_recur_mutex

#define _is_recur_mutex (   _Tp)    (std::is_same<_Tp, TMCRecursiveMutex>::value)

Definition at line 511 of file TMCAutoLock.h.

◆ _is_other_mutex

#define _is_other_mutex (   _Tp)    (!_is_stand_mutex(_Tp) && !_is_recur_mutex(_Tp))

Definition at line 512 of file TMCAutoLock.h.

Typedef Documentation

◆ TMCMutex

using TMCMutex = std::mutex

Definition at line 310 of file TMCAutoLock.h.

◆ TMCRecursiveMutex

using TMCRecursiveMutex = std::recursive_mutex

Definition at line 311 of file TMCAutoLock.h.

◆ thread_lock

using thread_lock = int (*)(TMCMutex*)

Definition at line 312 of file TMCAutoLock.h.

◆ thread_unlock

using thread_unlock = int (*)(TMCMutex*)

Definition at line 314 of file TMCAutoLock.h.

◆ TMCAutoLock

Definition at line 650 of file TMCAutoLock.h.

◆ TMCRecursiveAutoLock

Definition at line 651 of file TMCAutoLock.h.

◆ TMCTAutoLock

template<typename _Tp >
using TMCTAutoLock = TMCTemplateAutoLock<_Tp>

Definition at line 656 of file TMCAutoLock.h.