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