Import Geant4 10.5.0.beta source tree

This commit is contained in:
Gabriele Cosmo
2018-06-29 10:58:11 +02:00
parent fe81a77428
commit 6aa23be517
1581 changed files with 124288 additions and 83758 deletions
+1 -1
View File
@@ -1,4 +1,4 @@
# $Id: GNUmakefile 108486 2018-02-15 14:47:25Z gcosmo $
# $Id: GNUmakefile 108071 2017-12-19 15:30:19Z gcosmo $
# --------------------------------------------------------------
# GNUmakefile for global management. Gabriele Cosmo, 26/9/96.
# --------------------------------------------------------------
+495 -48
View File
@@ -36,82 +36,529 @@
//
// #include "G4Threading.hh"
// #include "G4AutoLock.hh"
// /* somehwere */
// G4Mutex aMutex = G4MUTEX_INITIALIZER;
// /*
// somewhere else:
// The G4AutoLock instance will automatically unlock the mutex when it
// goes out of scope, lock and unlock method are anyway available for
// explicit handling of mutex lock. */
// G4AutoLock l(&aMutex);
// ProtectedCode();
// l.unlock(); //explicit unlock
// UnprotectedCode();
// l.lock(); //explicit lock
//
// Note that G4AutoLock is defined also for a sequential Geant4 build,
// but has no effect.
// // defined somewhere -- static so all threads see the same mutex
// static G4Mutex aMutex;
//
// // somewhere else:
// // The G4AutoLock instance will automatically unlock the mutex when it
// // goes out of scope. One typically defines the scope within { } if
// // there is thread-safe code following the auto-lock
//
// {
// G4AutoLock l(&aMutex);
// ProtectedCode();
// }
//
// UnprotectedCode();
//
// // When ProtectedCode() is calling a function that also tries to lock
// // a normal G4AutoLock + G4Mutex will "deadlock". In other words, the
// // the mutex in the ProtectedCode() function will wait forever to
// // acquire the lock that is being held by the function that called
// // ProtectedCode(). In this situation, use a G4RecursiveAutoLock +
// // G4RecursiveMutex, e.g.
//
// // defined somewhere -- static so all threads see the same mutex
// static G4RecursiveMutex aRecursiveMutex;
//
// // this function is sometimes called directly and sometimes called
// // from SomeFunction_B(), which also locks the mutex
// void SomeFunction_A()
// {
// // when called from SomeFunction_B(), a G4Mutex + G4AutoLock will
// // deadlock
// G4RecursiveAutoLock l(&aRecursiveMutex);
// // do something
// }
//
// void SomeFunction_B()
// {
//
// {
// G4RecursiveAutoLock l(&aRecursiveMutex);
// SomeFunction_A();
// }
//
// UnprotectedCode();
// }
//
//
// ---------------------------------------------------------------
// Author: Andrea Dotti (15 Feb 2013): First Implementation
//
// Update: Jonathan Madsen (9 Feb 2018): Replaced custom implementation
// with inheritance from C++11 unique_lock, which inherits the
// following member functions:
//
// - unique_lock(unique_lock&& other) noexcept;
// - explicit unique_lock(mutex_type& m);
// - unique_lock(mutex_type& m, std::defer_lock_t t) noexcept;
// - unique_lock(mutex_type& m, std::try_to_lock_t t);
// - unique_lock(mutex_type& m, std::adopt_lock_t t);
//
// - template <typename Rep, typename Period>
// unique_lock(mutex_type& m,
// const std::chrono::duration<Rep,Period>& timeout_duration);
//
// - template<typename Clock, typename Duration>
// unique_lock(mutex_type& m,
// const std::chrono::time_point<Clock,Duration>& timeout_time);
//
// - void lock();
// - void unlock();
// - bool try_lock();
//
// - template <typename Rep, typename Period>
// bool try_lock_for(const std::chrono::duration<Rep,Period>&);
//
// - template <typename Rep, typename Period>
// bool try_lock_until(const std::chrono::time_point<Clock,Duration>&);
//
// - void swap(unique_lock& other) noexcept;
// - mutex_type* release() noexcept;
// - mutex_type* mutex() const noexcept;
// - bool owns_lock() const noexcept;
// - explicit operator bool() const noexcept;
// - unique_lock& operator=(unique_lock&& other);
//
// ---------------------------------------------------------------
//
// Note that G4AutoLock is defined also for a sequential Geant4 build but below
// regarding implementation (also found in G4Threading.hh)
//
//
// NOTE ON GEANT4 SERIAL BUILDS AND MUTEX/UNIQUE_LOCK
// ==================================================
//
// G4Mutex and G4RecursiveMutex are always C++11 std::mutex types
// however, in serial mode, using G4MUTEXLOCK and G4MUTEXUNLOCK on these
// types has no effect -- i.e. the mutexes are not actually locked or unlocked
//
// Additionally, when a G4Mutex or G4RecursiveMutex is used with G4AutoLock
// and G4RecursiveAutoLock, respectively, these classes also suppressing
// the locking and unlocking of the mutex. Regardless of the build type,
// G4AutoLock and G4RecursiveAutoLock inherit from std::unique_lock<std::mutex>
// and std::unique_lock<std::recursive_mutex>, respectively. This means
// that in situations (such as is needed by the analysis category), the
// G4AutoLock and G4RecursiveAutoLock can be passed to functions requesting
// a std::unique_lock. Within these functions, since std::unique_lock
// member functions are not virtual, they will not retain the dummy locking
// and unlocking behavior
// --> An example of this behavior can be found below
//
// Jonathan R. Madsen (February 21, 2018)
//
/**
//============================================================================//
void print_threading()
{
#ifdef G4MULTITHREADED
std::cout << "\nUsing G4MULTITHREADED 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);
}
**/
#ifndef G4AUTOLOCK_HH
#define G4AUTOLOCK_HH
#include "G4Threading.hh"
#include <mutex>
#include <chrono>
#include <system_error>
#include <iostream>
// Note: Note that G4TemplateAutoLock by itself is not thread-safe and
// cannot be shared among threads due to the locked switch
//
template<class M, typename L, typename U>
class G4TemplateAutoLock
template <typename _Mutex_t>
class G4TemplateAutoLock : public std::unique_lock<_Mutex_t>
{
public:
public:
//------------------------------------------------------------------------//
// Some useful typedefs
//------------------------------------------------------------------------//
typedef std::unique_lock<_Mutex_t> unique_lock_t;
typedef G4TemplateAutoLock<_Mutex_t> this_type;
typedef typename unique_lock_t::mutex_type mutex_type;
G4TemplateAutoLock(M* mtx, L l, U u) : locked(false), _m(mtx), _l(l), _u(u)
public:
//------------------------------------------------------------------------//
// STL-consistent reference form constructors
//------------------------------------------------------------------------//
// reference form is consistent with STL lock_guard types
// Locks the associated mutex by calling m.lock(). The behavior is
// undefined if the current thread already owns the mutex except when
// the mutex is recursive
G4TemplateAutoLock(mutex_type& _mutex)
: unique_lock_t(_mutex, std::defer_lock)
{
lock();
// call termination-safe locking. if serial, this call has no effect
_lock_deferred();
}
virtual ~G4TemplateAutoLock()
// Tries to lock the associated mutex by calling
// m.try_lock_for(_timeout_duration). Blocks until specified
// _timeout_duration has elapsed or the lock is acquired, whichever comes
// first. May block for longer than _timeout_duration.
template <typename Rep, typename Period>
G4TemplateAutoLock(mutex_type& _mutex,
const std::chrono::duration<Rep, Period>&
_timeout_duration)
: unique_lock_t(_mutex, std::defer_lock)
{
unlock();
// call termination-safe locking. if serial, this call has no effect
_lock_deferred(_timeout_duration);
}
inline void unlock() {
if ( !locked ) return;
_u(_m);
locked = false;
// Tries to lock the associated mutex by calling
// m.try_lock_until(_timeout_time). Blocks until specified _timeout_time has
// been reached or the lock is acquired, whichever comes first. May block
// for longer than until _timeout_time has been reached.
template<typename Clock, typename Duration>
G4TemplateAutoLock(mutex_type& _mutex,
const std::chrono::time_point<Clock, Duration>&
_timeout_time)
: unique_lock_t(_mutex, std::defer_lock)
{
// call termination-safe locking. if serial, this call has no effect
_lock_deferred(_timeout_time);
}
inline void lock() {
if ( locked ) return;
_l(_m);
locked = true;
// Does not lock the associated mutex.
G4TemplateAutoLock(mutex_type& _mutex, std::defer_lock_t _lock) noexcept
: unique_lock_t(_mutex, _lock)
{ }
#ifdef G4MULTITHREADED
// Tries to lock the associated mutex without blocking by calling
// m.try_lock(). The behavior is undefined if the current thread already
// owns the mutex except when the mutex is recursive.
G4TemplateAutoLock(mutex_type& _mutex, std::try_to_lock_t _lock)
: unique_lock_t(_mutex, _lock)
{ }
// Assumes the calling thread already owns m
G4TemplateAutoLock(mutex_type& _mutex, std::adopt_lock_t _lock)
: unique_lock_t(_mutex, _lock)
{ }
#else
// serial dummy version (initializes unique_lock but does not lock)
G4TemplateAutoLock(mutex_type& _mutex, std::try_to_lock_t)
: unique_lock_t(_mutex, std::defer_lock)
{ }
// serial dummy version (initializes unique_lock but does not lock)
G4TemplateAutoLock(mutex_type& _mutex, std::adopt_lock_t)
: unique_lock_t(_mutex, std::defer_lock)
{ }
#endif // defined(G4MULTITHREADED)
public:
//------------------------------------------------------------------------//
// Backwards compatibility versions (constructor with pointer to mutex)
//------------------------------------------------------------------------//
G4TemplateAutoLock(mutex_type* _mutex)
: unique_lock_t(*_mutex, std::defer_lock)
{
// call termination-safe locking. if serial, this call has no effect
_lock_deferred();
}
private:
G4TemplateAutoLock(mutex_type* _mutex, std::defer_lock_t _lock) noexcept
: unique_lock_t(*_mutex, _lock)
{ }
// Disable copy and assignement operators
//
G4TemplateAutoLock( const G4TemplateAutoLock& rhs );
G4TemplateAutoLock& operator= ( const G4TemplateAutoLock& rhs );
#if defined(G4MULTITHREADED)
G4TemplateAutoLock(mutex_type* _mutex, std::try_to_lock_t _lock)
: unique_lock_t(*_mutex, _lock)
{ }
G4TemplateAutoLock(mutex_type* _mutex, std::adopt_lock_t _lock)
: unique_lock_t(*_mutex, _lock)
{ }
#else // NOT defined(G4MULTITHREADED) -- i.e. serial
G4TemplateAutoLock(mutex_type* _mutex, std::try_to_lock_t)
: unique_lock_t(*_mutex, std::defer_lock)
{ }
G4TemplateAutoLock(mutex_type* _mutex, std::adopt_lock_t)
: unique_lock_t(*_mutex, std::defer_lock)
{ }
#endif // defined(G4MULTITHREADED)
public:
//------------------------------------------------------------------------//
// Non-constructor overloads
//------------------------------------------------------------------------//
#if defined(G4MULTITHREADED)
// overload nothing
#else // NOT defined(G4MULTITHREADED) -- i.e. serial
// override unique lock member functions to keep from locking/unlocking
// but does not override in polymorphic usage
void lock() { }
void unlock() { }
bool try_lock() { return true; }
template <typename Rep, typename Period>
bool try_lock_for(const std::chrono::duration<Rep, Period>&)
{ return true; }
template <typename Clock, typename Duration>
bool try_lock_until(const std::chrono::time_point<Clock, Duration>&)
{ return true; }
void swap(this_type& other) noexcept { std::swap(*this, other); }
bool owns_lock() const noexcept { return false; }
// no need to overload
//explicit operator bool() const noexcept;
//this_type& operator=(this_type&& other);
//mutex_type* release() noexcept;
//mutex_type* mutex() const noexcept;
#endif // defined(G4MULTITHREADED)
private:
// helpful macros
#define _is_stand_mutex(_Tp) (std::is_same<_Tp, G4Mutex>::value)
#define _is_recur_mutex(_Tp) (std::is_same<_Tp, G4RecursiveMutex>::value)
#define _is_other_mutex(_Tp) (! _is_stand_mutex(_Tp) && ! _is_recur_mutex(_Tp) )
template <typename _Tp = _Mutex_t,
typename std::enable_if<_is_stand_mutex(_Tp), int>::type = 0>
std::string GetTypeString() { return "G4AutoLock<G4Mutex>"; }
template <typename _Tp = _Mutex_t,
typename std::enable_if<_is_recur_mutex(_Tp), int>::type = 0>
std::string GetTypeString() { return "G4AutoLock<G4RecursiveMutex>"; }
template <typename _Tp = _Mutex_t,
typename std::enable_if<_is_other_mutex(_Tp), int>::type = 0>
std::string GetTypeString() { return "G4AutoLock<UNKNOWN_MUTEX>"; }
// pollution is bad
#undef _is_stand_mutex
#undef _is_recur_mutex
#undef _is_other_mutex
// used in _lock_deferred chrono variants to avoid ununsed-variable warning
template <typename _Tp>
void suppress_unused_variable(const _Tp&) { }
//========================================================================//
// NOTE on _lock_deferred(...) variants:
// a system_error in lock means that the mutex is unavailable
// we want to throw the error that comes from locking an unavailable
// mutex so that we know there is a memory leak
// if the mutex is valid, this will hold until the other thread
// finishes
// sometimes certain destructors use locks, this isn't an issue unless
// the object is leaked. When this occurs, the application finalization
// (i.e. the real or implied "return 0" part of main) will call destructors
// on Geant4 object after some static mutex variables are deleted, leading
// to the error code (typically on Clang compilers):
// libc++abi.dylib: terminating with uncaught exception of type
// std::__1::system_error: mutex lock failed: Invalid argument
// this function protects against this failure until such a time that
// these issues have been resolved
//========================================================================//
// standard locking
inline void _lock_deferred()
{
#if defined(G4MULTITHREADED)
try { this->unique_lock_t::lock(); }
catch (std::system_error& e) { PrintLockErrorMessage(e); }
#endif
}
//========================================================================//
// Tries to lock the associated mutex by calling
// m.try_lock_for(_timeout_duration). Blocks until specified
// _timeout_duration has elapsed or the lock is acquired, whichever comes
// first. May block for longer than _timeout_duration.
template <typename Rep, typename Period>
void _lock_deferred(const std::chrono::duration<Rep, Period>&
_timeout_duration)
{
#if defined(G4MULTITHREADED)
try { this->unique_lock_t::try_lock_for(_timeout_duration); }
catch (std::system_error& e) { PrintLockErrorMessage(e); }
#else
suppress_unused_variable(_timeout_duration);
#endif
}
//========================================================================//
// Tries to lock the associated mutex by calling
// m.try_lock_until(_timeout_time). Blocks until specified _timeout_time has
// been reached or the lock is acquired, whichever comes first. May block
// for longer than until _timeout_time has been reached.
template<typename Clock, typename Duration>
void _lock_deferred(const std::chrono::time_point<Clock, Duration>&
_timeout_time)
{
#if defined(G4MULTITHREADED)
try { this->unique_lock_t::try_lock_until(_timeout_time); }
catch (std::system_error& e) { PrintLockErrorMessage(e); }
#else
suppress_unused_variable(_timeout_time);
#endif
}
//========================================================================//
// the message for what mutex lock fails due to deleted static mutex
// at termination
void PrintLockErrorMessage(std::system_error& e)
{
// use std::cout/std::endl to avoid include dependencies
using std::cout;
using std::endl;
// the error that comes from locking an unavailable mutex
#if defined(G4VERBOSE)
cout << "Non-critical error: mutex lock failure in "
<< GetTypeString<mutex_type>() << ". "
<< "If the app is terminating, Geant4 failed to "
<< "delete an allocated resource and a Geant4 destructor is "
<< "being called after the statics were destroyed. \n\t--> "
<< "Exception: [code: " << e.code() << "] caught: "
<< e.what() << endl;
#else
suppress_unused_variable(e);
#endif
}
private:
G4bool locked;
M* _m;
L _l;
U _u;
};
struct G4ImpMutexAutoLock
: public G4TemplateAutoLock<G4Mutex,thread_lock,thread_unlock>
{
G4ImpMutexAutoLock(G4Mutex* mtx)
: G4TemplateAutoLock<G4Mutex, thread_lock, thread_unlock>
(mtx, &G4MUTEXLOCK, &G4MUTEXUNLOCK) {}
};
typedef G4ImpMutexAutoLock G4AutoLock;
// -------------------------------------------------------------------------- //
//
// Use the non-template types below:
// - G4AutoLock with G4Mutex
// - G4RecursiveAutoLock with G4RecursiveMutex
//
// -------------------------------------------------------------------------- //
typedef G4TemplateAutoLock<G4Mutex> G4AutoLock;
typedef G4TemplateAutoLock<G4RecursiveMutex> G4RecursiveAutoLock;
// provide abbriviated type if another mutex type is desired to be used
// aside from above
template <typename _Tp> using G4TAutoLock = G4TemplateAutoLock<_Tp>;
#endif //G4AUTOLOCK_HH
+56 -29
View File
@@ -77,6 +77,13 @@
//Debug this code
//#define g4cdebug 1
#include <system_error>
#include <atomic>
// also included in G4CacheDetails.hh
#include "G4Threading.hh"
#include "G4AutoLock.hh"
//Thread Local storage details are in this header file
#include "G4CacheDetails.hh"
@@ -109,18 +116,18 @@ public:
G4Cache& operator=(const G4Cache& rhs);
protected:
const int& GetId() const { return id; }
private:
int id;
mutable G4CacheReference<value_type> theCache;
static G4Mutex gMutex;
static unsigned int instancesctr;
static unsigned int dstrctr;
const int& GetId() const { return id; }
inline value_type& GetCache() const {
theCache.Initialize(id);
return theCache.GetCache(id);
}
private:
int id;
mutable G4CacheReference<value_type> theCache;
static std::atomic<unsigned int> instancesctr;
static std::atomic<unsigned int> dstrctr;
inline value_type& GetCache() const {
theCache.Initialize(id);
return theCache.GetCache(id);
}
};
@@ -215,7 +222,7 @@ using std::endl;
template<class V>
G4Cache<V>::G4Cache()
{
G4AutoLock l(&gMutex);
G4AutoLock l(G4TypeMutex<G4Cache<V>>());
id = instancesctr++;
#ifdef g4cdebug
cout<<"G4Cache id: "<<id<<endl;
@@ -228,7 +235,7 @@ G4Cache<V>::G4Cache(const G4Cache<V>& rhs)
//Copy is special, we need to copy the content
//of the cache, not the cache object
if ( this == &rhs ) return;
G4AutoLock l(&gMutex);
G4AutoLock l(G4TypeMutex<G4Cache<V>>());
id = instancesctr++;
//Force copy of cached data
V aCopy = rhs.GetCache();
@@ -254,8 +261,8 @@ G4Cache<V>& G4Cache<V>::operator=(const G4Cache<V>& rhs)
template<class V>
G4Cache<V>::G4Cache(const V& v)
{
G4AutoLock l(&gMutex);
id = instancesctr++;
G4AutoLock l(G4TypeMutex<G4Cache<V>>());
id = instancesctr++;
Put(v);
#ifdef g4cdebug
cout<<"G4Cache id: "<<id<<" "<<endl;
@@ -268,13 +275,38 @@ G4Cache<V>::~G4Cache()
#ifdef g4cdebug
cout<<"~G4Cache id: "<<id<<" "<<endl;
#endif
G4AutoLock l(&gMutex);
++dstrctr;
// don't automatically lock --> wait until we can catch an error
// without scoping the G4AutoLock
G4AutoLock l(G4TypeMutex<G4Cache<V>>(), std::defer_lock);
// sometimes the mutex is unavailable in destructors so
// try to lock the associated mutex, but catch if fails
try
{
// a system_error in lock means that the mutex is unavailable
// we want to throw the error that comes from locking an unavailable
// mutex so that we know there is a memory leak
// if the mutex is valid, this will hold until the other thread finishes
l.lock();
}
catch (std::system_error& e)
{
// the error that comes from locking an unavailable mutex
#ifdef G4VERBOSE
G4cout << "Non-critical error: mutex lock failure in ~G4Cache<"
<< typeid(V).name() << ">. "
<< "If the RunManagerKernel has been deleted, it failed to "
<< "delete an allocated resource and this destructor is being "
<< "called after the statics were destroyed." << G4endl;
G4cout << "Exception: [code: " << e.code() << "] caught: "
<< e.what() << G4endl;
#endif
}
++dstrctr;
G4bool last = ( dstrctr == instancesctr );
theCache.Destroy(id,last);
theCache.Destroy(id, last);
if (last) {
instancesctr = 0;
dstrctr = 0;
instancesctr.store(0);
dstrctr.store(0);
}
}
@@ -292,13 +324,10 @@ V G4Cache<V>::Pop()
{ return GetCache(); }
template<class V>
unsigned int G4Cache<V>::instancesctr = 0;
std::atomic<unsigned int> G4Cache<V>::instancesctr(0);
template<class V>
unsigned int G4Cache<V>::dstrctr = 0;
template<class V>
G4Mutex G4Cache<V>::gMutex = G4MUTEX_INITIALIZER;
std::atomic<unsigned int> G4Cache<V>::dstrctr(0);
//========== Implementation: G4VectorCache<V>
template<class V>
@@ -388,10 +417,8 @@ G4MapCache<K,V>::~G4MapCache()
}
template<class K, class V>
std::pair<typename G4MapCache<K,V>::iterator,G4bool> G4MapCache<K,V>::Insert(
const K& k,
const V& v
)
std::pair<typename G4MapCache<K,V>::iterator,G4bool>
G4MapCache<K,V>::Insert(const K& k, const V& v)
{
return G4Cache<map_type>::Get().insert( std::pair<key_type,value_type>(k,v) );
}
@@ -100,7 +100,7 @@ template<class VALTYPE> class G4CacheReference
// std::vector in case of stored objects and allow use of
// specialized allocators
static G4ThreadLocal cache_container *cache;
static cache_container*& cache();
};
// Template specialization for pointers
@@ -118,7 +118,7 @@ template<class VALTYPE> class G4CacheReference<VALTYPE*>
private:
typedef std::vector<VALTYPE*> cache_container;
static G4ThreadLocal cache_container *cache;
static cache_container*& cache();
};
// Template specialization for probably the most used case: double
@@ -137,7 +137,7 @@ template<> class G4CacheReference<G4double>
private:
typedef std::vector<G4double> cache_container;
G4GLOB_DLL static G4ThreadLocal std::vector<G4double> *cache;
static G4GLOB_DLL cache_container*& cache();
};
@@ -152,47 +152,47 @@ template<class V>
void G4CacheReference<V>::Initialize( unsigned int id )
{
#ifdef g4cdebug
if ( cache == 0 )
if ( cache() == 0 )
cout<<"Generic template"<<endl;
#endif
// Create cache container
if ( cache == 0 )
cache = new cache_container;
if ( cache->size() <= id )
cache->resize(id+1,static_cast<V*>(0));
if ( (*cache)[id] == 0 )
(*cache)[id]=new V;
if ( cache() == 0 )
cache() = new cache_container;
if ( cache()->size() <= id )
cache()->resize(id+1,static_cast<V*>(0));
if ( (*cache())[id] == 0 )
(*cache())[id]=new V;
}
template<class V>
void G4CacheReference<V>::Destroy( unsigned int id, G4bool last )
{
if ( cache )
if ( cache() )
{
#ifdef g4cdebug
cout<<"Destroying element"<<id<<" is last?"<<last<<endl;
#endif
if ( cache->size() < id )
if ( cache()->size() < id )
{
G4ExceptionDescription msg;
msg << "Internal fatal error. Invalid G4Cache size (requested id: "
<< id << " but cache has size: "<<cache->size();
<< id << " but cache has size: "<< cache()->size();
msg << " Possibly client created G4Cache object in a thread and"
<< " tried to delete it from another thread!";
G4Exception("G4CacheReference<V>::Destroy", "Cache001",
FatalException, msg);
return;
}
if ( cache->size() > id && (*cache)[id] )
if ( cache()->size() > id && (*cache())[id] )
{
delete (*cache)[id];
(*cache)[id]=0;
delete (*cache())[id];
(*cache())[id]=0;
}
if (last)
{
delete cache;
cache = 0;
delete cache();
cache() = 0;
}
}
}
@@ -200,12 +200,16 @@ void G4CacheReference<V>::Destroy( unsigned int id, G4bool last )
template<class V>
V& G4CacheReference<V>::GetCache( unsigned int id ) const
{
return *(cache->operator[](id));
return *(cache()->operator[](id));
}
template<class V>
G4ThreadLocal typename
G4CacheReference<V>::cache_container * G4CacheReference<V>::cache = 0;
typename G4CacheReference<V>::cache_container*&
G4CacheReference<V>::cache()
{
G4ThreadLocalStatic cache_container* _instance = nullptr;
return _instance;
}
//======= Implementation: G4CacheReference<V*>
//============================================
@@ -214,45 +218,45 @@ template<class V>
void G4CacheReference<V*>::Initialize( unsigned int id )
{
#ifdef g4cdebug
if ( cache == 0 )
if ( cache() == 0 )
cout<<"Pointer template"<<endl;
#endif
if ( cache == 0 )
cache = new cache_container;
if ( cache->size() <= id )
cache->resize(id+1,static_cast<V*>(0));
if ( cache() == 0 )
cache() = new cache_container;
if ( cache()->size() <= id )
cache()->resize(id+1,static_cast<V*>(0));
}
template<class V>
inline void G4CacheReference<V*>::Destroy( unsigned int id , G4bool last )
{
if ( cache )
if ( cache() )
{
#ifdef g4cdebug
cout << "Destroying element" << id << " is last?" << last
<< "-Pointer template specialization-" << endl;
#endif
if ( cache->size() < id )
if ( cache()->size() < id )
{
G4ExceptionDescription msg;
msg << "Internal fatal error. Invalid G4Cache size (requested id: "
<< id << " but cache has size: " << cache->size();
<< id << " but cache has size: " << cache()->size();
msg << " Possibly client created G4Cache object in a thread and"
<< " tried to delete it from another thread!";
G4Exception("G4CacheReference<V*>::Destroy", "Cache001",
FatalException, msg);
return;
}
if ( cache->size() > id && (*cache)[id] )
if ( cache()->size() > id && (*cache())[id] )
{
// Ownership is for client
// delete (*cache)[id];
(*cache)[id]=0;
(*cache())[id]=0;
}
if (last )
{
delete cache;
cache = 0;
delete cache();
cache() = 0;
}
}
}
@@ -260,12 +264,16 @@ inline void G4CacheReference<V*>::Destroy( unsigned int id , G4bool last )
template<class V>
V*& G4CacheReference<V*>::GetCache(unsigned int id) const
{
return (cache->operator[](id));
return (cache()->operator[](id));
}
template<class V>
G4ThreadLocal typename
G4CacheReference<V*>::cache_container * G4CacheReference<V*>::cache = 0;
typename G4CacheReference<V*>::cache_container*&
G4CacheReference<V*>::cache()
{
G4ThreadLocalStatic cache_container* _instance = nullptr;
return _instance;
}
//======= Implementation: G4CacheReference<double>
//============================================
@@ -275,10 +283,10 @@ void G4CacheReference<G4double>::Initialize( unsigned int id )
#ifdef g4cdebug
cout<<"Specialized template for G4double"<<endl;
#endif
if ( cache == 0 )
cache = new cache_container;
if ( cache->size() <= id )
cache->resize(id+1,static_cast<G4double>(0));
if ( cache() == 0 )
cache() = new cache_container;
if ( cache()->size() <= id )
cache()->resize(id+1,static_cast<G4double>(0));
}
#ifdef g4cdebug
@@ -287,20 +295,20 @@ void G4CacheReference<G4double>::Destroy( unsigned int id , G4bool last)
void G4CacheReference<G4double>::Destroy( unsigned int /*id*/ , G4bool last)
#endif
{
if ( cache && last )
if ( cache() && last )
{
#ifdef g4cdebug
cout << "Destroying element" << id << " is last?" << last
<< "-Pointer template specialization-" << endl;
#endif
delete cache;
cache = 0;
delete cache();
cache() = 0;
}
}
G4double& G4CacheReference<G4double>::GetCache(unsigned int id) const
{
return cache->operator[](id);
return cache()->operator[](id);
}
#endif
@@ -0,0 +1,149 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// $Id:$
//
//
// ----------------------------------------------------------------------
// G4Exception
//
// Global error function prints string to G4cerr (or G4cout in case of
// warning). May abort program according to severity.
// ----------------------------------------------------------------------
#ifndef G4EXCEPTION_HH
#define G4EXCEPTION_HH
#include "G4ios.hh"
#include "G4String.hh"
#include "G4StateManager.hh"
#include "G4VExceptionHandler.hh"
typedef std::ostringstream G4ExceptionDescription;
inline const G4String G4ExceptionErrBannerStart()
{
return "\n-------- EEEE ------- G4Exception-START -------- EEEE -------\n";
}
inline const G4String G4ExceptionWarnBannerStart()
{
return "\n-------- WWWW ------- G4Exception-START -------- WWWW -------\n";
}
inline const G4String G4ExceptionErrBannerEnd()
{
return "\n-------- EEEE ------- G4Exception-END -------- EEEE -------\n";
}
inline const G4String G4ExceptionWarnBannerEnd()
{
return "\n-------- WWWW ------- G4Exception-END -------- WWWW -------\n";
}
inline void G4Exception(const char* originOfException,
const char* exceptionCode,
G4ExceptionSeverity severity,
const char* description)
{
G4VExceptionHandler* exceptionHandler
= G4StateManager::GetStateManager()->GetExceptionHandler();
G4bool toBeAborted = true;
if(exceptionHandler)
{
toBeAborted = exceptionHandler
->Notify(originOfException,exceptionCode,severity,description);
}
else
{
static const G4String& es_banner = G4ExceptionErrBannerStart();
static const G4String& ee_banner = G4ExceptionErrBannerEnd();
static const G4String& ws_banner = G4ExceptionWarnBannerStart();
static const G4String& we_banner = G4ExceptionWarnBannerEnd();
std::ostringstream message;
message << "\n*** ExceptionHandler is not defined ***\n"
<< "*** G4Exception : " << exceptionCode << G4endl
<< " issued by : " << originOfException << G4endl
<< description << G4endl;
switch(severity)
{
case FatalException:
G4cerr << es_banner << message.str() << "*** Fatal Exception ***"
<< ee_banner << G4endl;
break;
case FatalErrorInArgument:
G4cerr << es_banner << message.str() << "*** Fatal Error In Argument ***"
<< ee_banner << G4endl;
break;
case RunMustBeAborted:
G4cerr << es_banner << message.str() << "*** Run Must Be Aborted ***"
<< ee_banner << G4endl;
break;
case EventMustBeAborted:
G4cerr << es_banner << message.str() << "*** Event Must Be Aborted ***"
<< ee_banner << G4endl;
break;
default:
G4cout << ws_banner << message.str()
<< "*** This is just a warning message. ***"
<< we_banner << G4endl;
toBeAborted = false;
break;
}
}
if(toBeAborted)
{
if(G4StateManager::GetStateManager()->SetNewState(G4State_Abort))
{
G4cerr << G4endl << "*** G4Exception: Aborting execution ***" << G4endl;
abort();
}
else
{
G4cerr << G4endl << "*** G4Exception: Abortion suppressed ***"
<< G4endl << "*** No guarantee for further execution ***" << G4endl;
}
}
}
inline void G4Exception(const char* originOfException,
const char* exceptionCode,
G4ExceptionSeverity severity,
G4ExceptionDescription & description)
{
G4String des = description.str();
G4Exception(originOfException, exceptionCode, severity, des.c_str());
}
inline void G4Exception(const char* originOfException,
const char* exceptionCode,
G4ExceptionSeverity severity,
G4ExceptionDescription & description,
const char* comments)
{
description << comments << G4endl;
G4Exception(originOfException, exceptionCode, severity, description);
}
#endif /* G4EXCEPTION_HH */
@@ -24,7 +24,7 @@
// ********************************************************************
//
//
// $Id: G4FPEDetection.hh 86793 2014-11-18 10:01:46Z gcosmo $
// $Id: G4FPEDetection.hh 108434 2018-02-14 07:20:56Z gcosmo $
//
//
// -*- C++ -*-
@@ -164,10 +164,10 @@
#include <fenv.h>
#include <signal.h>
#define DEFINED_PPC (defined(__ppc__) || defined(__ppc64__))
#define DEFINED_INTEL (defined(__i386__) || defined(__x86_64__))
//#define DEFINED_PPC (defined(__ppc__) || defined(__ppc64__))
//#define DEFINED_INTEL (defined(__i386__) || defined(__x86_64__))
#if DEFINED_PPC
#if (defined(__ppc__) || defined(__ppc64__)) // PPC
#define FE_EXCEPT_SHIFT 22 // shift flags right to get masks
#define FM_ALL_EXCEPT FE_ALL_EXCEPT >> FE_EXCEPT_SHIFT
@@ -198,7 +198,7 @@
return ( fesetenv (&fenv) ? -1 : old_excepts );
}
#elif DEFINED_INTEL
#elif (defined(__i386__) || defined(__x86_64__)) // INTEL
static inline int feenableexcept (unsigned int excepts)
{
@@ -119,11 +119,8 @@
#ifndef G4MTBARRIER_HH_
#define G4MTBARRIER_HH_
#include "G4Threading.hh"
#ifdef WIN32
#include "windefs.hh"
#endif
#include "G4Threading.hh"
class G4MTBarrier
{
@@ -154,11 +151,6 @@ private:
G4Mutex m_mutex;
G4Condition m_counterChanged;
G4Condition m_continue;
#if defined(WIN32)
CRITICAL_SECTION cs1;
CRITICAL_SECTION cs2;
#endif
};
#endif /* G4MTBARRIER_HH_ */
+7 -24
View File
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4Pow.hh 93311 2015-10-16 10:16:37Z gcosmo $
// $Id: G4Pow.hh 109086 2018-03-26 08:20:25Z gcosmo $
//
//
// -------------------------------------------------------------------
@@ -64,7 +64,7 @@ class G4Pow
// Fast computation of Z^1/3
//
inline G4double Z13(G4int Z) const;
inline G4double A13(G4double A) const;
G4double A13(G4double A) const;
// Fast computation of Z^2/3
//
@@ -101,6 +101,9 @@ class G4Pow
G4Pow();
G4double A13Low(const G4double, const bool) const;
G4double A13High(const G4double, const bool) const;
inline G4double logBase(G4double x) const;
static G4Pow* fpInstance;
@@ -109,12 +112,14 @@ class G4Pow
const G4int max2;
G4double maxA;
G4double maxLowA;
G4double maxA2;
G4double maxAexp;
G4DataVector ener;
G4DataVector logen;
G4DataVector pz13;
G4DataVector lowa13;
G4DataVector lz;
G4DataVector lz2;
G4DataVector fexp;
@@ -129,28 +134,6 @@ inline G4double G4Pow::Z13(G4int Z) const
return pz13[Z];
}
inline G4double G4Pow::A13(G4double A) const
{
G4double res = 0.0;
if(A > 0.0)
{
G4double a = (1.0 <= A) ? A : 1.0/A;
if(1.0 > A) { a = 1.0/A; }
if(a <= maxA)
{
G4int i = G4int(a + 0.5);
G4double x = (a/G4double(i) - 1.0)*onethird;
res = pz13[i]*(1.0 + x - x*x*(1.0 - 1.66666666*x));
if(1.0 > A) { res = 1.0/res; }
}
else
{
res = std::pow(A, onethird);
}
}
return res;
}
inline G4double G4Pow::Z23(G4int Z) const
{
G4double x = Z13(Z);
@@ -24,7 +24,7 @@
// ********************************************************************
//
//
// $Id: G4ReferenceCountedHandle.hh 108486 2018-02-15 14:47:25Z gcosmo $
// $Id: G4ReferenceCountedHandle.hh 110251 2018-05-17 14:09:28Z gcosmo $
//
//
// Class G4ReferenceCountedHandle
@@ -115,8 +115,8 @@ private:
// The object subject to reference counting.
};
extern G4GLOB_DLL G4ThreadLocal
G4Allocator<G4ReferenceCountedHandle<void> > *aRCHAllocator;
extern G4GLOB_DLL
G4Allocator<G4ReferenceCountedHandle<void>>*& aRCHAllocator();
template <class X>
class G4CountedObject
@@ -156,8 +156,8 @@ private:
// The counted object.
};
extern G4GLOB_DLL G4ThreadLocal
G4Allocator<G4CountedObject<void> > *aCountedObjectAllocator;
extern G4GLOB_DLL
G4Allocator<G4CountedObject<void>>*& aCountedObjectAllocator();
// --------- G4CountedObject<X> Inline function definitions ---------
@@ -189,15 +189,15 @@ void G4CountedObject<X>::Release()
template <class X>
void* G4CountedObject<X>::operator new( size_t )
{
if (!aCountedObjectAllocator)
aCountedObjectAllocator = new G4Allocator<G4CountedObject<void> >;
return( (void *)aCountedObjectAllocator->MallocSingle() );
if (!aCountedObjectAllocator())
aCountedObjectAllocator() = new G4Allocator<G4CountedObject<void>>;
return( (void *)aCountedObjectAllocator()->MallocSingle() );
}
template <class X>
void G4CountedObject<X>::operator delete( void *pObj )
{
aCountedObjectAllocator->FreeSingle( (G4CountedObject<void>*)pObj );
aCountedObjectAllocator()->FreeSingle( (G4CountedObject<void>*)pObj );
}
// --------- G4ReferenceCountedHandle<X> Inline function definitions ---------
@@ -282,15 +282,15 @@ X* G4ReferenceCountedHandle<X>::operator ()() const
template <class X>
void* G4ReferenceCountedHandle<X>::operator new( size_t )
{
if (!aRCHAllocator)
aRCHAllocator = new G4Allocator<G4ReferenceCountedHandle<void> >;
return( (void *)aRCHAllocator->MallocSingle() );
if (!aRCHAllocator())
aRCHAllocator() = new G4Allocator<G4ReferenceCountedHandle<void> >;
return( (void *)aRCHAllocator()->MallocSingle() );
}
template <class X>
void G4ReferenceCountedHandle<X>::operator delete( void *pObj )
{
aRCHAllocator->FreeSingle( (G4ReferenceCountedHandle<void>*)pObj );
aRCHAllocator()->FreeSingle( (G4ReferenceCountedHandle<void>*)pObj );
}
#endif // _G4REFERENCECOUNTEDHANDLE_H_
@@ -24,7 +24,7 @@
// ********************************************************************
//
//
// $Id: G4SliceTimer.hh 67970 2013-03-13 10:10:06Z gcosmo $
// $Id: G4SliceTimer.hh 110674 2018-06-07 10:30:11Z gcosmo $
//
//
// ----------------------------------------------------------------------
@@ -134,6 +134,4 @@ std::ostream& operator << (std::ostream& os, const G4SliceTimer& t);
#include "G4SliceTimer.icc"
#define times ostimes
#endif
@@ -24,7 +24,7 @@
// ********************************************************************
//
//
// $Id: G4StateManager.hh 108486 2018-02-15 14:47:25Z gcosmo $
// $Id: G4StateManager.hh 110286 2018-05-18 09:40:01Z gcosmo $
//
//
// ------------------------------------------------------------
@@ -52,7 +52,8 @@
#define G4StateManager_h 1
#include <vector>
#include "globals.hh"
#include "G4Types.hh"
#include "G4String.hh"
#include "G4ApplicationState.hh"
#include "G4VStateDependent.hh"
#include "G4VExceptionHandler.hh"
+207 -144
View File
@@ -40,179 +40,242 @@
#include "G4Types.hh"
#include <chrono>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <future>
#include <vector>
// Macro to put current thread to sleep
//
#if defined(WIN32)
#define G4THREADSLEEP( tick ) { Sleep(tick); }
#else
#include <unistd.h> // needed for sleep()
#define G4THREADSLEEP( tick ) { sleep(tick); }
#endif
#define G4THREADSLEEP(tick) \
std::this_thread::sleep_for(std::chrono::seconds( tick ))
// will be used in the future when migrating threading to task-based style
//template <typename _Tp> using G4Future = std::future<_Tp>;
//template <typename _Tp> using G4SharedFuture = std::shared_future<_Tp>;
//template <typename _Tp> using G4Promise = std::promise<_Tp>;
//
// NOTE ON GEANT4 SERIAL BUILDS AND MUTEX/UNIQUE_LOCK
// ==================================================
//
// G4Mutex and G4RecursiveMutex are always C++11 std::mutex types
// however, in serial mode, using G4MUTEXLOCK and G4MUTEXUNLOCK on these
// types has no effect -- i.e. the mutexes are not actually locked or unlocked
//
// Additionally, when a G4Mutex or G4RecursiveMutex is used with G4AutoLock
// and G4RecursiveAutoLock, respectively, these classes also suppressing
// the locking and unlocking of the mutex. Regardless of the build type,
// G4AutoLock and G4RecursiveAutoLock inherit from std::unique_lock<std::mutex>
// and std::unique_lock<std::recursive_mutex>, respectively. This means
// that in situations (such as is needed by the analysis category), the
// G4AutoLock and G4RecursiveAutoLock can be passed to functions requesting
// a std::unique_lock. Within these functions, since std::unique_lock
// member functions are not virtual, they will not retain the dummy locking
// and unlocking behavior
// --> An example of this behavior can be found in G4AutoLock.hh
//
// Jonathan R. Madsen (February 21, 2018)
//
// global mutex types
typedef std::mutex G4Mutex;
typedef std::recursive_mutex G4RecursiveMutex;
// mutex macros
#define G4MUTEX_INITIALIZER {}
#define G4MUTEXINIT(mutex) ;;
#define G4MUTEXDESTROY(mutex) ;;
// static functions: get_id(), sleep_for(...), sleep_until(...), yield(),
namespace G4ThisThread { using namespace std::this_thread; }
// will be used in the future when migrating threading to task-based style
// and are currently used in unit tests
template <typename _Tp> using G4Promise = std::promise<_Tp>;
template <typename _Tp> using G4Future = std::future<_Tp>;
template <typename _Tp> using G4SharedFuture = std::shared_future<_Tp>;
// Some useful types
typedef void* G4ThreadFunReturnType;
typedef void* G4ThreadFunArgType;
typedef G4int (*thread_lock)(G4Mutex*);
typedef G4int (*thread_unlock)(G4Mutex*);
// Helper function for getting a unique static mutex for a specific
// class or type
// Usage example:
// a template class "G4Cache<T>" that required a static
// mutex for specific to type T:
// G4AutoLock l(G4TypeMutex<G4Cache<T>>());
template <typename _Tp>
G4Mutex& G4TypeMutex(const unsigned int& _n = 0)
{
static G4Mutex* _mutex = new G4Mutex();
if(_n == 0)
return *_mutex;
static std::vector<G4Mutex*> _mutexes;
if(_n > _mutexes.size())
_mutexes.resize(_n, nullptr);
if(!_mutexes[_n])
_mutexes[_n] = new G4Mutex();
return *(_mutexes[_n-1]);
}
// Helper function for getting a unique static recursive_mutex for a
// specific class or type
// Usage example:
// a template class "G4Cache<T>" that required a static
// recursive_mutex for specific to type T:
// G4RecursiveAutoLock l(G4TypeRecursiveMutex<G4Cache<T>>());
template <typename _Tp>
G4RecursiveMutex& G4TypeRecursiveMutex(const unsigned int& _n = 0)
{
static G4RecursiveMutex* _mutex = new G4RecursiveMutex();
if(_n == 0)
return *(_mutex);
static std::vector<G4RecursiveMutex*> _mutexes;
if(_n > _mutexes.size())
_mutexes.resize(_n, nullptr);
if(!_mutexes[_n])
_mutexes[_n] = new G4RecursiveMutex();
return *(_mutexes[_n-1]);
}
#if defined(G4MULTITHREADED)
//===============================
// Multi-threaded build
//===============================
#if ( defined(__MACH__) && defined(__clang__) && defined(__x86_64__) ) || \
( defined(__MACH__) && defined(__GNUC__) && (__GNUC__>=4 && __GNUC_MINOR__>=7 || __GNUC__>=5) ) || \
defined(__linux__) || defined(_AIX)
//
// Multi-threaded build: for POSIX systems
//
#include <pthread.h>
#if defined(__MACH__) // needed only for MacOSX for definition of pid_t
#include <sys/types.h>
#endif
//==========================================
// G4MULTITHREADED is ON - threading enabled
//==========================================
typedef pthread_mutex_t G4Mutex;
typedef pthread_t G4Thread;
// global thread types
typedef std::thread G4Thread;
typedef std::thread::native_handle_type G4NativeThread;
// G4Mutex initializer macro
//
#define G4MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
// Lock/unlock a G4Mutex function name
//
#define G4MUTEXLOCK pthread_mutex_lock
#define G4MUTEXUNLOCK pthread_mutex_unlock
// Macro to initialize a Mutex
//
#define G4MUTEXINIT(mutex) pthread_mutex_init( &mutex , NULL);
#define G4MUTEXDESTROY(mutex) pthread_mutex_destroy( &mutex );
// Macro to create a G4Thread object
//
#define G4THREADCREATE( worker , func , arg ) { \
pthread_attr_t attr; \
pthread_attr_init(&attr); \
pthread_attr_setstacksize(&attr,16*1024*1024); \
pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_JOINABLE); \
pthread_create( worker, &attr, func , arg ); \
}
// mutex macros
#define G4MUTEXLOCK(mutex) { (mutex)->lock(); }
#define G4MUTEXUNLOCK(mutex) { (mutex)->unlock(); }
// Macro to join thread
//
#define G4THREADJOIN( worker ) pthread_join( worker , NULL)
#define G4THREADJOIN(worker) (worker).join()
// Macro to retrieve caller thread
//
#define G4THREADSELF pthread_self
// std::thread::id does not cast to integer
typedef std::thread::id G4Pid_t;
// Some useful types
//
typedef void* G4ThreadFunReturnType;
typedef void* G4ThreadFunArgType;
typedef G4int (*thread_lock)(G4Mutex*);
typedef G4int (*thread_unlock)(G4Mutex*);
typedef pid_t G4Pid_t;
// Instead of previous macro taking one argument, define function taking
// unlimited arguments
template <typename _Worker, typename _Func, typename... _Args>
void G4THREADCREATE(_Worker*& worker, _Func func, _Args... args)
{
*worker = G4Thread(func, std::forward<_Args>(args)...);
}
// Conditions
//
// See G4MTRunManager for example on how to use these
// This complication is needed to be portable with WIN32
// Note that WIN32 requires an additional initialization step.
// See example code
//
typedef pthread_cond_t G4Condition;
#define G4CONDITION_INITIALIZER PTHREAD_COND_INITIALIZER
#define G4CONDITIONWAIT( cond, mutex ) pthread_cond_wait( cond , mutex );
#define G4CONDITIONBROADCAST( cond ) pthread_cond_broadcast( cond );
#elif defined(WIN32)
typedef std::condition_variable G4Condition;
#define G4CONDITION_INITIALIZER {}
#define G4CONDITIONWAIT(cond, lock) (cond)->wait(*lock);
#define G4CONDITIONWAITLAMBDA(cond, lock, lambda) (cond)->wait(*lock, lambda);
#define G4CONDITIONBROADCAST(cond) (cond)->notify_all();
//
// Multi-threaded build: for Windows systems
// we don't define above globally so single-threaded code does not get
// caught in condition with no other thread to wake it up
//
#include "windefs.hh" // Include 'safe...' <windows.h>
typedef HANDLE G4Mutex;
typedef HANDLE G4Thread;
#define G4MUTEX_INITIALIZER CreateMutex(NULL,FALSE,NULL)
DWORD /*WINAPI*/ G4WaitForSingleObjectInf( __in G4Mutex m );
#define G4MUTEXLOCK G4WaitForSingleObjectInf
// #define G4MUTEXINIT(mutex) InitializeCriticalSection( &mutex );
#define G4MUTEXINIT(mutex);
#define G4MUTEXDESTROY(mutex);
// Not clear why following two lines are needed...
//
BOOL G4ReleaseMutex( __in G4Mutex m);
#define G4MUTEXUNLOCK G4ReleaseMutex
#define G4THREADCREATE( worker, func, arg ) { *worker = CreateThread( NULL, 16*1024*1024 , func , arg , 0 , NULL ); }
#define G4THREADJOIN( worker ) WaitForSingleObject( worker , INFINITE);
#define G4THREADSELF GetCurrentThreadId
#define G4ThreadFunReturnType DWORD WINAPI
typedef LPVOID G4ThreadFunArgType;
typedef DWORD (*thread_lock)(G4Mutex);
typedef BOOL (*thread_unlock)(G4Mutex);
typedef DWORD G4Pid_t;
// Conditions
//
typedef CONDITION_VARIABLE G4Condition;
#define G4CONDITION_INITIALIZER CONDITION_VARIABLE_INIT
#define G4CONDITIONWAIT( cond , criticalsectionmutex ) SleepConditionVariableCS( cond, criticalsectionmutex , INFINITE );
#define G4CONDITIONBROADCAST( cond ) WakeAllConditionVariable( cond );
#else
#error "No Threading model technology supported for this platform. Use sequential build !"
#endif
#else
//==========================================
// G4MULTITHREADED is OFF - Sequential build
//==========================================
typedef G4int G4Mutex;
typedef G4int G4Thread;
#define G4MUTEX_INITIALIZER 1
G4int fake_mutex_lock_unlock( G4Mutex* );// { return 0; }
#define G4MUTEXINIT(mutex) ;;
#define G4MUTEXDESTROY(mutex) ;;
#define G4MUTEXLOCK fake_mutex_lock_unlock
#define G4MUTEXUNLOCK fake_mutex_lock_unlock
#define G4THREADCREATE( worker , func , arg ) ;;
#define G4THREADJOIN( worker ) ;;
#define G4THREADSELF( nothing ) G4Thread(nothing);
typedef void* G4ThreadFunReturnType;
typedef void* G4ThreadFunArgType;
typedef G4int (*thread_lock)(G4Mutex*);
typedef G4int (*thread_unlock)(G4Mutex*);
typedef G4int G4Pid_t;
typedef G4int G4Condition;
#define G4CONDITION_INITIALIZER 1
#define G4CONDITIONWAIT( cond, mutex ) { ++(*cond); ++(*mutex); }
#define G4CONDITIONBROADCAST( cond ) { ++(*cond); }
//==========================================
// G4MULTITHREADED is OFF - Sequential build
//==========================================
// implement a dummy thread class that acts like a thread
class G4DummyThread
{
public:
typedef G4int native_handle_type;
typedef std::thread::id id;
public:
// does nothing
G4DummyThread()
{ }
// a std::thread-like constructor that execute upon construction
template <typename _Func, typename... _Args>
G4DummyThread(_Func func, _Args&&... _args)
{
func(std::forward<_Args>(_args)...);
}
public:
native_handle_type native_handle() const { return native_handle_type(); }
bool joinable() const { return true; }
id get_id() const noexcept { return std::this_thread::get_id(); }
void swap(G4DummyThread&) { }
void join() { }
void detach() { }
public:
static unsigned int hardware_concurrency() noexcept
{
return std::thread::hardware_concurrency();
}
};
// global thread types
typedef G4DummyThread G4Thread;
typedef G4DummyThread::native_handle_type G4NativeThread;
// mutex macros
#define G4MUTEXLOCK(mutex) ;;
#define G4MUTEXUNLOCK(mutex) ;;
// Macro to join thread
#define G4THREADJOIN(worker) ;;
typedef G4int G4Pid_t;
// Instead of previous macro taking one argument, define function taking
// unlimited arguments
template <typename _Worker, typename _Func, typename... _Args>
void G4THREADCREATE(_Worker*& worker, _Func func, _Args... args)
{
*worker = G4Thread(func, std::forward<_Args>(args)...);
}
typedef G4int G4Condition;
#define G4CONDITION_INITIALIZER 1
#define G4CONDITIONWAIT( cond, mutex ) { (*cond)++; }
#define G4CONDITIONWAITLAMBDA( cond, mutex, lambda ) { (*cond)++; }
#define G4CONDITIONBROADCAST( cond ) { (*cond)++; }
#endif //G4MULTITHREADING
namespace G4Threading
{
enum {
enum
{
SEQUENTIAL_ID = -2,
MASTER_ID = -1,
WORKER_ID = 0,
GENERICTHREAD_ID = -1000
};
G4Pid_t G4GetPidId();
G4int G4GetNumberOfCores();
G4int G4GetThreadId();
G4bool IsWorkerThread();
G4bool IsMasterThread();
void G4SetThreadId( G4int aNewValue );
G4bool G4SetPinAffinity( G4int idx , G4Thread& at);
void SetMultithreadedApplication(G4bool value);
G4bool IsMultithreadedApplication();
int WorkerThreadLeavesPool();
int WorkerThreadJoinsPool();
G4int GetNumberOfRunningWorkerThreads();
G4Pid_t G4GetPidId();
G4int G4GetNumberOfCores();
G4int G4GetThreadId();
G4bool IsWorkerThread();
G4bool IsMasterThread();
void G4SetThreadId( G4int aNewValue );
G4bool G4SetPinAffinity( G4int idx , G4NativeThread& at);
void SetMultithreadedApplication(G4bool value);
G4bool IsMultithreadedApplication();
int WorkerThreadLeavesPool();
int WorkerThreadJoinsPool();
G4int GetNumberOfRunningWorkerThreads();
}
#endif //G4Threading_hh
@@ -23,34 +23,60 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id$
//
// ---------------------------------------------------------------
// GEANT 4 class header file
// $Id:$
//
// Class Description:
//
// This file includes Windows declarations from <windows.h> protecting
// those defines that may cause troubles within the Geant4 code.
// ----------------------------------------------------------------------
// G4TiMemory
//
// Provides empty macros when Geant4 is compiled with TiMemory disabled
// ----------------------------------------------------------------------
// ---------------------------------------------------------------
#ifndef windefs_hh
#define windefs_hh
#ifndef g4timemory_hh_
#define g4timemory_hh_
#if defined(WIN32)
//
#define WIN32_LEAN_AND_MEAN
#define NOMINMAX // avoid redefinition of min() and max()
#include <windows.h>
#undef pascal // trick to overcome redefinition of 'pascal'
#undef scr1
#undef scr2
#undef rad1
#undef rad2
#undef small
#undef ABSOLUTE
#undef RELATIVE
#undef GetObject
#endif // WIN32
#include "globals.hh"
//----------------------------------------------------------------------------//
#ifdef GEANT4_USE_TIMEMORY
# if defined __GNUC__
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wexceptions"
# pragma GCC diagnostic ignored "-Wunused-private-field"
# endif
#include <timemory/timemory.hpp>
typedef tim::auto_timer G4AutoTimer;
inline void InitializeTiMemory()
{
tim::manager* instance = tim::manager::instance();
instance->enable(true);
}
# if defined __GNUC__
# pragma GCC diagnostic pop
# endif
#else
#define TIMEMORY_AUTO_TIMER(str)
#define TIMEMORY_AUTO_TIMER_OBJ(str) {}
#define TIMEMORY_BASIC_AUTO_TIMER(str)
#define TIMEMORY_BASIC_AUTO_TIMER_OBJ(str) {}
#define TIMEMORY_DEBUG_BASIC_AUTO_TIMER(str)
#define TIMEMORY_DEBUG_AUTO_TIMER(str)
inline void InitializeTiMemory()
{ }
#endif
//----------------------------------------------------------------------------//
#endif
#endif //windefs_hh
+8 -6
View File
@@ -24,7 +24,7 @@
// ********************************************************************
//
//
// $Id: G4Timer.hh 67970 2013-03-13 10:10:06Z gcosmo $
// $Id: G4Timer.hh 110674 2018-06-07 10:30:11Z gcosmo $
//
//
// ----------------------------------------------------------------------
@@ -107,9 +107,13 @@
#include "G4Types.hh"
#include "G4ios.hh"
#include <chrono>
class G4Timer
{
public:
typedef std::chrono::high_resolution_clock clock_type;
public:
G4Timer();
@@ -121,10 +125,10 @@ class G4Timer
G4double GetSystemElapsed() const;
G4double GetUserElapsed() const;
private:
private:
G4bool fValidTimes;
clock_t fStartRealTime,fEndRealTime;
std::chrono::time_point<clock_type> fStartRealTime, fEndRealTime;
tms fStartTimes,fEndTimes;
};
@@ -132,6 +136,4 @@ std::ostream& operator << (std::ostream& os, const G4Timer& t);
#include "G4Timer.icc"
#define times ostimes
#endif
+5 -3
View File
@@ -24,7 +24,7 @@
// ********************************************************************
//
//
// $Id: G4Timer.icc 67970 2013-03-13 10:10:06Z gcosmo $
// $Id: G4Timer.icc 108434 2018-02-14 07:20:56Z gcosmo $
//
//
// ------------------------------------------------------------
@@ -35,13 +35,15 @@ inline
void G4Timer::Start()
{
fValidTimes=false;
fStartRealTime=times(&fStartTimes);
times(&fStartTimes);
fStartRealTime = clock_type::now();
}
inline
void G4Timer::Stop()
{
fEndRealTime=times(&fEndTimes);
times(&fEndTimes);
fEndRealTime = clock_type::now();
fValidTimes=true;
}
+2 -2
View File
@@ -24,7 +24,7 @@
// ********************************************************************
//
//
// $Id: G4Types.hh 67970 2013-03-13 10:10:06Z gcosmo $
// $Id: G4Types.hh 109033 2018-03-22 11:14:17Z gcosmo $
//
//
// GEANT4 native types
@@ -43,7 +43,7 @@
// Define DLL export macro for WIN32 systems for
// importing/exporting external symbols to DLLs
//
#if defined G4LIB_BUILD_DLL
#if defined G4LIB_BUILD_DLL && !defined G4MULTITHREADED
#define G4DLLEXPORT __declspec( dllexport )
#define G4DLLIMPORT __declspec( dllimport )
#else
@@ -24,7 +24,7 @@
// ********************************************************************
//
//
// $Id: G4VExceptionHandler.hh 67970 2013-03-13 10:10:06Z gcosmo $
// $Id: G4VExceptionHandler.hh 110286 2018-05-18 09:40:01Z gcosmo $
//
//
// ------------------------------------------------------------
@@ -49,7 +49,7 @@
#ifndef G4VExceptionHandler_h
#define G4VExceptionHandler_h 1
#include "globals.hh"
#include "G4Types.hh"
#include "G4ExceptionSeverity.hh"
class G4VExceptionHandler
@@ -24,7 +24,7 @@
// ********************************************************************
//
//
// $Id: G4VStateDependent.hh 67970 2013-03-13 10:10:06Z gcosmo $
// $Id: G4VStateDependent.hh 110286 2018-05-18 09:40:01Z gcosmo $
//
//
// ------------------------------------------------------------
@@ -49,7 +49,7 @@
#ifndef G4VStateDependent_h
#define G4VStateDependent_h 1
#include "globals.hh"
#include "G4Types.hh"
#include "G4ApplicationState.hh"
class G4VStateDependent
@@ -24,7 +24,7 @@
// ********************************************************************
//
//
// $Id: G4Version.hh 110074 2018-05-15 10:03:53Z gcosmo $
// $Id: G4Version.hh 110902 2018-06-25 08:56:46Z gcosmo $
// GEANT4 tag $Name:$
//
// Version information
@@ -46,11 +46,11 @@
// |--> patch number
#ifndef G4VERSION_NUMBER
#define G4VERSION_NUMBER 1042
#define G4VERSION_NUMBER 1050
#endif
#ifndef G4VERSION_TAG
#define G4VERSION_TAG "$Name: geant4-10-04-patch-02 $"
#define G4VERSION_TAG "$Name: geant4-10-05-beta-01 $"
#endif
// as variables
@@ -58,10 +58,10 @@
#include "G4String.hh"
#ifdef G4MULTITHREADED
static const G4String G4Version = "$Name: geant4-10-04-patch-02 [MT]$";
static const G4String G4Version = "$Name: geant4-10-05-beta-01 [MT]$";
#else
static const G4String G4Version = "$Name: geant4-10-04-patch-02 $";
static const G4String G4Version = "$Name: geant4-10-05-beta-01 $";
#endif
static const G4String G4Date = "(25-May-2018)";
static const G4String G4Date = "(29-June-2018)";
#endif
+5 -5
View File
@@ -24,7 +24,7 @@
// ********************************************************************
//
//
// $Id: G4ios.hh 70021 2013-05-22 07:55:29Z gcosmo $
// $Id: G4ios.hh 110251 2018-05-17 14:09:28Z gcosmo $
//
//
// ---------------------------------------------------------------
@@ -42,10 +42,10 @@
#ifdef G4MULTITHREADED
extern G4GLOB_DLL G4ThreadLocal std::ostream *G4cout_p;
extern G4GLOB_DLL G4ThreadLocal std::ostream *G4cerr_p;
#define G4cout (*G4cout_p)
#define G4cerr (*G4cerr_p)
extern G4GLOB_DLL std::ostream*& _G4cout_p();
extern G4GLOB_DLL std::ostream*& _G4cerr_p();
#define G4cout (*_G4cout_p())
#define G4cerr (*_G4cerr_p())
#else // Sequential
@@ -24,7 +24,7 @@
// ********************************************************************
//
//
// $Id: G4strstreambuf.hh 103661 2017-04-20 14:57:11Z gcosmo $
// $Id: G4strstreambuf.hh 110251 2018-05-17 14:09:28Z gcosmo $
//
// ====================================================================
//
@@ -43,10 +43,10 @@ class G4strstreambuf;
#ifdef G4MULTITHREADED
extern G4GLOB_DLL G4ThreadLocal G4strstreambuf *G4coutbuf_p;
extern G4GLOB_DLL G4ThreadLocal G4strstreambuf *G4cerrbuf_p;
#define G4coutbuf (*G4coutbuf_p)
#define G4cerrbuf (*G4cerrbuf_p)
extern G4GLOB_DLL G4strstreambuf*& _G4coutbuf_p();
extern G4GLOB_DLL G4strstreambuf*& _G4cerrbuf_p();
#define G4coutbuf (*_G4coutbuf_p())
#define G4cerrbuf (*_G4cerrbuf_p())
#else // Sequential
+2 -23
View File
@@ -24,7 +24,7 @@
// ********************************************************************
//
//
// $Id: globals.hh 67970 2013-03-13 10:10:06Z gcosmo $
// $Id: globals.hh 110286 2018-05-18 09:40:01Z gcosmo $
//
//
// Global Constants and typedefs
@@ -66,28 +66,7 @@
// Includes some additional definitions: sqr, G4SwapPtr, G4SwapObj.
#include "templates.hh"
// Includes Physical Constants and System of Units
// #include "G4PhysicalConstants.hh"
// #include "G4SystemOfUnits.hh"
// Global error function
#include "G4ExceptionSeverity.hh"
typedef std::ostringstream G4ExceptionDescription;
void G4Exception(const char* originOfException,
const char* exceptionCode,
G4ExceptionSeverity severity,
const char* comments);
void G4Exception(const char* originOfException,
const char* exceptionCode,
G4ExceptionSeverity severity,
G4ExceptionDescription & description);
void G4Exception(const char* originOfException,
const char* exceptionCode,
G4ExceptionSeverity severity,
G4ExceptionDescription & description,
const char* comments);
#include "G4Exception.hh"
#endif /* GLOBALS_HH */
+11 -31
View File
@@ -36,34 +36,19 @@
#if defined (G4MULTITHREADED)
#if ( defined(__MACH__) && defined(__clang__) && defined(__x86_64__) ) || \
( defined(__linux__) && defined(__clang__) )
#if (defined (G4USE_STD11) && __has_feature(cxx_thread_local))
# define G4ThreadLocalStatic static thread_local
# define G4ThreadLocal thread_local
#else
# define G4ThreadLocalStatic static __thread
# define G4ThreadLocal __thread
#endif
# define G4ThreadLocalStatic static thread_local
# define G4ThreadLocal thread_local
#elif ( (defined(__linux__) || defined(__MACH__)) && \
!defined(__INTEL_COMPILER) && defined(__GNUC__) && (__GNUC__>=4 && __GNUC_MINOR__<9))
#if defined (G4USE_STD11)
# define G4ThreadLocalStatic static __thread
# define G4ThreadLocal thread_local
#else
# define G4ThreadLocalStatic static __thread
# define G4ThreadLocal __thread
#endif
# define G4ThreadLocalStatic static __thread
# define G4ThreadLocal thread_local
#elif ( (defined(__linux__) || defined(__MACH__)) && \
!defined(__INTEL_COMPILER) && defined(__GNUC__) && (__GNUC__>=4 && __GNUC_MINOR__>=9) || __GNUC__>=5 )
#if defined (G4USE_STD11)
# define G4ThreadLocalStatic static thread_local
# define G4ThreadLocal thread_local
#else
# define G4ThreadLocalStatic static __thread
# define G4ThreadLocal __thread
#endif
# define G4ThreadLocalStatic static thread_local
# define G4ThreadLocal thread_local
#elif ( (defined(__linux__) || defined(__MACH__)) && \
defined(__INTEL_COMPILER) )
#if (defined (G4USE_STD11) && __INTEL_COMPILER>=1500)
#if __INTEL_COMPILER>=1500
# define G4ThreadLocalStatic static thread_local
# define G4ThreadLocal thread_local
#else
@@ -71,16 +56,11 @@
# define G4ThreadLocal __thread
#endif
#elif defined(_AIX)
#if defined (G4USE_STD11)
# define G4ThreadLocalStatic static thread_local
# define G4ThreadLocal thread_local
#else
# define G4ThreadLocalStatic static __thread
# define G4ThreadLocal __thread
#endif
# define G4ThreadLocalStatic static thread_local
# define G4ThreadLocal thread_local
#elif defined(WIN32)
# define G4ThreadLocalStatic static __declspec(thread)
# define G4ThreadLocal __declspec(thread)
# define G4ThreadLocalStatic static thread_local
# define G4ThreadLocal thread_local
#else
# error "No Thread Local Storage (TLS) technology supported for this platform. Use sequential build !"
#endif
+5 -2
View File
@@ -11,12 +11,13 @@
#
# Generated on : 24/9/2010
#
# $Id: sources.cmake 103592 2017-04-19 08:09:03Z gcosmo $
# $Id: sources.cmake 110674 2018-06-07 10:30:11Z gcosmo $
#
#------------------------------------------------------------------------------
# List external includes needed.
include_directories(${CLHEP_INCLUDE_DIRS})
include_directories(${TiMemory_INCLUDE_DIRS})
# List internal includes needed.
@@ -29,7 +30,6 @@ GEANT4_DEFINE_MODULE(NAME G4globman
globals.hh
templates.hh
tls.hh
windefs.hh
G4Allocator.hh
G4strstreambuf.icc
G4AllocatorPool.hh
@@ -41,6 +41,7 @@ GEANT4_DEFINE_MODULE(NAME G4globman
G4ErrorPropagatorData.hh
G4ErrorPropagatorData.icc
G4Evaluator.hh
G4Exception.hh
G4ExceptionSeverity.hh
G4Exp.hh
G4FPEDetection.hh
@@ -105,6 +106,7 @@ GEANT4_DEFINE_MODULE(NAME G4globman
G4MasterForwardcoutDestination.hh
G4FilecoutDestination.hh
G4BuffercoutDestination.hh
G4TiMemory.hh
SOURCES
G4Allocator.cc
G4AllocatorPool.cc
@@ -147,6 +149,7 @@ GEANT4_DEFINE_MODULE(NAME G4globman
GLOBAL_DEPENDENCIES
LINK_LIBRARIES
${CLHEP_LIBRARIES}
${TiMemory_LIBRARIES}
)
# List any source specific properties here
@@ -28,4 +28,10 @@
// Decalare needed static data member for fully specialized version of cache
#include "G4CacheDetails.hh"
G4ThreadLocal std::vector<G4double>* G4CacheReference<G4double>::cache = 0;
G4CacheReference<G4double>::cache_container*&
G4CacheReference<G4double>::cache()
{
G4ThreadLocalStatic std::vector<G4double>* _instance = nullptr;
return _instance;
}
+2 -95
View File
@@ -24,104 +24,11 @@
// ********************************************************************
//
//
// $Id: G4Exception.cc 67970 2013-03-13 10:10:06Z gcosmo $
// $Id: G4Exception.cc 110286 2018-05-18 09:40:01Z gcosmo $
//
//
// ----------------------------------------------------------------------
// G4Exception
//
// Global error function prints string to G4cerr (or G4cout in case of
// warning). May abort program according to severity.
// ----------------------------------------------------------------------
#include "G4ios.hh"
#include "G4String.hh"
#include "G4StateManager.hh"
void G4Exception(const char* originOfException,
const char* exceptionCode,
G4ExceptionSeverity severity,
const char* description)
{
G4VExceptionHandler* exceptionHandler
= G4StateManager::GetStateManager()->GetExceptionHandler();
G4bool toBeAborted = true;
if(exceptionHandler)
{
toBeAborted = exceptionHandler
->Notify(originOfException,exceptionCode,severity,description);
}
else
{
static const G4String es_banner
= "\n-------- EEEE ------- G4Exception-START -------- EEEE -------\n";
static const G4String ee_banner
= "\n-------- EEEE -------- G4Exception-END --------- EEEE -------\n";
static const G4String ws_banner
= "\n-------- WWWW ------- G4Exception-START -------- WWWW -------\n";
static const G4String we_banner
= "\n-------- WWWW -------- G4Exception-END --------- WWWW -------\n";
std::ostringstream message;
message << "\n*** ExceptionHandler is not defined ***\n"
<< "*** G4Exception : " << exceptionCode << G4endl
<< " issued by : " << originOfException << G4endl
<< description << G4endl;
switch(severity)
{
case FatalException:
G4cerr << es_banner << message.str() << "*** Fatal Exception ***"
<< ee_banner << G4endl;
break;
case FatalErrorInArgument:
G4cerr << es_banner << message.str() << "*** Fatal Error In Argument ***"
<< ee_banner << G4endl;
break;
case RunMustBeAborted:
G4cerr << es_banner << message.str() << "*** Run Must Be Aborted ***"
<< ee_banner << G4endl;
break;
case EventMustBeAborted:
G4cerr << es_banner << message.str() << "*** Event Must Be Aborted ***"
<< ee_banner << G4endl;
break;
default:
G4cout << ws_banner << message.str()
<< "*** This is just a warning message. ***"
<< we_banner << G4endl;
toBeAborted = false;
break;
}
}
if(toBeAborted)
{
if(G4StateManager::GetStateManager()->SetNewState(G4State_Abort))
{
G4cerr << G4endl << "*** G4Exception: Aborting execution ***" << G4endl;
abort();
}
else
{
G4cerr << G4endl << "*** G4Exception: Abortion suppressed ***"
<< G4endl << "*** No guarantee for further execution ***" << G4endl;
}
}
}
void G4Exception(const char* originOfException,
const char* exceptionCode,
G4ExceptionSeverity severity,
G4ExceptionDescription & description)
{
G4String des = description.str();
G4Exception(originOfException, exceptionCode, severity, des.c_str());
}
void G4Exception(const char* originOfException,
const char* exceptionCode,
G4ExceptionSeverity severity,
G4ExceptionDescription & description,
const char* comments)
{
description << comments << G4endl;
G4Exception(originOfException, exceptionCode, severity, description);
}
#include "G4Exception.hh"
+6 -34
View File
@@ -30,6 +30,8 @@
*
* Created on: Feb 10, 2016
* Author: adotti
* Updated on: Feb 9, 2018
* Author: jmadsen
*/
#include "G4MTBarrier.hh"
@@ -37,60 +39,30 @@
G4MTBarrier::G4MTBarrier(unsigned int numThreads ) :
m_numActiveThreads(numThreads),
m_counter(0),
m_mutex(G4MUTEX_INITIALIZER),
m_counterChanged(G4CONDITION_INITIALIZER),
m_continue(G4CONDITION_INITIALIZER)
{
#if defined(WIN32)
InitializeCriticalSection( &cs1 );
InitializeCriticalSection( &cs2 );
#endif
}
m_counter(0)
{}
void G4MTBarrier::ThisWorkerReady() {
//Step-1: Worker acquires lock on shared resource (the counter)
#ifndef WIN32
G4AutoLock lock(&m_mutex);
#else
EnterCriticalSection( &cs1 );
#endif
//Step-2: Worker increases counter
++m_counter;
//Step-3: Worker broadcasts that the counter has changed
G4CONDITIONBROADCAST(&m_counterChanged);
//Step-4: Worker waits on condition to continue
#ifndef WIN32
G4CONDITIONWAIT(&m_continue,&m_mutex);
#else
# ifdef G4MULTITHREADED
G4CONDITIONWAIT(&m_continue,&cs1);
# endif
LeaveCriticalSection(&cs1);
#endif
G4CONDITIONWAIT(&m_continue,&lock);
}
void G4MTBarrier::Wait() {
while (true)
{
//Step-2: Acquires lock on shared resource (the counter)
#ifndef WIN32
G4AutoLock lock(&m_mutex);
#else
EnterCriticalSection(&cs2);
#endif
//If the counter equals active threads, all threads are ready, exit the loop
if ( m_counter == m_numActiveThreads ) { break; }
//Step-3: Not all workers are ready, wait for the number to change
//before repeating the check
#ifdef WIN32
# ifdef G4MULTITHREADED
G4CONDITIONWAIT(&m_counterChanged,&cs2);
# endif
LeaveCriticalSection(&cs2);
#else
G4CONDITIONWAIT(&m_counterChanged,&m_mutex);
#endif
G4CONDITIONWAIT(&m_counterChanged,&lock);
}
}
+52 -3
View File
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4Pow.cc 93311 2015-10-16 10:16:37Z gcosmo $
// $Id: G4Pow.cc 109086 2018-03-26 08:20:25Z gcosmo $
//
// -------------------------------------------------------------------
//
@@ -40,6 +40,8 @@
// 08.01.2011 V.Ivanchenko extended maxZ from 256 to 512
// 02.05.2013 V.Ivanchenko added expA and logX methods,
// revised A13, logA, powZ, powA to improved accuracy
// 23.03.2018 M.Novak increased accuracy of A13 on the most critical
// [1/4,4] interval by introducing a denser(0.25) grid
//
// -------------------------------------------------------------------
@@ -74,17 +76,20 @@ G4Pow::G4Pow()
"Attempt to instantiate G4Pow in worker thread!");
}
#endif
const G4int maxZ = 512;
const G4int maxZ = 512;
const G4int maxZfact = 170;
const G4int numLowA = 17;
maxA = -0.6 + maxZ;
maxA2 = 1.25 + max2*0.2;
maxLowA = 4.0;
maxA2 = 1.25 + max2*0.2;
maxAexp = -0.76+ maxZfact*0.5;
ener.resize(max2+1,1.0);
logen.resize(max2+1,0.0);
lz2.resize(max2+1,0.0);
pz13.resize(maxZ,0.0);
lowa13.resize(numLowA,0.0);
lz.resize(maxZ,0.0);
fexp.resize(maxZfact,0.0);
fact.resize(maxZfact,0.0);
@@ -116,6 +121,11 @@ G4Pow::G4Pow()
logf += lz[i];
logfact[i] = logf;
}
for (G4int i=4; i<numLowA; ++i) {
lowa13[i] = std::pow(0.25*i,onethird);
}
}
// -------------------------------------------------------------------
@@ -125,6 +135,45 @@ G4Pow::~G4Pow()
// -------------------------------------------------------------------
G4double G4Pow::A13(G4double A) const {
G4double res = 0.;
if (A>0.) {
const bool invert = (A<1.);
const G4double a = invert ? 1./A : A;
res = (a<maxLowA) ? A13Low(a, invert) : A13High(a, invert);
}
return res;
}
// -------------------------------------------------------------------
G4double G4Pow::A13High(const G4double a, const bool invert) const {
G4double res;
if (a<maxA) {
const G4int i = static_cast<G4int>(a+0.5);
const G4double x = (a/i-1.)*onethird;
res = pz13[i]*(1.+x-x*x*(1.-1.666667*x));
} else {
res = G4Exp(G4Log(a)*onethird);
}
res = invert ? 1./res : res;
return res;
}
// -------------------------------------------------------------------
G4double G4Pow::A13Low(const G4double a, const bool invert) const {
G4double res;
const G4int i = static_cast<G4int>(4.*(a+0.125));
const G4double y = 0.25*i;
const G4double x = (a/y-1.)*onethird;
res = lowa13[i]*(1.+x-x*x*(1.-1.666667*x));
res = invert ? 1./res : res;
return res;
}
// -------------------------------------------------------------------
G4double G4Pow::powN(G4double x, G4int n) const
{
if(0.0 == x) { return 0.0; }
@@ -37,5 +37,15 @@
#include "G4Types.hh"
#include "G4ReferenceCountedHandle.hh"
G4ThreadLocal G4Allocator<G4CountedObject<void> > *aCountedObjectAllocator = 0;
G4ThreadLocal G4Allocator<G4ReferenceCountedHandle<void> > *aRCHAllocator = 0;
G4Allocator<G4CountedObject<void>>*& aCountedObjectAllocator()
{
G4ThreadLocalStatic G4Allocator<G4CountedObject<void>>* _instance = nullptr;
return _instance;
}
G4Allocator<G4ReferenceCountedHandle<void>>*& aRCHAllocator()
{
G4ThreadLocalStatic G4Allocator<G4ReferenceCountedHandle<void>>*
_instance = nullptr;
return _instance;
}
+1 -3
View File
@@ -24,7 +24,7 @@
// ********************************************************************
//
//
// $Id: G4SliceTimer.cc 67970 2013-03-13 10:10:06Z gcosmo $
// $Id: G4SliceTimer.cc 110674 2018-06-07 10:30:11Z gcosmo $
//
//
// ----------------------------------------------------------------------
@@ -36,8 +36,6 @@
#include "G4SliceTimer.hh"
#include "G4ios.hh"
#undef times
#if defined(IRIX6_2)
# if defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE_EXTENDED==1)
# define __vfork vfork
@@ -24,7 +24,7 @@
// ********************************************************************
//
//
// $Id: G4StateManager.cc 108486 2018-02-15 14:47:25Z gcosmo $
// $Id: G4StateManager.cc 108402 2018-02-12 10:31:27Z gcosmo $
//
//
// ------------------------------------------------------------
+33 -49
View File
@@ -58,31 +58,14 @@ namespace
}
G4Pid_t G4Threading::G4GetPidId()
{ // In multithreaded mode return Thread ID
#if defined(__MACH__)
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_12
uint64_t tid64;
pthread_threadid_np(NULL, &tid64);
return (pid_t)tid64;
#else
return syscall(SYS_thread_selfid);
#endif
#elif defined(WIN32)
return GetCurrentThreadId();
#else
return syscall(SYS_gettid);
#endif
{
// In multithreaded mode return Thread ID
return std::this_thread::get_id();
}
G4int G4Threading::G4GetNumberOfCores()
{
#if defined(WIN32)
SYSTEM_INFO sysinfo;
GetSystemInfo( &sysinfo );
return static_cast<G4int>( sysinfo.dwNumberOfProcessors );
#else
return static_cast<G4int>(sysconf( _SC_NPROCESSORS_ONLN ));
#endif
return std::thread::hardware_concurrency();
}
void G4Threading::G4SetThreadId(G4int value ) { G4ThreadID = value; }
@@ -90,38 +73,40 @@ G4int G4Threading::G4GetThreadId() { return G4ThreadID; }
G4bool G4Threading::IsWorkerThread() { return (G4ThreadID>=0); }
G4bool G4Threading::IsMasterThread() { return (G4ThreadID==MASTER_ID); }
#if defined(WIN32) // WIN32 stuff needed for MT
DWORD /*WINAPI*/ G4WaitForSingleObjectInf( __in G4Mutex m )
{ return WaitForSingleObject( m , INFINITE); }
BOOL G4ReleaseMutex( __in G4Mutex m)
{ return ReleaseMutex(m); }
#endif
#if defined(__linux__) || defined(_AIX)
G4bool G4Threading::G4SetPinAffinity(G4int cpu, G4Thread& aT)
G4bool G4Threading::G4SetPinAffinity(G4int cpu, G4NativeThread& aT)
{
cpu_set_t* aset = new cpu_set_t;
G4AutoDelete::Register(aset);
CPU_ZERO(aset);
CPU_SET(cpu,aset);
return ( pthread_setaffinity_np(aT, sizeof(cpu_set_t), aset) == 0 );
cpu_set_t* aset = new cpu_set_t;
G4AutoDelete::Register(aset);
CPU_ZERO(aset);
CPU_SET(cpu, aset);
pthread_t& _aT = (pthread_t&) (aT);
return (pthread_setaffinity_np(_aT, sizeof(cpu_set_t), aset) == 0);
}
#else //Not available for Mac, WIN,...
G4bool G4Threading::G4SetPinAffinity(G4int, G4Thread&)
G4bool G4Threading::G4SetPinAffinity(G4int, G4NativeThread&)
{
G4Exception("G4Threading::G4SetPinAffinity()",
"NotImplemented", JustWarning,
"Affinity setting not available for this architecture, ignoring...");
return true;
G4Exception("G4Threading::G4SetPinAffinity()",
"NotImplemented", JustWarning,
"Affinity setting not available for this architecture, "
"ignoring...");
return true;
}
#endif
void G4Threading::SetMultithreadedApplication(G4bool value ) { isMTAppType = value; }
G4bool G4Threading::IsMultithreadedApplication() { return isMTAppType; }
void G4Threading::SetMultithreadedApplication(G4bool value)
{
isMTAppType = value;
}
G4bool G4Threading::IsMultithreadedApplication()
{
return isMTAppType;
}
namespace
{
std::atomic_int numActThreads(0);
std::atomic_int numActThreads(0);
}
int G4Threading::WorkerThreadLeavesPool() { return numActThreads--; }
int G4Threading::WorkerThreadJoinsPool() { return numActThreads++;}
@@ -129,15 +114,14 @@ G4int G4Threading::GetNumberOfRunningWorkerThreads() { return numActThreads.load
#else // Sequential mode
G4int fake_mutex_lock_unlock( G4Mutex* ) { return 0; }
G4Pid_t G4Threading::G4GetPidId()
{ // In sequential mode return Process ID and not Thread ID
#if defined(WIN32)
{
// In sequential mode return Process ID and not Thread ID
#if defined(WIN32)
return GetCurrentProcessId();
#else
#else
return getpid();
#endif
#endif
}
G4int G4Threading::G4GetNumberOfCores() { return 1; }
@@ -146,7 +130,7 @@ G4bool G4Threading::IsWorkerThread() { return false; }
G4bool G4Threading::IsMasterThread() { return true; }
void G4Threading::G4SetThreadId(G4int) {}
G4bool G4Threading::G4SetPinAffinity(G4int,G4Thread&) { return true;}
G4bool G4Threading::G4SetPinAffinity(G4int, G4NativeThread&) { return true; }
void G4Threading::SetMultithreadedApplication(G4bool) {}
G4bool G4Threading::IsMultithreadedApplication() { return false; }
+25 -10
View File
@@ -24,7 +24,7 @@
// ********************************************************************
//
//
// $Id: G4Timer.cc 67970 2013-03-13 10:10:06Z gcosmo $
// $Id: G4Timer.cc 110674 2018-06-07 10:30:11Z gcosmo $
//
//
// ----------------------------------------------------------------------
@@ -36,7 +36,7 @@
#include "G4Timer.hh"
#include "G4ios.hh"
#undef times
#include <iomanip>
// Global error function
#include "G4ExceptionSeverity.hh"
@@ -86,16 +86,31 @@ void G4Exception(const char* originOfException,
// Print timer status n std::ostream
std::ostream& operator << (std::ostream& os, const G4Timer& t)
{
// so fixed doesn't propagate
std::stringstream ss;
ss << std::fixed;
if (t.IsValid())
{
ss << "User=" << t.GetUserElapsed()
<< "s Real=" << t.GetRealElapsed()
<< "s Sys=" << t.GetSystemElapsed() << "s";
#ifdef G4MULTITHREADED
// avoid possible FPE error
if(t.GetRealElapsed() > 1.0e-6)
{
os << "User=" << t.GetUserElapsed()
<< "s Real=" << t.GetRealElapsed()
<< "s Sys=" << t.GetSystemElapsed() << "s";
double cpu_util = (t.GetUserElapsed()+t.GetRealElapsed()) /
t.GetRealElapsed() * 100.0;
ss << std::setprecision(1);
ss << " [Cpu=" << std::setprecision(1) << cpu_util << "%]";
}
#endif
}
else
{
os << "User=****s Real=****s Sys=****s";
}
{
ss << "User=****s Real=****s Sys=****s";
}
os << ss.str();
return os;
}
@@ -111,8 +126,8 @@ G4double G4Timer::GetRealElapsed() const
G4Exception("G4Timer::GetRealElapsed()", "InvalidCondition",
FatalException, "Timer not stopped or times not recorded!");
}
G4double diff=fEndRealTime-fStartRealTime;
return diff/sysconf(_SC_CLK_TCK);
std::chrono::duration<double> diff=fEndRealTime-fStartRealTime;
return diff.count();
}
+56 -34
View File
@@ -24,7 +24,7 @@
// ********************************************************************
//
//
// $Id: G4ios.cc 78780 2014-01-23 13:55:15Z gcosmo $
// $Id: G4ios.cc 110251 2018-05-17 14:09:28Z gcosmo $
//
//
// --------------------------------------------------------------
@@ -36,53 +36,75 @@
#include "G4ios.hh"
#include "G4strstreambuf.hh"
#include <iostream>
#ifdef G4MULTITHREADED
G4ThreadLocal G4strstreambuf *G4coutbuf_p = 0;
G4ThreadLocal G4strstreambuf *G4cerrbuf_p = 0;
G4ThreadLocal std::ostream *G4cout_p = 0;
G4ThreadLocal std::ostream *G4cerr_p = 0;
#define G4coutbuf (*G4coutbuf_p)
#define G4cerrbuf (*G4cerrbuf_p)
#define G4cout (*G4cout_p)
#define G4cerr (*G4cerr_p)
void G4iosInitialization()
{
if (G4coutbuf_p == 0) G4coutbuf_p = new G4strstreambuf;
if (G4cerrbuf_p == 0) G4cerrbuf_p = new G4strstreambuf;
if (G4cout_p == 0) G4cout_p = new std::ostream(G4coutbuf_p);
if (G4cerr_p == 0) G4cerr_p = new std::ostream(G4cerrbuf_p);
}
G4strstreambuf*& _G4coutbuf_p()
{
G4ThreadLocalStatic G4strstreambuf* _instance = new G4strstreambuf();
return _instance;
}
void G4iosFinalization()
{
delete G4cout_p; G4cout_p = 0;
delete G4cerr_p; G4cerr_p = 0;
delete G4coutbuf_p; G4coutbuf_p = 0;
delete G4cerrbuf_p; G4cerrbuf_p = 0;
}
G4strstreambuf*& _G4cerrbuf_p()
{
G4ThreadLocalStatic G4strstreambuf* _instance = new G4strstreambuf();
return _instance;
}
// These two functions are guaranteed to be called at load and
// unload of the library containing this code.
namespace
{
std::ostream*& _G4cout_p()
{
G4ThreadLocalStatic std::ostream* _instance = new std::ostream(_G4coutbuf_p());
return _instance;
}
std::ostream*& _G4cerr_p()
{
G4ThreadLocalStatic std::ostream* _instance = new std::ostream(_G4cerrbuf_p());
return _instance;
}
#define G4coutbuf (*_G4coutbuf_p())
#define G4cerrbuf (*_G4cerrbuf_p())
#define G4cout (*_G4cout_p())
#define G4cerr (*_G4cerr_p())
void G4iosInitialization()
{
if (_G4coutbuf_p() == 0) _G4coutbuf_p() = new G4strstreambuf;
if (_G4cerrbuf_p() == 0) _G4cerrbuf_p() = new G4strstreambuf;
if (_G4cout_p() == &std::cout || _G4cout_p() == 0) _G4cout_p() = new std::ostream(_G4coutbuf_p());
if (_G4cerr_p() == &std::cerr || _G4cerr_p() == 0) _G4cerr_p() = new std::ostream(_G4cerrbuf_p());
}
void G4iosFinalization()
{
delete _G4cout_p(); _G4cout_p() = &std::cout;
delete _G4cerr_p(); _G4cerr_p() = &std::cerr;
delete _G4coutbuf_p(); _G4coutbuf_p() = nullptr;
delete _G4cerrbuf_p(); _G4cerrbuf_p() = nullptr;
}
// These two functions are guaranteed to be called at load and
// unload of the library containing this code.
namespace
{
#ifndef WIN32
void setupG4ioSystem(void) __attribute__ ((constructor));
void cleanupG4ioSystem(void) __attribute__((destructor));
#endif
void setupG4ioSystem(void) { G4iosInitialization(); }
void cleanupG4ioSystem(void) { G4iosFinalization(); }
}
}
#else // Sequential
G4strstreambuf G4coutbuf;
G4strstreambuf G4cerrbuf;
std::ostream G4cout(&G4coutbuf);
std::ostream G4cerr(&G4cerrbuf);
G4strstreambuf G4coutbuf;
G4strstreambuf G4cerrbuf;
std::ostream G4cout(&G4coutbuf);
std::ostream G4cerr(&G4cerrbuf);
void G4iosInitialization() {}
void G4iosFinalization() {}
void G4iosInitialization() {}
void G4iosFinalization() {}
#endif