Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-25 09:21:07

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 <Select3D_SensitiveEntity.hxx>
0020 #include <Standard_Condition.hxx>
0021 #include <Message_Messenger.hxx>
0022 
0023 #include <mutex>
0024 
0025 //! Class defining a thread pool for building BVH for the list of Select3D_SensitiveEntity within
0026 //! background thread(s).
0027 class SelectMgr_BVHThreadPool : public Standard_Transient
0028 {
0029   DEFINE_STANDARD_RTTIEXT(SelectMgr_BVHThreadPool, Standard_Transient)
0030 public:
0031   //! Main constructor
0032   Standard_EXPORT SelectMgr_BVHThreadPool(int theNbThreads);
0033 
0034   //! Destructor
0035   Standard_EXPORT ~SelectMgr_BVHThreadPool() override;
0036 
0037 public:
0038   //! Thread with back reference to thread pool and thread mutex in it.
0039   class BVHThread : public OSD_Thread
0040   {
0041     friend class SelectMgr_BVHThreadPool;
0042 
0043   public:
0044     BVHThread()
0045         : myPool(nullptr),
0046 
0047           myToCatchFpe(false)
0048     {
0049     }
0050 
0051     BVHThread(const BVHThread& theOther)
0052         : OSD_Thread(theOther),
0053           myPool(theOther.myPool),
0054 
0055           myToCatchFpe(theOther.myToCatchFpe)
0056     {
0057     }
0058 
0059     //! Returns mutex used for BVH building
0060     std::mutex& BVHMutex() { return myMutex; }
0061 
0062     //! Assignment operator.
0063     BVHThread& operator=(const BVHThread& theCopy)
0064     {
0065       Assign(theCopy);
0066       return *this;
0067     }
0068 
0069     //! Assignment operator.
0070     void Assign(const BVHThread& theCopy)
0071     {
0072       OSD_Thread::Assign(theCopy);
0073       myPool       = theCopy.myPool;
0074       myToCatchFpe = theCopy.myToCatchFpe;
0075     }
0076 
0077   private:
0078     //! Method is executed in the context of thread.
0079     void performThread();
0080 
0081     //! Method is executed in the context of thread.
0082     static void* runThread(void* theTask);
0083 
0084   private:
0085     SelectMgr_BVHThreadPool* myPool;
0086     std::mutex               myMutex;
0087     bool                     myToCatchFpe;
0088   };
0089 
0090 public:
0091   //! Queue a sensitive entity to build its BVH
0092   Standard_EXPORT void AddEntity(const occ::handle<Select3D_SensitiveEntity>& theEntity);
0093 
0094   //! Stops threads
0095   Standard_EXPORT void StopThreads();
0096 
0097   //! Waits for all threads finish their jobs
0098   Standard_EXPORT void WaitThreads();
0099 
0100   //! Returns array of threads
0101   NCollection_Array1<BVHThread>& Threads() { return myBVHThreads; }
0102 
0103 public:
0104   //! Class providing a simple interface to mutexes for list of BVHThread
0105   class Sentry
0106   {
0107   public:
0108     //! Constructor - initializes the sentry object and locks list of mutexes immediately
0109     Sentry(const occ::handle<SelectMgr_BVHThreadPool>& thePool)
0110         : myPool(thePool)
0111     {
0112       Lock();
0113     }
0114 
0115     //! Destructor - unlocks list of mutexes if already locked.
0116     ~Sentry() { Unlock(); }
0117 
0118     //! Lock list of mutexes
0119     void Lock()
0120     {
0121       if (!myPool.IsNull())
0122       {
0123         for (int i = myPool->Threads().Lower(); i <= myPool->Threads().Upper(); ++i)
0124         {
0125           myPool->Threads().ChangeValue(i).BVHMutex().lock();
0126         }
0127       }
0128     }
0129 
0130     //! Unlock list of mutexes
0131     void Unlock()
0132     {
0133       if (!myPool.IsNull())
0134       {
0135         for (int i = myPool->Threads().Lower(); i <= myPool->Threads().Upper(); ++i)
0136         {
0137           myPool->Threads().ChangeValue(i).BVHMutex().unlock();
0138         }
0139       }
0140     }
0141 
0142     //! This method should not be called (prohibited).
0143     Sentry(const Sentry&);
0144     //! This method should not be called (prohibited).
0145     Sentry& operator=(const Sentry&);
0146 
0147   private:
0148     occ::handle<SelectMgr_BVHThreadPool> myPool;
0149   };
0150 
0151 protected:
0152   // clang-format off
0153   NCollection_List<occ::handle<Select3D_SensitiveEntity>> myBVHToBuildList; //!< list of queued sensitive entities
0154   NCollection_Array1<BVHThread> myBVHThreads;                          //!< threads to build BVH
0155   bool myToStopBVHThread;                                  //!< flag to stop BVH threads
0156   std::mutex myBVHListMutex;                                           //!< mutex for interaction with myBVHToBuildList
0157   Standard_Condition myWakeEvent;                                      //!< raises when any sensitive is added to the BVH list
0158   Standard_Condition myIdleEvent;                                      //!< raises when BVH list become empty
0159   bool myIsStarted;                                        //!< indicates that threads are running
0160   // clang-format on
0161 };
0162 
0163 #endif