File indexing completed on 2025-01-18 10:03:05
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #ifndef _BOPTools_Parallel_HeaderFile
0016 #define _BOPTools_Parallel_HeaderFile
0017
0018 #include <OSD_Parallel.hxx>
0019 #include <OSD_ThreadPool.hxx>
0020 #include <NCollection_DataMap.hxx>
0021 #include <Standard_Mutex.hxx>
0022 #include <OSD_Thread.hxx>
0023
0024
0025 class BOPTools_Parallel
0026 {
0027 template<class TypeSolverVector>
0028 class Functor
0029 {
0030 public:
0031
0032 explicit Functor(TypeSolverVector& theSolverVec) : mySolvers (theSolverVec) {}
0033
0034
0035 void operator() (const Standard_Integer theIndex) const
0036 {
0037 typename TypeSolverVector::value_type& aSolver = mySolvers[theIndex];
0038 aSolver.Perform();
0039 }
0040
0041 private:
0042 Functor(const Functor&);
0043 Functor& operator= (const Functor&);
0044
0045 private:
0046 TypeSolverVector& mySolvers;
0047 };
0048
0049
0050 template<class TypeSolverVector, class TypeContext>
0051 class ContextFunctor
0052 {
0053 public:
0054
0055
0056 explicit ContextFunctor (TypeSolverVector& theVector) : mySolverVector(theVector) {}
0057
0058
0059 void SetContext (const opencascade::handle<TypeContext>& theContext)
0060 {
0061 myContextMap.Bind (OSD_Thread::Current(), theContext);
0062 }
0063
0064
0065 const opencascade::handle<TypeContext>& GetThreadContext() const
0066 {
0067 const Standard_ThreadId aThreadID = OSD_Thread::Current();
0068 if (const opencascade::handle<TypeContext>* aContextPtr = myContextMap.Seek (aThreadID))
0069 {
0070 if (!aContextPtr->IsNull())
0071 {
0072 return *aContextPtr;
0073 }
0074 }
0075
0076
0077 opencascade::handle<TypeContext> aContext = new TypeContext (NCollection_BaseAllocator::CommonBaseAllocator());
0078
0079 Standard_Mutex::Sentry aLocker (myMutex);
0080 myContextMap.Bind (aThreadID, aContext);
0081 return myContextMap (aThreadID);
0082 }
0083
0084
0085 void operator()( const Standard_Integer theIndex ) const
0086 {
0087 const opencascade::handle<TypeContext>& aContext = GetThreadContext();
0088 typename TypeSolverVector::value_type& aSolver = mySolverVector[theIndex];
0089
0090 aSolver.SetContext(aContext);
0091 aSolver.Perform();
0092 }
0093
0094 private:
0095 ContextFunctor(const ContextFunctor&);
0096 ContextFunctor& operator= (const ContextFunctor&);
0097
0098 private:
0099 TypeSolverVector& mySolverVector;
0100 mutable NCollection_DataMap<Standard_ThreadId, opencascade::handle<TypeContext>> myContextMap;
0101 mutable Standard_Mutex myMutex;
0102 };
0103
0104
0105 template<class TypeSolverVector, class TypeContext>
0106 class ContextFunctor2
0107 {
0108 public:
0109
0110
0111 explicit ContextFunctor2 (TypeSolverVector& theVector, const OSD_ThreadPool::Launcher& thePoolLauncher)
0112 : mySolverVector(theVector),
0113 myContextArray (thePoolLauncher.LowerThreadIndex(), thePoolLauncher.UpperThreadIndex()) {}
0114
0115
0116 void SetContext (const opencascade::handle<TypeContext>& theContext)
0117 {
0118 myContextArray.ChangeLast() = theContext;
0119 }
0120
0121
0122 void operator() (int theThreadIndex,
0123 int theIndex) const
0124 {
0125 opencascade::handle<TypeContext>& aContext = myContextArray.ChangeValue (theThreadIndex);
0126 if (aContext.IsNull())
0127 {
0128 aContext = new TypeContext (NCollection_BaseAllocator::CommonBaseAllocator());
0129 }
0130 typename TypeSolverVector::value_type& aSolver = mySolverVector[theIndex];
0131 aSolver.SetContext (aContext);
0132 aSolver.Perform();
0133 }
0134
0135 private:
0136 ContextFunctor2(const ContextFunctor2&);
0137 ContextFunctor2& operator= (const ContextFunctor2&);
0138
0139 private:
0140 TypeSolverVector& mySolverVector;
0141 mutable NCollection_Array1< opencascade::handle<TypeContext> > myContextArray;
0142 };
0143
0144 public:
0145
0146
0147 template<class TypeSolverVector>
0148 static void Perform (Standard_Boolean theIsRunParallel,
0149 TypeSolverVector& theSolverVector)
0150 {
0151 Functor<TypeSolverVector> aFunctor (theSolverVector);
0152 OSD_Parallel::For (0, theSolverVector.Length(), aFunctor, !theIsRunParallel);
0153 }
0154
0155
0156 template<class TypeSolverVector, class TypeContext>
0157 static void Perform (Standard_Boolean theIsRunParallel,
0158 TypeSolverVector& theSolverVector,
0159 opencascade::handle<TypeContext>& theContext)
0160 {
0161 if (OSD_Parallel::ToUseOcctThreads())
0162 {
0163 const Handle(OSD_ThreadPool)& aThreadPool = OSD_ThreadPool::DefaultPool();
0164 OSD_ThreadPool::Launcher aPoolLauncher (*aThreadPool, theIsRunParallel ? theSolverVector.Length() : 0);
0165 ContextFunctor2<TypeSolverVector, TypeContext> aFunctor (theSolverVector, aPoolLauncher);
0166 aFunctor.SetContext (theContext);
0167 aPoolLauncher.Perform (0, theSolverVector.Length(), aFunctor);
0168 }
0169 else
0170 {
0171 ContextFunctor<TypeSolverVector, TypeContext> aFunctor (theSolverVector);
0172 aFunctor.SetContext (theContext);
0173 OSD_Parallel::For (0, theSolverVector.Length(), aFunctor, !theIsRunParallel);
0174 }
0175 }
0176 };
0177
0178 #endif