Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:03:05

0001 // Created by: Peter KURNEV
0002 // Copyright (c) 1999-2013 OPEN CASCADE SAS
0003 //
0004 // This file is part of Open CASCADE Technology software library.
0005 //
0006 // This library is free software; you can redistribute it and/or modify it under
0007 // the terms of the GNU Lesser General Public License version 2.1 as published
0008 // by the Free Software Foundation, with special exception defined in the file
0009 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
0010 // distribution for complete text of the license and disclaimer of any warranty.
0011 //
0012 // Alternatively, this file may be used under the terms of Open CASCADE
0013 // commercial license or contractual agreement.
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 //! Implementation of Functors/Starters
0025 class BOPTools_Parallel
0026 {
0027   template<class TypeSolverVector>
0028   class Functor
0029   {
0030   public:
0031     //! Constructor.
0032     explicit Functor(TypeSolverVector& theSolverVec) : mySolvers (theSolverVec) {}
0033 
0034     //! Defines functor interface.
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   //! Functor storing map of thread id -> algorithm context
0050   template<class TypeSolverVector, class TypeContext>
0051   class ContextFunctor
0052   {
0053   public:
0054 
0055     //! Constructor
0056     explicit ContextFunctor (TypeSolverVector& theVector) : mySolverVector(theVector) {}
0057 
0058     //! Binds main thread context
0059     void SetContext (const opencascade::handle<TypeContext>& theContext)
0060     {
0061       myContextMap.Bind (OSD_Thread::Current(), theContext);
0062     }
0063 
0064     //! Returns current thread context
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       // Create new context
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     //! Defines functor interface
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   //! Functor storing array of algorithm contexts per thread in pool
0105   template<class TypeSolverVector, class TypeContext>
0106   class ContextFunctor2
0107   {
0108   public:
0109 
0110     //! Constructor
0111     explicit ContextFunctor2 (TypeSolverVector& theVector, const OSD_ThreadPool::Launcher& thePoolLauncher)
0112     : mySolverVector(theVector),
0113       myContextArray (thePoolLauncher.LowerThreadIndex(), thePoolLauncher.UpperThreadIndex()) {}
0114 
0115     //! Binds main thread context
0116     void SetContext (const opencascade::handle<TypeContext>& theContext)
0117     {
0118       myContextArray.ChangeLast() = theContext; // OSD_ThreadPool::Launcher::UpperThreadIndex() is reserved for a main thread
0119     }
0120 
0121     //! Defines functor interface with serialized thread index.
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   //! Pure version
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   //! Context dependent version
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