1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-21 10:13:43 +03:00

0022850: Not stable fix 22735

Class TopTools_MutexForShapeProvider has been created
Class contain methods:
TopTools_MutexForShapeProvider::CreateMutexesForSubShapes - Creates and associates mutexes with each sub-shape of type theType in theShape.
TopTools_MutexForShapeProvider::CreateMutexForShape - Creates and associates mutex with theShape
TopTools_MutexForShapeProvider::GetMutex - Returns pointer to mutex associated with theShape. In case when mutex not found returns NULL.

Added method RemoveAllMutexes to TopTools_MutexForShapeProvider
Assign operator in MutexProvider, constructor and operator and assign operator in Standard_Mutex now private
Replaced TopExp_Explorer with TopoDS_Iterator to avoid cyclic dependence
This commit is contained in:
dbv 2012-07-06 16:08:21 +04:00
parent 36f35343b8
commit d00cba631f
10 changed files with 246 additions and 10 deletions

View File

@ -67,8 +67,9 @@ uses Boolean from Standard,
MapOfInteger from BRepMesh, MapOfInteger from BRepMesh,
BaseAllocator from BRepMesh, BaseAllocator from BRepMesh,
DataMapOfFaceAttribute from BRepMesh, DataMapOfFaceAttribute from BRepMesh,
IndexedDataMapOfShapeListOfShape from TopTools IndexedDataMapOfShapeListOfShape from TopTools,
MutexForShapeProvider from TopTools,
ShapeEnum from TopAbs
is is
@ -194,6 +195,17 @@ is
---Purpose: ---Purpose:
-- Returns the multi-threading usage flag. -- Returns the multi-threading usage flag.
CreateMutexesForSubShapes(me : mutable;
theShape : Shape from TopoDS;
theType : ShapeEnum from TopAbs);
---Purpose:
-- Creates mutexes for each sub-shape of type theType in theShape.
-- Used to avoid data races.
RemoveAllMutexes(me: mutable);
---Purpose:
-- Removes all created mutexes
-- Output : -- Output :
@ -338,5 +350,6 @@ fields
myMapdefle : DataMapOfShapeReal from TopTools; myMapdefle : DataMapOfShapeReal from TopTools;
myNottriangulated : ListOfShape from TopTools; myNottriangulated : ListOfShape from TopTools;
myAllocator : BaseAllocator from BRepMesh; myAllocator : BaseAllocator from BRepMesh;
myMutexProvider: MutexForShapeProvider from TopTools;
end FastDiscret; end FastDiscret;

View File

@ -258,6 +258,7 @@ void BRepMesh_FastDiscret::Perform(const TopoDS_Shape& theShape)
if (myInParallel) if (myInParallel)
{ {
#ifdef HAVE_TBB #ifdef HAVE_TBB
CreateMutexesForSubShapes(theShape, TopAbs_EDGE);
// mesh faces in parallel threads using TBB // mesh faces in parallel threads using TBB
tbb::parallel_for_each (aFaces.begin(), aFaces.end(), *this); tbb::parallel_for_each (aFaces.begin(), aFaces.end(), *this);
#else #else
@ -265,6 +266,7 @@ void BRepMesh_FastDiscret::Perform(const TopoDS_Shape& theShape)
for (std::vector<TopoDS_Face>::iterator it(aFaces.begin()); it != aFaces.end(); it++) for (std::vector<TopoDS_Face>::iterator it(aFaces.begin()); it != aFaces.end(); it++)
Process (*it); Process (*it);
#endif #endif
RemoveAllMutexes();
} }
else else
{ {
@ -286,7 +288,7 @@ void BRepMesh_FastDiscret::Process(const TopoDS_Face& theFace) const
if ( GetFaceAttribute (theFace, fattribute) ) if ( GetFaceAttribute (theFace, fattribute) )
{ {
BRepMesh_FastDiscretFace aTool (GetAngle(), WithShare()); BRepMesh_FastDiscretFace aTool (GetAngle(), WithShare());
aTool.Add (theFace, fattribute, GetMapOfDefEdge()); aTool.Add (theFace, fattribute, GetMapOfDefEdge(), myMutexProvider);
} }
//cout << "END face " << theFace.TShape().operator->() << endl << flush; //cout << "END face " << theFace.TShape().operator->() << endl << flush;
} }
@ -1687,3 +1689,22 @@ void BRepMesh_FastDiscret::RemoveFaceAttribute(const TopoDS_Face& theFace)
if(myMapattrib.IsBound(theFace)) if(myMapattrib.IsBound(theFace))
myMapattrib.UnBind(theFace); myMapattrib.UnBind(theFace);
} }
//=======================================================================
//function : CreateMutexesForSubShapes
//purpose :
//=======================================================================
void BRepMesh_FastDiscret::CreateMutexesForSubShapes(const TopoDS_Shape& theShape,
const TopAbs_ShapeEnum theType)
{
myMutexProvider.CreateMutexesForSubShapes(theShape, theType);
}
//=======================================================================
//function : RemoveAllMutexes
//purpose :
//=======================================================================
void BRepMesh_FastDiscret::RemoveAllMutexes()
{
myMutexProvider.RemoveAllMutexes();
}

View File

@ -39,6 +39,7 @@ uses Boolean from Standard,
DataMapOfVertexInteger from BRepMesh, DataMapOfVertexInteger from BRepMesh,
DataMapOfIntegerListOfXY from BRepMesh, DataMapOfIntegerListOfXY from BRepMesh,
DataMapOfShapeReal from TopTools, DataMapOfShapeReal from TopTools,
MutexForShapeProvider from TopTools,
ListOfVertex from BRepMesh, ListOfVertex from BRepMesh,
ClassifierPtr from BRepMesh, ClassifierPtr from BRepMesh,
Triangle from BRepMesh, Triangle from BRepMesh,
@ -54,7 +55,6 @@ uses Boolean from Standard,
Triangulation from Poly, Triangulation from Poly,
Location from TopLoc Location from TopLoc
is is
Create (theAngle : Real from Standard; Create (theAngle : Real from Standard;
@ -67,7 +67,8 @@ is
Add (me : mutable; Add (me : mutable;
theFace : Face from TopoDS; theFace : Face from TopoDS;
theAttrib : FaceAttribute from BRepMesh; theAttrib : FaceAttribute from BRepMesh;
theMapDefle : DataMapOfShapeReal from TopTools) theMapDefle : DataMapOfShapeReal from TopTools;
theMutexProvider : MutexForShapeProvider from TopTools)
is static; is static;
@ -116,7 +117,8 @@ is
AddInShape (me: mutable; AddInShape (me: mutable;
theFace : Face from TopoDS; theFace : Face from TopoDS;
theDefFace: Real from Standard) theDefFace: Real from Standard;
theMutexProvider: MutexForShapeProvider from TopTools)
is static private; is static private;

View File

@ -108,7 +108,8 @@ BRepMesh_FastDiscretFace::BRepMesh_FastDiscretFace
void BRepMesh_FastDiscretFace::Add(const TopoDS_Face& theFace, void BRepMesh_FastDiscretFace::Add(const TopoDS_Face& theFace,
const Handle(BRepMesh_FaceAttribute)& theAttrib, const Handle(BRepMesh_FaceAttribute)& theAttrib,
const TopTools_DataMapOfShapeReal& theMapDefle) const TopTools_DataMapOfShapeReal& theMapDefle,
const TopTools_MutexForShapeProvider& theMutexProvider)
{ {
#ifndef DEB_MESH #ifndef DEB_MESH
try try
@ -324,7 +325,7 @@ void BRepMesh_FastDiscretFace::Add(const TopoDS_Face& theFace
} }
myStructure->ReplaceNodes(aMoveNodes); myStructure->ReplaceNodes(aMoveNodes);
AddInShape(face, (aDef < 0.0)? theAttrib->GetDefFace() : aDef); AddInShape(face, (aDef < 0.0)? theAttrib->GetDefFace() : aDef, theMutexProvider);
#ifndef DEB_MESH #ifndef DEB_MESH
} }
catch(Standard_Failure) catch(Standard_Failure)
@ -1522,12 +1523,15 @@ Standard_Real BRepMesh_FastDiscretFace::Control(const Handle(BRepAdaptor_HSurfac
return Sqrt(maxdef); return Sqrt(maxdef);
} }
static Standard_Mutex DummyMutex;
//======================================================================= //=======================================================================
//function : AddInShape //function : AddInShape
//purpose : //purpose :
//======================================================================= //=======================================================================
void BRepMesh_FastDiscretFace::AddInShape(const TopoDS_Face& theFace, void BRepMesh_FastDiscretFace::AddInShape(const TopoDS_Face& theFace,
const Standard_Real theDefFace) const Standard_Real theDefFace,
const TopTools_MutexForShapeProvider& theMutexProvider)
{ {
// gp_Pnt Pt; // gp_Pnt Pt;
BRep_Builder B; BRep_Builder B;
@ -1624,6 +1628,12 @@ void BRepMesh_FastDiscretFace::AddInShape(const TopoDS_Face& theFace,
const BRepMesh_PairOfPolygon& pair = It.Value(); const BRepMesh_PairOfPolygon& pair = It.Value();
const Handle(Poly_PolygonOnTriangulation)& NOD1 = pair.First(); const Handle(Poly_PolygonOnTriangulation)& NOD1 = pair.First();
const Handle(Poly_PolygonOnTriangulation)& NOD2 = pair.Last(); const Handle(Poly_PolygonOnTriangulation)& NOD2 = pair.Last();
// lock mutex to prevent parallel change of the same data
Standard_Mutex* aMutex = theMutexProvider.GetMutex(It.Key());
Standard_Mutex::SentryNested (aMutex == NULL ? DummyMutex : *aMutex,
aMutex != NULL);
if ( NOD1 == NOD2 ) { if ( NOD1 == NOD2 ) {
B.UpdateEdge(TopoDS::Edge(It.Key()), NullPoly, TOld,loc); B.UpdateEdge(TopoDS::Edge(It.Key()), NullPoly, TOld,loc);
B.UpdateEdge(TopoDS::Edge(It.Key()), NOD1, T, loc); B.UpdateEdge(TopoDS::Edge(It.Key()), NOD1, T, loc);

View File

@ -40,6 +40,7 @@
#include <TopExp_Explorer.hxx> #include <TopExp_Explorer.hxx>
#include <TopAbs.hxx> #include <TopAbs.hxx>
#include <TopTools_ListIteratorOfListOfShape.hxx> #include <TopTools_ListIteratorOfListOfShape.hxx>
#include <TopTools_MutexForShapeProvider.hxx>
#include <TColgp_Array1OfPnt.hxx> #include <TColgp_Array1OfPnt.hxx>
#include <TColStd_Array1OfReal.hxx> #include <TColStd_Array1OfReal.hxx>
#include <TopoDS_Shape.hxx> #include <TopoDS_Shape.hxx>
@ -260,6 +261,7 @@ void BRepMesh_IncrementalMesh::Update(const TopoDS_Shape& S)
if (myInParallel) if (myInParallel)
{ {
#ifdef HAVE_TBB #ifdef HAVE_TBB
myMesh->CreateMutexesForSubShapes(S, TopAbs_EDGE);
// mesh faces in parallel threads using TBB // mesh faces in parallel threads using TBB
tbb::parallel_for_each (aFaces.begin(), aFaces.end(), *myMesh.operator->()); tbb::parallel_for_each (aFaces.begin(), aFaces.end(), *myMesh.operator->());
#else #else
@ -267,6 +269,7 @@ void BRepMesh_IncrementalMesh::Update(const TopoDS_Shape& S)
for (std::vector<TopoDS_Face>::iterator it(aFaces.begin()); it != aFaces.end(); it++) for (std::vector<TopoDS_Face>::iterator it(aFaces.begin()); it != aFaces.end(); it++)
myMesh->Process (*it); myMesh->Process (*it);
#endif #endif
myMesh->RemoveAllMutexes();
} }
else else
{ {

View File

@ -198,6 +198,11 @@ private:
//! Callback method to unlock the mutex if OCC exception or signal is raised //! Callback method to unlock the mutex if OCC exception or signal is raised
virtual void DestroyCallback (); virtual void DestroyCallback ();
//! This method should not be called (prohibited).
Standard_Mutex (const Standard_Mutex &);
//! This method should not be called (prohibited).
Standard_Mutex& operator = (const Standard_Mutex &);
private: private:
#ifdef WNT #ifdef WNT
CRITICAL_SECTION myMutex; CRITICAL_SECTION myMutex;

2
src/TopTools/FILES Normal file
View File

@ -0,0 +1,2 @@
TopTools_MutexForShapeProvider.hxx
TopTools_MutexForShapeProvider.cxx

View File

@ -215,6 +215,8 @@ is
-- Package methods -- Package methods
-- --
imported MutexForShapeProvider;
Dump(Sh : Shape from TopoDS; S : in out OStream); Dump(Sh : Shape from TopoDS; S : in out OStream);
---Purpose: Dumps the topological structure of <Sh> on the ---Purpose: Dumps the topological structure of <Sh> on the
-- stream <S>. -- stream <S>.

View File

@ -0,0 +1,112 @@
// Created on: 2012-06-27
// Created by: Dmitry BOBYLEV
// Copyright (c) 2012 OPEN CASCADE SAS
//
// The content of this file is subject to the Open CASCADE Technology Public
// License Version 6.5 (the "License"). You may not use the content of this file
// except in compliance with the License. Please obtain a copy of the License
// at http://www.opencascade.org and read it completely before using this file.
//
// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
//
// The Original Code and all software distributed under the License is
// distributed on an "AS IS" basis, without warranty of any kind, and the
// Initial Developer hereby disclaims all such warranties, including without
// limitation, any warranties of merchantability, fitness for a particular
// purpose or non-infringement. Please see the License for the specific terms
// and conditions governing the rights and limitations under the License.
#include <TopTools_MutexForShapeProvider.hxx>
#include <TopoDS_Iterator.hxx>
// macro to compare two types of shapes
#define SAMETYPE(x,y) ((x) == (y))
#define LESSCOMPLEX(x,y) ((x) > (y))
//=======================================================================
//function : TopTools_MutexForShapeProvider
//purpose :
//=======================================================================
TopTools_MutexForShapeProvider::TopTools_MutexForShapeProvider()
{
}
//=======================================================================
//function : ~TopTools_MutexForShapeProvider
//purpose :
//=======================================================================
TopTools_MutexForShapeProvider::~TopTools_MutexForShapeProvider()
{
RemoveAllMutexes();
}
//=======================================================================
//function : CreateMutexesForSubShapes
//purpose :
//=======================================================================
void TopTools_MutexForShapeProvider::CreateMutexesForSubShapes(const TopoDS_Shape& theShape,
const TopAbs_ShapeEnum theType)
{
if (LESSCOMPLEX(theShape.ShapeType(), theType))
return;
for(TopoDS_Iterator anIt(theShape); anIt.More(); anIt.Next())
{
const TopoDS_Shape& aShape = anIt.Value();
if (LESSCOMPLEX(theType, aShape.ShapeType()))
{
CreateMutexesForSubShapes(aShape, theType);
}
else if (SAMETYPE(theType, aShape.ShapeType()))
{
CreateMutexForShape(aShape);
}
}
}
//=======================================================================
//function : CreateMutexForShape
//purpose :
//=======================================================================
void TopTools_MutexForShapeProvider::CreateMutexForShape(const TopoDS_Shape& theShape)
{
if (!myMap.IsBound(theShape))
{
Standard_Mutex* aMutex = new Standard_Mutex();
myMap.Bind(theShape, aMutex);
}
}
//=======================================================================
//function : CreateMutexForShape
//purpose :
//=======================================================================
Standard_Mutex* TopTools_MutexForShapeProvider::GetMutex(const TopoDS_Shape& theShape) const
{
if (myMap.IsBound(theShape))
{
Standard_Mutex* aMutex = myMap.Find(theShape);
return aMutex;
}
else
{
return NULL;
}
}
//=======================================================================
//function : RemoveAllMutexes
//purpose :
//=======================================================================
void TopTools_MutexForShapeProvider::RemoveAllMutexes()
{
for (NCollection_DataMap<TopoDS_Shape, Standard_Mutex *, TopTools_ShapeMapHasher>::Iterator anIter;
anIter.More(); anIter.Next())
{
delete anIter.Value();
}
myMap.Clear();
}

View File

@ -0,0 +1,66 @@
// Created on: 2012-06-27
// Created by: Dmitry BOBYLEV
// Copyright (c) 2012 OPEN CASCADE SAS
//
// The content of this file is subject to the Open CASCADE Technology Public
// License Version 6.5 (the "License"). You may not use the content of this file
// except in compliance with the License. Please obtain a copy of the License
// at http://www.opencascade.org and read it completely before using this file.
//
// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
//
// The Original Code and all software distributed under the License is
// distributed on an "AS IS" basis, without warranty of any kind, and the
// Initial Developer hereby disclaims all such warranties, including without
// limitation, any warranties of merchantability, fitness for a particular
// purpose or non-infringement. Please see the License for the specific terms
// and conditions governing the rights and limitations under the License.
#ifndef _TopTools_MutexForShapeProvider_HeaderFile
#define _TopTools_MutexForShapeProvider_HeaderFile
#include <NCollection_DataMap.hxx>
#include <Standard_Mutex.hxx>
#include <TopAbs_ShapeEnum.hxx>
#include <TopoDS_Shape.hxx>
#include <TopTools_ShapeMapHasher.hxx>
//! Class TopTools_MutexForShapeProvider
//! This class is used to create and store mutexes associated with shapes.
class TopTools_MutexForShapeProvider
{
public:
//! Constructor
Standard_EXPORT TopTools_MutexForShapeProvider();
//! Destructor
Standard_EXPORT ~TopTools_MutexForShapeProvider();
//! Creates and associates mutexes with each sub-shape of type theType in theShape.
Standard_EXPORT void CreateMutexesForSubShapes(const TopoDS_Shape& theShape, const TopAbs_ShapeEnum theType);
//! Creates and associates mutex with theShape
Standard_EXPORT void CreateMutexForShape(const TopoDS_Shape& theShape);
//! Returns pointer to mutex associated with theShape.
//! In case when mutex not found returns NULL.
Standard_EXPORT Standard_Mutex* GetMutex(const TopoDS_Shape& theShape) const;
//! Removes all mutexes
Standard_EXPORT void RemoveAllMutexes();
private:
//! This method should not be called (prohibited).
TopTools_MutexForShapeProvider (const TopTools_MutexForShapeProvider &);
//! This method should not be called (prohibited).
TopTools_MutexForShapeProvider & operator = (const TopTools_MutexForShapeProvider &);
NCollection_DataMap<TopoDS_Shape, Standard_Mutex *, TopTools_ShapeMapHasher> myMap;
};
#endif