mirror of
https://github.com/Open-Cascade-SAS/OCCT.git
synced 2026-08-15 05:09:35 +08:00
Coding - Replace Standard_Mutex with std::mutex and migrate to RAII locks (#766)
- Replace legacy Standard_Mutex usage across many modules with std::mutex. - Include <mutex> where needed and remove <Standard_Mutex.hxx> includes. - Replace Standard_Mutex::Sentry / explicit Lock/Unlock with std::lock_guard or std::unique_lock. - Convert optional/heap mutex holders to std::unique_ptr<std::mutex> and adapt locking accordingly. - Simplify several singleton initializations (remove manual double-checked locking where safe). - Use thread_local for per-thread flags instead of ad-hoc mutex protection. - Fix BVH_BuildQueue Fetch logic to preserve thread counters and wasBusy handling. - Remove obsolete TopTools_MutexForShapeProvider sources and update FILES.cmake. This modernizes mutex usage, reduces dependency on custom mutex types and improves clarity of locking patterns.
This commit is contained in:
@@ -33,6 +33,7 @@
|
||||
#include <NCollection_Vector.hxx>
|
||||
#include <TopoDS.hxx>
|
||||
#include <TopoDS_Edge.hxx>
|
||||
#include <Standard_ErrorHandler.hxx>
|
||||
#include <TopoDS_Vertex.hxx>
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include <BOPTools_Parallel.hxx>
|
||||
#include <BndLib_Add3dCurve.hxx>
|
||||
#include <BRep_Builder.hxx>
|
||||
#include <Standard_ErrorHandler.hxx>
|
||||
#include <GeomAPI_ProjectPointOnCurve.hxx>
|
||||
#include <gp_Pnt.hxx>
|
||||
#include <IntTools_CommonPrt.hxx>
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <BOPDS_VectorOfInterfVF.hxx>
|
||||
#include <BOPTools_Parallel.hxx>
|
||||
#include <IntTools_Context.hxx>
|
||||
#include <Standard_ErrorHandler.hxx>
|
||||
#include <NCollection_Vector.hxx>
|
||||
#include <TColStd_MapOfInteger.hxx>
|
||||
#include <TopoDS_Face.hxx>
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include <BOPTools_Parallel.hxx>
|
||||
#include <BRep_Builder.hxx>
|
||||
#include <BRep_Tool.hxx>
|
||||
#include <Standard_ErrorHandler.hxx>
|
||||
#include <GeomAPI_ProjectPointOnSurf.hxx>
|
||||
#include <gp_Pnt.hxx>
|
||||
#include <IntTools_CommonPrt.hxx>
|
||||
|
||||
@@ -56,6 +56,7 @@
|
||||
#include <gp_Pnt.hxx>
|
||||
#include <IntSurf_ListOfPntOn2S.hxx>
|
||||
#include <IntSurf_PntOn2S.hxx>
|
||||
#include <Standard_ErrorHandler.hxx>
|
||||
#include <IntTools.hxx>
|
||||
#include <IntTools_Context.hxx>
|
||||
#include <IntTools_Curve.hxx>
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
#include <Geom_Curve.hxx>
|
||||
#include <Geom_Plane.hxx>
|
||||
#include <Geom_RectangularTrimmedSurface.hxx>
|
||||
#include <Standard_ErrorHandler.hxx>
|
||||
#include <Geom_Surface.hxx>
|
||||
#include <GeomAPI_ProjectPointOnCurve.hxx>
|
||||
#include <GeomAPI_ProjectPointOnSurf.hxx>
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include <BOPAlgo_BuilderSolid.hxx>
|
||||
#include <BOPAlgo_MakerVolume.hxx>
|
||||
#include <BOPAlgo_Tools.hxx>
|
||||
#include <Standard_ErrorHandler.hxx>
|
||||
|
||||
#include <BOPTools_AlgoTools.hxx>
|
||||
#include <BOPTools_Parallel.hxx>
|
||||
|
||||
@@ -18,9 +18,10 @@
|
||||
#include <OSD_Parallel.hxx>
|
||||
#include <OSD_ThreadPool.hxx>
|
||||
#include <NCollection_DataMap.hxx>
|
||||
#include <Standard_Mutex.hxx>
|
||||
#include <OSD_Thread.hxx>
|
||||
|
||||
#include <mutex>
|
||||
|
||||
//! Implementation of Functors/Starters
|
||||
class BOPTools_Parallel
|
||||
{
|
||||
@@ -82,7 +83,7 @@ class BOPTools_Parallel
|
||||
opencascade::handle<TypeContext> aContext =
|
||||
new TypeContext(NCollection_BaseAllocator::CommonBaseAllocator());
|
||||
|
||||
Standard_Mutex::Sentry aLocker(myMutex);
|
||||
std::lock_guard<std::mutex> aLock(myMutex);
|
||||
myContextMap.Bind(aThreadID, aContext);
|
||||
return myContextMap(aThreadID);
|
||||
}
|
||||
@@ -104,7 +105,7 @@ class BOPTools_Parallel
|
||||
private:
|
||||
TypeSolverVector& mySolverVector;
|
||||
mutable NCollection_DataMap<Standard_ThreadId, opencascade::handle<TypeContext>> myContextMap;
|
||||
mutable Standard_Mutex myMutex;
|
||||
mutable std::mutex myMutex;
|
||||
};
|
||||
|
||||
//! Functor storing array of algorithm contexts per thread in pool
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#define _IMeshTools_ModelAlgo_HeaderFile
|
||||
|
||||
#include <Standard_Transient.hxx>
|
||||
#include <Standard_ErrorHandler.hxx>
|
||||
#include <Message_ProgressRange.hxx>
|
||||
|
||||
class IMeshData_Model;
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include <ShapeAnalysis_Curve.hxx>
|
||||
#include <ShapeAnalysis_Edge.hxx>
|
||||
#include <ShapeAnalysis_Surface.hxx>
|
||||
#include <Standard_ErrorHandler.hxx>
|
||||
#include <Geom_TrimmedCurve.hxx>
|
||||
#include <gp_Pln.hxx>
|
||||
#include <GeomAdaptor_Surface.hxx>
|
||||
|
||||
@@ -19,15 +19,23 @@
|
||||
#include <ShapeProcess_Context.hxx>
|
||||
#include <Standard_ErrorHandler.hxx>
|
||||
#include <Standard_Failure.hxx>
|
||||
#include <Standard_Mutex.hxx>
|
||||
#include <Standard_Type.hxx>
|
||||
#include <TCollection_AsciiString.hxx>
|
||||
#include <TCollection_HAsciiString.hxx>
|
||||
|
||||
#include <mutex>
|
||||
|
||||
#include <sys/stat.h>
|
||||
IMPLEMENT_STANDARD_RTTIEXT(ShapeProcess_Context, Standard_Transient)
|
||||
|
||||
static Standard_Mutex THE_SHAPE_PROCESS_MUTEX;
|
||||
namespace
|
||||
{
|
||||
static std::mutex& GetShapeProcessMutex()
|
||||
{
|
||||
static std::mutex THE_SHAPE_PROCESS_MUTEX;
|
||||
return THE_SHAPE_PROCESS_MUTEX;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
@@ -74,7 +82,7 @@ Handle(Resource_Manager) ShapeProcess_Context::LoadResourceManager(const Standar
|
||||
{
|
||||
// Mutex is needed because we are initializing and changing static variables here, so
|
||||
// without mutex it leads to race condition.
|
||||
Standard_Mutex::Sentry aLock(&THE_SHAPE_PROCESS_MUTEX);
|
||||
std::lock_guard<std::mutex> aLock(GetShapeProcessMutex());
|
||||
// Optimisation of loading resource file: file is load only once
|
||||
// and reloaded only if file date has changed
|
||||
static Handle(Resource_Manager) sRC;
|
||||
|
||||
@@ -29,7 +29,6 @@
|
||||
#include <OSD_Parallel.hxx>
|
||||
#include <Standard_ErrorHandler.hxx>
|
||||
#include <Standard_Failure.hxx>
|
||||
#include <Standard_Mutex.hxx>
|
||||
#include <Standard_NullObject.hxx>
|
||||
#include <TopExp_Explorer.hxx>
|
||||
#include <TopoDS.hxx>
|
||||
@@ -37,6 +36,8 @@
|
||||
#include <TopoDS_Shape.hxx>
|
||||
#include <TopTools_MapOfShape.hxx>
|
||||
|
||||
#include <mutex>
|
||||
|
||||
//! Functor for multi-threaded execution.
|
||||
class BRepCheck_ParallelAnalyzer
|
||||
{
|
||||
@@ -166,7 +167,10 @@ public:
|
||||
|
||||
if (performwire)
|
||||
{
|
||||
Standard_Mutex::Sentry aLock(aFaceEdgeRes->GetMutex());
|
||||
std::unique_lock<std::mutex> aLock =
|
||||
aFaceEdgeRes->GetMutex()
|
||||
? std::unique_lock<std::mutex>(*aFaceEdgeRes->GetMutex())
|
||||
: std::unique_lock<std::mutex>();
|
||||
if (aFaceEdgeRes->IsStatusOnShape(aShape))
|
||||
{
|
||||
BRepCheck_ListIteratorOfListOfStatus itl(aFaceEdgeRes->StatusOnShape(aShape));
|
||||
@@ -211,7 +215,9 @@ public:
|
||||
|
||||
if (orientofwires)
|
||||
{
|
||||
Standard_Mutex::Sentry aLock(aFaceWireRes->GetMutex());
|
||||
std::unique_lock<std::mutex> aLock =
|
||||
aFaceWireRes->GetMutex() ? std::unique_lock<std::mutex>(*aFaceWireRes->GetMutex())
|
||||
: std::unique_lock<std::mutex>();
|
||||
if (aFaceWireRes->IsStatusOnShape(aShape))
|
||||
{
|
||||
const BRepCheck_ListOfStatus& aStatusList = aFaceWireRes->StatusOnShape(aShape);
|
||||
|
||||
@@ -259,7 +259,8 @@ void BRepCheck_Edge::InContext(const TopoDS_Shape& S)
|
||||
{
|
||||
Handle(BRepCheck_HListOfStatus) aHList;
|
||||
{
|
||||
Standard_Mutex::Sentry aLock(myMutex.get());
|
||||
std::unique_lock<std::mutex> aLock =
|
||||
myMutex ? std::unique_lock<std::mutex>(*myMutex) : std::unique_lock<std::mutex>();
|
||||
if (myMap.IsBound(S))
|
||||
{
|
||||
return;
|
||||
@@ -327,7 +328,7 @@ void BRepCheck_Edge::InContext(const TopoDS_Shape& S)
|
||||
|
||||
BRep_ListIteratorOfListOfCurveRepresentation itcr(TE->Curves());
|
||||
constexpr Standard_Real eps = Precision::PConfusion();
|
||||
Standard_Boolean toRunParallel = !myMutex.IsNull();
|
||||
const Standard_Boolean toRunParallel = myMutex != nullptr;
|
||||
while (itcr.More())
|
||||
{
|
||||
const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
|
||||
@@ -571,7 +572,8 @@ Standard_Boolean BRepCheck_Edge::GeometricControls() const
|
||||
|
||||
void BRepCheck_Edge::SetStatus(const BRepCheck_Status theStatus)
|
||||
{
|
||||
Standard_Mutex::Sentry aLock(myMutex.get());
|
||||
std::unique_lock<std::mutex> aLock =
|
||||
myMutex ? std::unique_lock<std::mutex>(*myMutex) : std::unique_lock<std::mutex>();
|
||||
BRepCheck::Add(*myMap(myShape), theStatus);
|
||||
}
|
||||
|
||||
|
||||
@@ -115,7 +115,8 @@ void BRepCheck_Face::InContext(const TopoDS_Shape& S)
|
||||
{
|
||||
Handle(BRepCheck_HListOfStatus) aHList;
|
||||
{
|
||||
Standard_Mutex::Sentry aLock(myMutex.get());
|
||||
std::unique_lock<std::mutex> aLock =
|
||||
myMutex ? std::unique_lock<std::mutex>(*myMutex) : std::unique_lock<std::mutex>();
|
||||
if (myMap.IsBound(S))
|
||||
{
|
||||
return;
|
||||
@@ -163,7 +164,8 @@ BRepCheck_Status BRepCheck_Face::IntersectWires(const Standard_Boolean Update)
|
||||
{
|
||||
Handle(BRepCheck_HListOfStatus) aHList;
|
||||
{
|
||||
Standard_Mutex::Sentry aLock(myMutex.get());
|
||||
std::unique_lock<std::mutex> aLock =
|
||||
myMutex ? std::unique_lock<std::mutex>(*myMutex) : std::unique_lock<std::mutex>();
|
||||
aHList = myMap(myShape);
|
||||
}
|
||||
|
||||
@@ -292,7 +294,8 @@ BRepCheck_Status BRepCheck_Face::ClassifyWires(const Standard_Boolean Update)
|
||||
{
|
||||
Handle(BRepCheck_HListOfStatus) aHList;
|
||||
{
|
||||
Standard_Mutex::Sentry aLock(myMutex.get());
|
||||
std::unique_lock<std::mutex> aLock =
|
||||
myMutex ? std::unique_lock<std::mutex>(*myMutex) : std::unique_lock<std::mutex>();
|
||||
aHList = myMap(myShape);
|
||||
}
|
||||
|
||||
@@ -420,7 +423,8 @@ BRepCheck_Status BRepCheck_Face::OrientationOfWires(const Standard_Boolean Updat
|
||||
{
|
||||
Handle(BRepCheck_HListOfStatus) aHList;
|
||||
{
|
||||
Standard_Mutex::Sentry aLock(myMutex.get());
|
||||
std::unique_lock<std::mutex> aLock =
|
||||
myMutex ? std::unique_lock<std::mutex>(*myMutex) : std::unique_lock<std::mutex>();
|
||||
aHList = myMap(myShape);
|
||||
}
|
||||
|
||||
@@ -535,7 +539,8 @@ BRepCheck_Status BRepCheck_Face::OrientationOfWires(const Standard_Boolean Updat
|
||||
|
||||
void BRepCheck_Face::SetUnorientable()
|
||||
{
|
||||
Standard_Mutex::Sentry aLock(myMutex.get());
|
||||
std::unique_lock<std::mutex> aLock =
|
||||
myMutex ? std::unique_lock<std::mutex>(*myMutex) : std::unique_lock<std::mutex>();
|
||||
BRepCheck::Add(*myMap(myShape), BRepCheck_UnorientableShape);
|
||||
}
|
||||
|
||||
@@ -543,7 +548,8 @@ void BRepCheck_Face::SetUnorientable()
|
||||
|
||||
void BRepCheck_Face::SetStatus(const BRepCheck_Status theStatus)
|
||||
{
|
||||
Standard_Mutex::Sentry aLock(myMutex.get());
|
||||
std::unique_lock<std::mutex> aLock =
|
||||
myMutex ? std::unique_lock<std::mutex>(*myMutex) : std::unique_lock<std::mutex>();
|
||||
BRepCheck::Add(*myMap(myShape), theStatus);
|
||||
}
|
||||
|
||||
|
||||
@@ -46,7 +46,8 @@ void BRepCheck_Result::Init(const TopoDS_Shape& S)
|
||||
|
||||
void BRepCheck_Result::SetFailStatus(const TopoDS_Shape& S)
|
||||
{
|
||||
Standard_Mutex::Sentry aLock(myMutex.get());
|
||||
std::unique_lock<std::mutex> aLock =
|
||||
myMutex ? std::unique_lock<std::mutex>(*myMutex) : std::unique_lock<std::mutex>();
|
||||
Handle(BRepCheck_HListOfStatus) aList;
|
||||
if (!myMap.Find(S, aList))
|
||||
{
|
||||
@@ -84,8 +85,8 @@ void BRepCheck_Result::NextShapeInContext()
|
||||
|
||||
void BRepCheck_Result::SetParallel(Standard_Boolean theIsParallel)
|
||||
{
|
||||
if (theIsParallel && myMutex.IsNull())
|
||||
if (theIsParallel && !myMutex)
|
||||
{
|
||||
myMutex.reset(new Standard_HMutex());
|
||||
myMutex = opencascade::make_unique<std::mutex>();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,10 +19,12 @@
|
||||
|
||||
#include <Standard.hxx>
|
||||
|
||||
#include <Standard_Mutex.hxx>
|
||||
#include <Standard_Transient.hxx>
|
||||
#include <BRepCheck_DataMapOfShapeListOfStatus.hxx>
|
||||
#include <BRepCheck_ListOfStatus.hxx>
|
||||
#include <Standard_MemoryUtils.hxx>
|
||||
|
||||
#include <mutex>
|
||||
|
||||
DEFINE_STANDARD_HANDLE(BRepCheck_Result, Standard_Transient)
|
||||
|
||||
@@ -80,10 +82,10 @@ protected:
|
||||
Standard_Boolean myMin;
|
||||
Standard_Boolean myBlind;
|
||||
BRepCheck_DataMapOfShapeListOfStatus myMap;
|
||||
mutable Handle(Standard_HMutex) myMutex;
|
||||
mutable std::unique_ptr<std::mutex> myMutex;
|
||||
|
||||
private:
|
||||
Standard_HMutex* GetMutex() { return myMutex.get(); }
|
||||
std::unique_ptr<std::mutex>& GetMutex() { return myMutex; }
|
||||
|
||||
private:
|
||||
BRepCheck_DataMapIteratorOfDataMapOfShapeListOfStatus myIter;
|
||||
|
||||
@@ -177,7 +177,8 @@ void BRepCheck_Shell::InContext(const TopoDS_Shape& S)
|
||||
{
|
||||
Handle(BRepCheck_HListOfStatus) aHList;
|
||||
{
|
||||
Standard_Mutex::Sentry aLock(myMutex.get());
|
||||
std::unique_lock<std::mutex> aLock =
|
||||
myMutex ? std::unique_lock<std::mutex>(*myMutex) : std::unique_lock<std::mutex>();
|
||||
if (myMap.IsBound(S))
|
||||
{
|
||||
return;
|
||||
@@ -247,7 +248,8 @@ BRepCheck_Status BRepCheck_Shell::Closed(const Standard_Boolean Update)
|
||||
{
|
||||
Handle(BRepCheck_HListOfStatus) aHList;
|
||||
{
|
||||
Standard_Mutex::Sentry aLock(myMutex.get());
|
||||
std::unique_lock<std::mutex> aLock =
|
||||
myMutex ? std::unique_lock<std::mutex>(*myMutex) : std::unique_lock<std::mutex>();
|
||||
aHList = myMap(myShape);
|
||||
}
|
||||
|
||||
@@ -429,7 +431,8 @@ BRepCheck_Status BRepCheck_Shell::Orientation(const Standard_Boolean Update)
|
||||
{
|
||||
Handle(BRepCheck_HListOfStatus) aHList;
|
||||
{
|
||||
Standard_Mutex::Sentry aLock(myMutex.get());
|
||||
std::unique_lock<std::mutex> aLock =
|
||||
myMutex ? std::unique_lock<std::mutex>(*myMutex) : std::unique_lock<std::mutex>();
|
||||
aHList = myMap(myShape);
|
||||
}
|
||||
BRepCheck_ListOfStatus& aStatusList = *aHList;
|
||||
@@ -826,7 +829,8 @@ BRepCheck_Status BRepCheck_Shell::Orientation(const Standard_Boolean Update)
|
||||
|
||||
void BRepCheck_Shell::SetUnorientable()
|
||||
{
|
||||
Standard_Mutex::Sentry aLock(myMutex.get());
|
||||
std::unique_lock<std::mutex> aLock =
|
||||
myMutex ? std::unique_lock<std::mutex>(*myMutex) : std::unique_lock<std::mutex>();
|
||||
BRepCheck::Add(*myMap(myShape), BRepCheck_UnorientableShape);
|
||||
}
|
||||
|
||||
@@ -841,7 +845,8 @@ Standard_Boolean BRepCheck_Shell::IsUnorientable() const
|
||||
|
||||
Handle(BRepCheck_HListOfStatus) aHList;
|
||||
{
|
||||
Standard_Mutex::Sentry aLock(myMutex.get());
|
||||
std::unique_lock<std::mutex> aLock =
|
||||
myMutex ? std::unique_lock<std::mutex>(*myMutex) : std::unique_lock<std::mutex>();
|
||||
aHList = myMap(myShape);
|
||||
}
|
||||
BRepCheck_ListOfStatus& aStatusList = *aHList;
|
||||
|
||||
@@ -64,7 +64,8 @@ void BRepCheck_Vertex::InContext(const TopoDS_Shape& S)
|
||||
{
|
||||
Handle(BRepCheck_HListOfStatus) aHList;
|
||||
{
|
||||
Standard_Mutex::Sentry aLock(myMutex.get());
|
||||
std::unique_lock<std::mutex> aLock =
|
||||
myMutex ? std::unique_lock<std::mutex>(*myMutex) : std::unique_lock<std::mutex>();
|
||||
if (myMap.IsBound(S))
|
||||
{
|
||||
return;
|
||||
|
||||
@@ -187,7 +187,8 @@ void BRepCheck_Wire::InContext(const TopoDS_Shape& S)
|
||||
{
|
||||
Handle(BRepCheck_HListOfStatus) aHList;
|
||||
{
|
||||
Standard_Mutex::Sentry aLock(myMutex.get());
|
||||
std::unique_lock<std::mutex> aLock =
|
||||
myMutex ? std::unique_lock<std::mutex>(*myMutex) : std::unique_lock<std::mutex>();
|
||||
if (myMap.IsBound(S))
|
||||
{
|
||||
return;
|
||||
@@ -273,7 +274,8 @@ BRepCheck_Status BRepCheck_Wire::Closed(const Standard_Boolean Update)
|
||||
{
|
||||
Handle(BRepCheck_HListOfStatus) aHList;
|
||||
{
|
||||
Standard_Mutex::Sentry aLock(myMutex.get());
|
||||
std::unique_lock<std::mutex> aLock =
|
||||
myMutex ? std::unique_lock<std::mutex>(*myMutex) : std::unique_lock<std::mutex>();
|
||||
aHList = myMap(myShape);
|
||||
}
|
||||
|
||||
@@ -540,7 +542,8 @@ BRepCheck_Status BRepCheck_Wire::Closed2d(const TopoDS_Face& theFace, const Stan
|
||||
{
|
||||
Handle(BRepCheck_HListOfStatus) aHList;
|
||||
{
|
||||
Standard_Mutex::Sentry aLock(myMutex.get());
|
||||
std::unique_lock<std::mutex> aLock =
|
||||
myMutex ? std::unique_lock<std::mutex>(*myMutex) : std::unique_lock<std::mutex>();
|
||||
aHList = myMap(myShape);
|
||||
}
|
||||
BRepCheck_ListOfStatus& aStatusList = *aHList;
|
||||
@@ -717,7 +720,8 @@ BRepCheck_Status BRepCheck_Wire::Orientation(const TopoDS_Face& F, const Standar
|
||||
BRepCheck_Status theOstat = Closed();
|
||||
Handle(BRepCheck_HListOfStatus) aHList;
|
||||
{
|
||||
Standard_Mutex::Sentry aLock(myMutex.get());
|
||||
std::unique_lock<std::mutex> aLock =
|
||||
myMutex ? std::unique_lock<std::mutex>(*myMutex) : std::unique_lock<std::mutex>();
|
||||
aHList = myMap(myShape);
|
||||
}
|
||||
BRepCheck_ListOfStatus& aStatusList = *aHList;
|
||||
@@ -1057,7 +1061,8 @@ BRepCheck_Status BRepCheck_Wire::SelfIntersect(const TopoDS_Face& F,
|
||||
{
|
||||
Handle(BRepCheck_HListOfStatus) aHList;
|
||||
{
|
||||
Standard_Mutex::Sentry aLock(myMutex.get());
|
||||
std::unique_lock<std::mutex> aLock =
|
||||
myMutex ? std::unique_lock<std::mutex>(*myMutex) : std::unique_lock<std::mutex>();
|
||||
aHList = myMap(myShape);
|
||||
}
|
||||
BRepCheck_ListOfStatus& aStatusList = *aHList;
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <TopoDS_Vertex.hxx>
|
||||
#include <TopoDS_Edge.hxx>
|
||||
#include <TopoDS_Face.hxx>
|
||||
#include <Standard_MemoryUtils.hxx>
|
||||
#include <TopAbs_ShapeEnum.hxx>
|
||||
#include <Precision.hxx>
|
||||
#include <BRepExtrema_UnCompatibleShape.hxx>
|
||||
@@ -38,6 +39,8 @@
|
||||
#include <StdFail_NotDone.hxx>
|
||||
|
||||
#include <algorithm>
|
||||
#include <atomic>
|
||||
#include <mutex>
|
||||
|
||||
namespace
|
||||
{
|
||||
@@ -696,7 +699,7 @@ struct TreatmentFunctor
|
||||
DistRef(0),
|
||||
InnerSol(NULL),
|
||||
IsDone(NULL),
|
||||
Mutex(NULL)
|
||||
Mutex()
|
||||
{
|
||||
for (Standard_Integer i = 0; i < theArrayOfArrays->Size(); ++i)
|
||||
{
|
||||
@@ -717,7 +720,7 @@ struct TreatmentFunctor
|
||||
break;
|
||||
}
|
||||
aScope.Next();
|
||||
if (*IsDone)
|
||||
if (IsDone->load(std::memory_order_acquire))
|
||||
{
|
||||
break;
|
||||
}
|
||||
@@ -727,10 +730,11 @@ struct TreatmentFunctor
|
||||
aClassifier.Perform(aPnt, aTolerance);
|
||||
if (aClassifier.State() == TopAbs_IN)
|
||||
{
|
||||
Standard_Mutex::Sentry aLock(Mutex.get());
|
||||
*InnerSol = Standard_True;
|
||||
*DistRef = 0.;
|
||||
*IsDone = Standard_True;
|
||||
std::unique_lock<std::mutex> aLock =
|
||||
Mutex ? std::unique_lock<std::mutex>(*Mutex) : std::unique_lock<std::mutex>();
|
||||
InnerSol->store(true, std::memory_order_release);
|
||||
*DistRef = 0.;
|
||||
IsDone->store(true, std::memory_order_release);
|
||||
BRepExtrema_SolutionElem aSolElem(0, aPnt, BRepExtrema_IsVertex, aVertex);
|
||||
SolutionsShape1->Append(aSolElem);
|
||||
SolutionsShape2->Append(aSolElem);
|
||||
@@ -746,9 +750,9 @@ struct TreatmentFunctor
|
||||
Message_ProgressScope Scope;
|
||||
NCollection_Array1<Message_ProgressRange> Ranges;
|
||||
Standard_Real* DistRef;
|
||||
volatile Standard_Boolean* InnerSol;
|
||||
volatile Standard_Boolean* IsDone;
|
||||
Handle(Standard_HMutex) Mutex;
|
||||
std::atomic<bool>* InnerSol;
|
||||
std::atomic<bool>* IsDone;
|
||||
std::unique_ptr<std::mutex> Mutex;
|
||||
};
|
||||
|
||||
//=================================================================================================
|
||||
@@ -788,21 +792,29 @@ Standard_Boolean BRepExtrema_DistShapeShape::SolidTreatment(
|
||||
anArrayOfArray[aVectIndex][aShapeIndex] = theVertexMap(anI);
|
||||
}
|
||||
|
||||
// Create local atomic variables for thread-safe communication during parallel section
|
||||
std::atomic<bool> anAtomicInnerSol(myInnerSol);
|
||||
std::atomic<bool> anAtomicIsDone(myIsDone);
|
||||
|
||||
Message_ProgressScope aScope(theRange, "Solid treatment", aNbTasks);
|
||||
TreatmentFunctor aFunctor(&anArrayOfArray, aScope.Next());
|
||||
aFunctor.SolutionsShape1 = &mySolutionsShape1;
|
||||
aFunctor.SolutionsShape2 = &mySolutionsShape2;
|
||||
aFunctor.Shape = theShape;
|
||||
aFunctor.DistRef = &myDistRef;
|
||||
aFunctor.InnerSol = &myInnerSol;
|
||||
aFunctor.IsDone = &myIsDone;
|
||||
if (myIsMultiThread)
|
||||
aFunctor.InnerSol = &anAtomicInnerSol;
|
||||
aFunctor.IsDone = &anAtomicIsDone;
|
||||
if (myIsMultiThread && !aFunctor.Mutex)
|
||||
{
|
||||
aFunctor.Mutex.reset(new Standard_HMutex());
|
||||
aFunctor.Mutex = std::make_unique<std::mutex>();
|
||||
}
|
||||
|
||||
OSD_Parallel::For(0, aNbTasks, aFunctor, !myIsMultiThread);
|
||||
|
||||
// Copy atomic results back to class members after parallel section completes
|
||||
myInnerSol = anAtomicInnerSol.load(std::memory_order_acquire);
|
||||
myIsDone = anAtomicIsDone.load(std::memory_order_acquire);
|
||||
|
||||
if (!aScope.More())
|
||||
{
|
||||
return Standard_False;
|
||||
|
||||
Reference in New Issue
Block a user