Import Geant4 11.2.0.beta source tree

This commit is contained in:
Gabriele Cosmo
2023-06-30 09:09:57 +02:00
parent aef78ca386
commit dd1f179cda
3780 changed files with 212808 additions and 142780 deletions
+37 -54
View File
@@ -52,53 +52,47 @@
#ifndef G4VUPLSplitter_hh
#define G4VUPLSplitter_hh 1
#include <stdlib.h>
#include "G4AutoLock.hh"
#include "globals.hh"
#include "rundefs.hh"
template <class T> // T is the private data from the object to be split
#include "rundefs.hh"
#include <stdlib.h>
template<class T> // T is the private data from the object to be split
class G4VUPLSplitter
{
public:
G4VUPLSplitter() { G4MUTEXINIT(mutex); }
G4VUPLSplitter()
{
G4MUTEXINIT(mutex);
}
// Invoked by the master thread to create a new subinstance
// whenever a new split class instance is created.
// This is called by constructor of shared classes,
// thus only master thread calls this
G4int CreateSubInstance()
// Invoked by the master thread to create a new subinstance
// whenever a new split class instance is created.
// This is called by constructor of shared classes,
// thus only master thread calls this
{
G4AutoLock l(&mutex);
// One more instance
++totalobj;
// If the number of objects is larger than the available spaces,
// a re-allocation is needed
if(totalobj > workertotalspace)
{
if (totalobj > workertotalspace) {
l.unlock();
NewSubInstances();
l.lock();
}
// Since this is called by Master thread, we can remember this
totalspace = workertotalspace;
totalspace = workertotalspace;
sharedOffset = offset;
return (totalobj - 1);
}
// Invoked by each worker thread to grow the subinstance array and
// initialize each new subinstance using a particular method defined
// by the subclass.
void NewSubInstances()
// Invoked by each worker thread to grow the subinstance array and
// initialize each new subinstance using a particular method defined
// by the subclass.
{
G4AutoLock l(&mutex);
if(workertotalspace >= totalobj)
{
if (workertotalspace >= totalobj) {
return;
}
// Remember current large size
@@ -106,25 +100,22 @@ class G4VUPLSplitter
// Increase its size by some value (purely arbitrary)
workertotalspace = totalobj + 512;
// Now re-allocate new space
offset = (T*) realloc(offset, workertotalspace * sizeof(T));
if(offset == nullptr)
{
G4Exception("G4VUPLSplitter::NewSubInstances()", "OutOfMemory",
FatalException, "Cannot malloc space!");
offset = (T*)realloc(offset, workertotalspace * sizeof(T));
if (offset == nullptr) {
G4Exception("G4VUPLSplitter::NewSubInstances()", "OutOfMemory", FatalException,
"Cannot malloc space!");
return;
}
// The newly created objects need to be initialized
for(G4int i = originaltotalspace; i < workertotalspace; ++i)
{
for (G4int i = originaltotalspace; i < workertotalspace; ++i) {
offset[i].initialize();
}
}
void FreeWorker()
// Invoked by all threads to free the subinstance array.
void FreeWorker()
{
if(offset == nullptr)
{
if (offset == nullptr) {
return;
}
free(offset);
@@ -136,18 +127,14 @@ class G4VUPLSplitter
void UseWorkArea(T* newOffset)
{
// Use recycled work area - which was created previously
if(offset != nullptr && offset != newOffset)
{
G4Exception("G4VUPLSplitter::UseWorkspace()", "TwoWorkspaces",
FatalException,
if (offset != nullptr && offset != newOffset) {
G4Exception("G4VUPLSplitter::UseWorkspace()", "TwoWorkspaces", FatalException,
"Thread already has workspace - cannot use another.");
}
offset = newOffset;
// totalobj= numObjects;
// totalspace= numSpace;
}
T* FreeWorkArea() // G4int* numObjects, G4int* numSpace)
T* FreeWorkArea()
{
// Detach this thread from this Location
// The object which calls this method is responsible for it.
@@ -158,22 +145,20 @@ class G4VUPLSplitter
return offsetRet;
}
// Invoked by each worker thread to copy all subinstances array from
// the master thread
void WorkerCopySubInstanceArray()
// Invoked by each worker thread to copy all subinstances array from
// the master thread
{
if(offset != nullptr)
return;
if (offset != nullptr) return;
// Since this is called by worker threds, totalspace is some valid
// number > 0. Remember totalspace is the number of available slots
// from master. We are sure that it has valid data
G4AutoLock l(&mutex);
offset = (T*) realloc(offset, totalspace * sizeof(T));
if(offset == nullptr)
{
G4Exception("G4VUPLSplitter::WorkerCopySubInstanceArray()",
"OutOfMemory", FatalException, "Cannot malloc space!");
offset = (T*)realloc(offset, totalspace * sizeof(T));
if (offset == nullptr) {
G4Exception("G4VUPLSplitter::WorkerCopySubInstanceArray()", "OutOfMemory", FatalException,
"Cannot malloc space!");
return;
}
// Now just copy from master thread (sharedOffset)
@@ -181,23 +166,21 @@ class G4VUPLSplitter
}
public:
// Per-thread available number of slots
G4RUN_DLL G4ThreadLocalStatic G4int workertotalspace;
// Per-thread available number of slots
// Pointer to first instance of an array
G4RUN_DLL G4ThreadLocalStatic T* offset;
// Pointer to first instance of an array
private:
G4int totalobj = 0; // Total number of instances from master thread
G4int totalobj = 0; // Total number of instances from master thread
G4int totalspace = 0; // Available number of "slots"
T* sharedOffset = nullptr;
G4Mutex mutex;
};
template <typename T>
template<typename T>
G4ThreadLocal G4int G4VUPLSplitter<T>::workertotalspace = 0;
template <typename T>
template<typename T>
G4ThreadLocal T* G4VUPLSplitter<T>::offset = nullptr;
#endif