Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:04:53

0001 // Copyright (c) 2020 OPEN CASCADE SAS
0002 //
0003 // This file is part of Open CASCADE Technology software library.
0004 //
0005 // This library is free software; you can redistribute it and/or modify it under
0006 // the terms of the GNU Lesser General Public License version 2.1 as published
0007 // by the Free Software Foundation, with special exception defined in the file
0008 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
0009 // distribution for complete text of the license and disclaimer of any warranty.
0010 //
0011 // Alternatively, this file may be used under the terms of Open CASCADE
0012 // commercial license or contractual agreement.
0013 
0014 #ifndef _SelectMgr_BVHThreadPool_HeaderFile
0015 #define _SelectMgr_BVHThreadPool_HeaderFile
0016 
0017 #include <Standard_Transient.hxx>
0018 #include <OSD_Thread.hxx>
0019 #include <Standard_Mutex.hxx>
0020 #include <Select3D_SensitiveEntity.hxx>
0021 #include <Standard_Condition.hxx>
0022 #include <Message_Messenger.hxx>
0023 
0024 //! Class defining a thread pool for building BVH for the list of Select3D_SensitiveEntity within background thread(s).
0025 class SelectMgr_BVHThreadPool : public Standard_Transient
0026 {
0027   DEFINE_STANDARD_RTTIEXT(SelectMgr_BVHThreadPool, Standard_Transient)
0028 public:
0029   //! Main constructor
0030   Standard_EXPORT SelectMgr_BVHThreadPool (Standard_Integer theNbThreads);
0031 
0032   //! Destructor
0033   Standard_EXPORT virtual ~SelectMgr_BVHThreadPool();
0034 
0035 public:
0036 
0037   //! Thread with back reference to thread pool and thread mutex in it.
0038   class BVHThread : public OSD_Thread
0039   {
0040     friend class SelectMgr_BVHThreadPool;
0041   public:
0042 
0043     BVHThread()
0044       : OSD_Thread(),
0045       myPool(nullptr),
0046       myMutex(),
0047       myToCatchFpe (Standard_False)
0048     {}
0049 
0050 
0051     BVHThread(const BVHThread& theOther)
0052       : OSD_Thread(theOther),
0053       myPool(theOther.myPool),
0054       myMutex(),
0055       myToCatchFpe(theOther.myToCatchFpe)
0056     {}
0057 
0058     //! Returns mutex used for BVH building
0059     Standard_Mutex& BVHMutex()
0060     {
0061       return myMutex;
0062     }
0063 
0064     //! Assignment operator.
0065     BVHThread& operator= (const BVHThread& theCopy)
0066     {
0067       Assign (theCopy);
0068       return *this;
0069     }
0070 
0071     //! Assignment operator.
0072     void Assign (const BVHThread& theCopy)
0073     {
0074       OSD_Thread::Assign (theCopy);
0075       myPool = theCopy.myPool;
0076       myToCatchFpe = theCopy.myToCatchFpe;
0077     }
0078 
0079   private:
0080     //! Method is executed in the context of thread.
0081     void performThread();
0082 
0083     //! Method is executed in the context of thread.
0084     static Standard_Address runThread (Standard_Address theTask);
0085 
0086   private:
0087 
0088     SelectMgr_BVHThreadPool* myPool;
0089     Standard_Mutex myMutex;
0090     bool myToCatchFpe;
0091   };
0092 
0093 public:
0094   //! Queue a sensitive entity to build its BVH
0095   Standard_EXPORT void AddEntity (const Handle(Select3D_SensitiveEntity)& theEntity);
0096 
0097   //! Stops threads
0098   Standard_EXPORT void StopThreads();
0099 
0100   //! Waits for all threads finish their jobs
0101   Standard_EXPORT void WaitThreads();
0102 
0103   //! Returns array of threads
0104   NCollection_Array1<BVHThread>& Threads()
0105   {
0106     return myBVHThreads;
0107   }
0108 
0109 public:
0110 
0111   //! Class providing a simple interface to mutexes for list of BVHThread
0112   class Sentry 
0113   {
0114   public:
0115 
0116     //! Constructor - initializes the sentry object and locks list of mutexes immediately
0117     Sentry (const Handle(SelectMgr_BVHThreadPool)& thePool)
0118     : myPool (thePool)
0119     {
0120       Lock();
0121     }
0122     
0123     //! Destructor - unlocks list of mutexes if already locked.
0124     ~Sentry()
0125     {
0126         Unlock();
0127     }
0128 
0129     //! Lock list of mutexes
0130     void Lock()
0131     {
0132       if (!myPool.IsNull())
0133       {
0134         for (Standard_Integer i = myPool->Threads().Lower(); i <= myPool->Threads().Upper(); ++i)
0135         {
0136           myPool->Threads().ChangeValue(i).BVHMutex().Lock();
0137         }
0138       }
0139     }
0140 
0141     //! Unlock list of mutexes
0142     void Unlock()
0143     {
0144       if (!myPool.IsNull())
0145       {
0146         for (Standard_Integer i = myPool->Threads().Lower(); i <= myPool->Threads().Upper(); ++i)
0147         {
0148           myPool->Threads().ChangeValue(i).BVHMutex().Unlock();
0149         }
0150       }
0151     }
0152 
0153     //! This method should not be called (prohibited).
0154     Sentry (const Sentry &);
0155     //! This method should not be called (prohibited).
0156     Sentry& operator = (const Sentry &);
0157 
0158   private:
0159     Handle(SelectMgr_BVHThreadPool) myPool;
0160   };
0161 
0162 protected:
0163 
0164   NCollection_List<Handle(Select3D_SensitiveEntity)> myBVHToBuildList; //!< list of queued sensitive entities
0165   NCollection_Array1<BVHThread> myBVHThreads;                          //!< threads to build BVH
0166   Standard_Boolean myToStopBVHThread;                                  //!< flag to stop BVH threads
0167   Standard_Mutex myBVHListMutex;                                       //!< mutex for interaction with myBVHToBuildList
0168   Standard_Condition myWakeEvent;                                      //!< raises when any sensitive is added to the BVH list
0169   Standard_Condition myIdleEvent;                                      //!< raises when BVH list become empty
0170   Standard_Boolean myIsStarted;                                        //!< indicates that threads are running
0171 };
0172 
0173 #endif