From 207b89891f188a48d0d791907a4cd5c5618a0625 Mon Sep 17 00:00:00 2001
From: Ivana Hrivnacova <ihrivnac@mail.cern.ch>
Date: Thu, 22 Mar 2012 16:11:34 +0000
Subject: [PATCH] Modifications in vmc for multi-threading: Making TVirtualMC
 and TVirtualMCApplication instances thread local; behind #if
 defined(__linux__) && !defined(__CINT__)

git-svn-id: http://root.cern.ch/svn/root/trunk@43453 27541ba8-7e3a-0410-8455-c3a389f83636
---
 montecarlo/vmc/inc/TVirtualMC.h              | 28 +++++++++++++++++---
 montecarlo/vmc/inc/TVirtualMCApplication.h   | 10 ++++++-
 montecarlo/vmc/src/TVirtualMC.cxx            |  5 ++++
 montecarlo/vmc/src/TVirtualMCApplication.cxx |  4 +++
 4 files changed, 42 insertions(+), 5 deletions(-)

diff --git a/montecarlo/vmc/inc/TVirtualMC.h b/montecarlo/vmc/inc/TVirtualMC.h
index 7658acb747e..e7135d8930b 100644
--- a/montecarlo/vmc/inc/TVirtualMC.h
+++ b/montecarlo/vmc/inc/TVirtualMC.h
@@ -32,6 +32,10 @@
 #include "TString.h"
 #include "TError.h"
 
+#if defined(__linux__) && !defined(__CINT__)
+#include <pthread.h>
+#endif
+
 class TLorentzVector;
 class TGeoHMatrix;
 class TArrayI;
@@ -479,7 +483,7 @@ public:
    virtual Bool_t   DefineParticle(Int_t pdg, const char* name,
                         TMCParticleType mcType, 
                         Double_t mass, Double_t charge, Double_t lifetime) = 0;
-                        
+
    // Set a user defined particle
    // Function is ignored if particle with specified pdg
    // already exists and error report is printed.
@@ -797,7 +801,10 @@ public:
    // Initialize MC
    virtual void Init() = 0;
 
-   // Initialize MC physics
+    // Initialize MC in a multi-threaded application
+   virtual void InitMT(Int_t threadRank);
+
+  // Initialize MC physics
    virtual void BuildPhysics() = 0;
 
    // Process one event
@@ -860,7 +867,11 @@ private:
    TVirtualMC(const TVirtualMC &mc);
    TVirtualMC & operator=(const TVirtualMC &);
 
-   static TVirtualMC*  fgMC;     // Monte Carlo singleton instance
+#if defined(__linux__) && !defined(__CINT__)
+   static __thread TVirtualMC*  fgMC; // Monte Carlo singleton instance
+#else
+   static          TVirtualMC*  fgMC; // Monte Carlo singleton instance
+#endif
 
    TVirtualMCStack*    fStack;   //! Particles stack
    TVirtualMCDecayer*  fDecayer; //! External decayer
@@ -889,7 +900,16 @@ inline Bool_t TVirtualMC::GetMaterial(Int_t /*imat*/, TString& /*name*/,
    return kFALSE;           
 }
 
-R__EXTERN TVirtualMC *gMC;
+inline void TVirtualMC::InitMT(Int_t /*threadRank*/) {
+   // Initialize MC in a multi-threaded application
+   Warning("InitMT(Int_t threadRank)", "New function - not yet implemented.");
+}
+
+#if defined(__linux__) && !defined(__CINT__)
+R__EXTERN __thread TVirtualMC *gMC;
+#else
+R__EXTERN          TVirtualMC *gMC;
+#endif
 
 #endif //ROOT_TVirtualMC
 
diff --git a/montecarlo/vmc/inc/TVirtualMCApplication.h b/montecarlo/vmc/inc/TVirtualMCApplication.h
index 685855a2aaf..9d12b5a3cd4 100644
--- a/montecarlo/vmc/inc/TVirtualMCApplication.h
+++ b/montecarlo/vmc/inc/TVirtualMCApplication.h
@@ -25,6 +25,10 @@
 #include "TMath.h"
 #endif
 
+#if defined(__linux__) && !defined(__CINT__)
+#include <pthread.h>
+#endif
+
 class TVirtualMCApplication : public TNamed {
 
 public:
@@ -101,7 +105,11 @@ public:
 
 private:
    // static data members
-   static TVirtualMCApplication* fgInstance; // singleton instance
+#if defined(__linux__) && !defined(__CINT__)
+   static __thread TVirtualMCApplication* fgInstance; // singleton instance
+#else
+   static          TVirtualMCApplication* fgInstance; // singleton instance
+#endif
 
    ClassDef(TVirtualMCApplication,1)  //Interface to MonteCarlo application
 };
diff --git a/montecarlo/vmc/src/TVirtualMC.cxx b/montecarlo/vmc/src/TVirtualMC.cxx
index 04e826936c1..576ac169438 100644
--- a/montecarlo/vmc/src/TVirtualMC.cxx
+++ b/montecarlo/vmc/src/TVirtualMC.cxx
@@ -26,8 +26,13 @@
 
 ClassImp(TVirtualMC)
 
+#if defined(__linux__) && !defined(__CINT__)
+__thread TVirtualMC* TVirtualMC::fgMC=0;
+__thread TVirtualMC* gMC;
+#else
 TVirtualMC* TVirtualMC::fgMC=0;
 TVirtualMC* gMC;
+#endif
 
 //_____________________________________________________________________________
 TVirtualMC::TVirtualMC(const char *name, const char *title,
diff --git a/montecarlo/vmc/src/TVirtualMCApplication.cxx b/montecarlo/vmc/src/TVirtualMCApplication.cxx
index dd5c3c4e643..0556c06dd07 100644
--- a/montecarlo/vmc/src/TVirtualMCApplication.cxx
+++ b/montecarlo/vmc/src/TVirtualMCApplication.cxx
@@ -20,7 +20,11 @@
 
 ClassImp(TVirtualMCApplication)
 
+#if defined(__linux__) && !defined(__CINT__)
+__thread TVirtualMCApplication* TVirtualMCApplication::fgInstance = 0;
+#else
 TVirtualMCApplication* TVirtualMCApplication::fgInstance = 0;
+#endif
 
 //_____________________________________________________________________________
 TVirtualMCApplication::TVirtualMCApplication(const char *name,
-- 
GitLab