Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-16 09:16:46

0001 // Created on: 2015-05-28
0002 // Created by: Denis BOGOLEPOV
0003 // Copyright (c) 2015 OPEN CASCADE SAS
0004 //
0005 // This file is part of Open CASCADE Technology software library.
0006 //
0007 // This library is free software; you can redistribute it and/or modify it under
0008 // the terms of the GNU Lesser General Public License version 2.1 as published
0009 // by the Free Software Foundation, with special exception defined in the file
0010 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
0011 // distribution for complete text of the license and disclaimer of any warranty.
0012 //
0013 // Alternatively, this file may be used under the terms of Open CASCADE
0014 // commercial license or contractual agreement.
0015 
0016 #ifndef _BVH_BuildQueue_Header
0017 #define _BVH_BuildQueue_Header
0018 
0019 #include <BVH_Builder.hxx>
0020 
0021 #include <NCollection_Sequence.hxx>
0022 
0023 #include <atomic>
0024 #include <mutex>
0025 
0026 //! Command-queue for parallel building of BVH nodes.
0027 class BVH_BuildQueue
0028 {
0029   template <class T, int N>
0030   friend class BVH_QueueBuilder;
0031 
0032 public:
0033   //! Creates new BVH build queue.
0034   BVH_BuildQueue()
0035       : myNbThreads(0),
0036         mySize(0)
0037   {
0038   }
0039 
0040   //! Releases resources of BVH build queue.
0041   ~BVH_BuildQueue() = default;
0042 
0043 public:
0044   //! Returns current size of BVH build queue.
0045   //! Uses acquire semantics to synchronize with enqueue/dequeue operations.
0046   int Size() const { return mySize.load(std::memory_order_acquire); }
0047 
0048   //! Enqueues new work-item onto BVH build queue.
0049   void Enqueue(const int theWorkItem)
0050   {
0051     std::lock_guard<std::mutex> aLock(myMutex);
0052     myQueue.Append(theWorkItem);
0053     mySize.fetch_add(1, std::memory_order_release);
0054   }
0055 
0056   //! Fetches first work-item from BVH build queue.
0057   int Fetch(bool& wasBusy)
0058   {
0059     int aQuery = -1;
0060 
0061     // Fetch item from queue under lock
0062     {
0063       std::lock_guard<std::mutex> aLock(myMutex);
0064       if (!myQueue.IsEmpty())
0065       {
0066         aQuery = myQueue.First();
0067         myQueue.Remove(1);
0068         mySize.fetch_sub(1, std::memory_order_release);
0069       }
0070     }
0071 
0072     // Update thread counter atomically with release/acquire semantics
0073     // to ensure proper synchronization with HasBusyThreads()
0074     if (aQuery != -1)
0075     {
0076       if (!wasBusy)
0077       {
0078         myNbThreads.fetch_add(1, std::memory_order_release);
0079       }
0080     }
0081     else if (wasBusy)
0082     {
0083       myNbThreads.fetch_sub(1, std::memory_order_release);
0084     }
0085 
0086     wasBusy = (aQuery != -1);
0087     return aQuery;
0088   }
0089 
0090   //! Checks if there are active build threads.
0091   //! Uses acquire semantics to ensure visibility of thread counter updates.
0092   //! This is critical for termination detection: threads check this after
0093   //! finding an empty queue to determine if they should exit or wait.
0094   bool HasBusyThreads() const { return myNbThreads.load(std::memory_order_acquire) != 0; }
0095 
0096 private:
0097   //! Queue of BVH nodes to build.
0098   NCollection_Sequence<int> myQueue;
0099 
0100   //! Manages access serialization for queue operations.
0101   std::mutex myMutex;
0102 
0103   //! Number of active build threads (atomic for lock-free reads).
0104   std::atomic<int> myNbThreads;
0105 
0106   //! Current queue size (atomic for lock-free reads).
0107   std::atomic<int> mySize;
0108 };
0109 
0110 #endif // _BVH_BuildQueue_Header