mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-04-07 18:30:55 +03:00
0023260: Regression: Instability in parallel incmesh on Linux.
Added protection to the function which may have data race (according to the valgrind report). Added protection to the BRepMesh_FastDiscretFace::RestoreStructureFromTriangulation function Slight reordering to optimize use of mutex (lock once) Now Standard_Mutex::SentryNested are created as named object. Map inside TopTools_MutexForShapeProvider now store Handle_TopoDS_TShape as a key instead of TopoDS_Shape
This commit is contained in:
parent
312cd1f500
commit
f67d0512ac
@ -84,7 +84,8 @@ is
|
|||||||
theSurf : HSurface from BRepAdaptor;
|
theSurf : HSurface from BRepAdaptor;
|
||||||
theTrigu : Triangulation from Poly;
|
theTrigu : Triangulation from Poly;
|
||||||
theDefEdge : Real from Standard;
|
theDefEdge : Real from Standard;
|
||||||
theLoc : Location from TopLoc)
|
theLoc : Location from TopLoc;
|
||||||
|
theMutexProvider: MutexForShapeProvider from TopTools)
|
||||||
returns Boolean from Standard is protected;
|
returns Boolean from Standard is protected;
|
||||||
|
|
||||||
|
|
||||||
|
@ -57,6 +57,8 @@
|
|||||||
|
|
||||||
#define UVDEFLECTION 1.e-05
|
#define UVDEFLECTION 1.e-05
|
||||||
|
|
||||||
|
static Standard_Mutex DummyMutex;
|
||||||
|
|
||||||
static Standard_Real FUN_CalcAverageDUV(TColStd_Array1OfReal& P, const Standard_Integer PLen)
|
static Standard_Real FUN_CalcAverageDUV(TColStd_Array1OfReal& P, const Standard_Integer PLen)
|
||||||
{
|
{
|
||||||
Standard_Integer i, j, n = 0;
|
Standard_Integer i, j, n = 0;
|
||||||
@ -173,8 +175,7 @@ void BRepMesh_FastDiscretFace::Add(const TopoDS_Face& theFace
|
|||||||
const TopoDS_Edge& edge = TopoDS::Edge(ex.Value());
|
const TopoDS_Edge& edge = TopoDS::Edge(ex.Value());
|
||||||
if(edge.IsNull())
|
if(edge.IsNull())
|
||||||
continue;
|
continue;
|
||||||
|
RestoreStructureFromTriangulation(edge, face, gFace, aFaceTrigu, theMapDefle(edge), loc, theMutexProvider);
|
||||||
RestoreStructureFromTriangulation(edge, face, gFace, aFaceTrigu, theMapDefle(edge), loc);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -349,22 +350,28 @@ Standard_Boolean BRepMesh_FastDiscretFace::RestoreStructureFromTriangulation
|
|||||||
const Handle(BRepAdaptor_HSurface)& theSurf,
|
const Handle(BRepAdaptor_HSurface)& theSurf,
|
||||||
const Handle(Poly_Triangulation)& theTrigu,
|
const Handle(Poly_Triangulation)& theTrigu,
|
||||||
const Standard_Real theDefEdge,
|
const Standard_Real theDefEdge,
|
||||||
const TopLoc_Location& theLoc)
|
const TopLoc_Location& theLoc,
|
||||||
|
const TopTools_MutexForShapeProvider& theMutexProvider)
|
||||||
{
|
{
|
||||||
// oan: changes for right restoring of triangulation data from face & edges
|
|
||||||
Handle(Poly_PolygonOnTriangulation) Poly;
|
|
||||||
Poly = BRep_Tool::PolygonOnTriangulation(theEdge, theTrigu, theLoc);
|
|
||||||
|
|
||||||
if (Poly.IsNull() || !Poly->HasParameters())
|
|
||||||
{
|
|
||||||
return Standard_False;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2d vertex indices
|
// 2d vertex indices
|
||||||
TopAbs_Orientation orEdge = theEdge.Orientation();
|
TopAbs_Orientation orEdge = theEdge.Orientation();
|
||||||
// Get end points on 2d curve
|
// Get end points on 2d curve
|
||||||
gp_Pnt2d uvFirst, uvLast;
|
gp_Pnt2d uvFirst, uvLast;
|
||||||
BRep_Tool::UVPoints(theEdge, theFace, uvFirst, uvLast);
|
// oan: changes for right restoring of triangulation data from face & edges
|
||||||
|
Handle(Poly_PolygonOnTriangulation) Poly;
|
||||||
|
|
||||||
|
{
|
||||||
|
// lock mutex during querying data from edge curves to prevent parallel change of the same data
|
||||||
|
Standard_Mutex* aMutex = theMutexProvider.GetMutex(theEdge);
|
||||||
|
Standard_Mutex::SentryNested aSentry(aMutex == NULL ? DummyMutex : *aMutex,
|
||||||
|
aMutex != NULL);
|
||||||
|
|
||||||
|
Poly = BRep_Tool::PolygonOnTriangulation(theEdge, theTrigu, theLoc);
|
||||||
|
if (Poly.IsNull() || !Poly->HasParameters())
|
||||||
|
return Standard_False;
|
||||||
|
|
||||||
|
BRep_Tool::UVPoints(theEdge, theFace, uvFirst, uvLast);
|
||||||
|
}
|
||||||
|
|
||||||
// Get vertices
|
// Get vertices
|
||||||
TopoDS_Vertex pBegin, pEnd;
|
TopoDS_Vertex pBegin, pEnd;
|
||||||
@ -1523,8 +1530,6 @@ 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 :
|
||||||
@ -1631,7 +1636,7 @@ void BRepMesh_FastDiscretFace::AddInShape(const TopoDS_Face& theFace,
|
|||||||
|
|
||||||
// lock mutex to prevent parallel change of the same data
|
// lock mutex to prevent parallel change of the same data
|
||||||
Standard_Mutex* aMutex = theMutexProvider.GetMutex(It.Key());
|
Standard_Mutex* aMutex = theMutexProvider.GetMutex(It.Key());
|
||||||
Standard_Mutex::SentryNested (aMutex == NULL ? DummyMutex : *aMutex,
|
Standard_Mutex::SentryNested aSentry(aMutex == NULL ? DummyMutex : *aMutex,
|
||||||
aMutex != NULL);
|
aMutex != NULL);
|
||||||
|
|
||||||
if ( NOD1 == NOD2 ) {
|
if ( NOD1 == NOD2 ) {
|
||||||
|
@ -19,8 +19,10 @@
|
|||||||
|
|
||||||
#include <TopTools_MutexForShapeProvider.hxx>
|
#include <TopTools_MutexForShapeProvider.hxx>
|
||||||
|
|
||||||
|
#include <Standard_Mutex.hxx>
|
||||||
#include <TopoDS_Iterator.hxx>
|
#include <TopoDS_Iterator.hxx>
|
||||||
|
|
||||||
|
|
||||||
// macro to compare two types of shapes
|
// macro to compare two types of shapes
|
||||||
#define SAMETYPE(x,y) ((x) == (y))
|
#define SAMETYPE(x,y) ((x) == (y))
|
||||||
#define LESSCOMPLEX(x,y) ((x) > (y))
|
#define LESSCOMPLEX(x,y) ((x) > (y))
|
||||||
@ -73,10 +75,10 @@ void TopTools_MutexForShapeProvider::CreateMutexesForSubShapes(const TopoDS_Shap
|
|||||||
//=======================================================================
|
//=======================================================================
|
||||||
void TopTools_MutexForShapeProvider::CreateMutexForShape(const TopoDS_Shape& theShape)
|
void TopTools_MutexForShapeProvider::CreateMutexForShape(const TopoDS_Shape& theShape)
|
||||||
{
|
{
|
||||||
if (!myMap.IsBound(theShape))
|
if (!myMap.IsBound(theShape.TShape()))
|
||||||
{
|
{
|
||||||
Standard_Mutex* aMutex = new Standard_Mutex();
|
Standard_Mutex* aMutex = new Standard_Mutex();
|
||||||
myMap.Bind(theShape, aMutex);
|
myMap.Bind(theShape.TShape(), aMutex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,9 +88,9 @@ void TopTools_MutexForShapeProvider::CreateMutexForShape(const TopoDS_Shape& the
|
|||||||
//=======================================================================
|
//=======================================================================
|
||||||
Standard_Mutex* TopTools_MutexForShapeProvider::GetMutex(const TopoDS_Shape& theShape) const
|
Standard_Mutex* TopTools_MutexForShapeProvider::GetMutex(const TopoDS_Shape& theShape) const
|
||||||
{
|
{
|
||||||
if (myMap.IsBound(theShape))
|
if (myMap.IsBound(theShape.TShape()))
|
||||||
{
|
{
|
||||||
Standard_Mutex* aMutex = myMap.Find(theShape);
|
Standard_Mutex* aMutex = myMap.Find(theShape.TShape());
|
||||||
return aMutex;
|
return aMutex;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -103,7 +105,7 @@ Standard_Mutex* TopTools_MutexForShapeProvider::GetMutex(const TopoDS_Shape& the
|
|||||||
//=======================================================================
|
//=======================================================================
|
||||||
void TopTools_MutexForShapeProvider::RemoveAllMutexes()
|
void TopTools_MutexForShapeProvider::RemoveAllMutexes()
|
||||||
{
|
{
|
||||||
for (NCollection_DataMap<TopoDS_Shape, Standard_Mutex *, TopTools_ShapeMapHasher>::Iterator anIter;
|
for (NCollection_DataMap<TopoDS_Shape, Standard_Mutex *>::Iterator anIter;
|
||||||
anIter.More(); anIter.Next())
|
anIter.More(); anIter.Next())
|
||||||
{
|
{
|
||||||
delete anIter.Value();
|
delete anIter.Value();
|
||||||
|
@ -21,17 +21,20 @@
|
|||||||
#ifndef _TopTools_MutexForShapeProvider_HeaderFile
|
#ifndef _TopTools_MutexForShapeProvider_HeaderFile
|
||||||
#define _TopTools_MutexForShapeProvider_HeaderFile
|
#define _TopTools_MutexForShapeProvider_HeaderFile
|
||||||
|
|
||||||
|
#include <Handle_TopoDS_TShape.hxx>
|
||||||
#include <NCollection_DataMap.hxx>
|
#include <NCollection_DataMap.hxx>
|
||||||
#include <Standard_Mutex.hxx>
|
|
||||||
#include <TopAbs_ShapeEnum.hxx>
|
#include <TopAbs_ShapeEnum.hxx>
|
||||||
#include <TopoDS_Shape.hxx>
|
|
||||||
#include <TopTools_ShapeMapHasher.hxx>
|
|
||||||
|
|
||||||
|
class Standard_Mutex;
|
||||||
|
class TopoDS_Shape;
|
||||||
|
|
||||||
//! Class TopTools_MutexForShapeProvider
|
//! Class TopTools_MutexForShapeProvider
|
||||||
//! This class is used to create and store mutexes associated with shapes.
|
//! This class is used to create and store mutexes associated with shapes.
|
||||||
class TopTools_MutexForShapeProvider
|
class TopTools_MutexForShapeProvider
|
||||||
{
|
{
|
||||||
|
friend Standard_Boolean IsEqual(const Handle_TopoDS_TShape & theFirstHandle,
|
||||||
|
const Handle_TopoDS_TShape & theSecondHandle);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
//! Constructor
|
//! Constructor
|
||||||
Standard_EXPORT TopTools_MutexForShapeProvider();
|
Standard_EXPORT TopTools_MutexForShapeProvider();
|
||||||
@ -59,8 +62,14 @@ private:
|
|||||||
TopTools_MutexForShapeProvider & operator = (const TopTools_MutexForShapeProvider &);
|
TopTools_MutexForShapeProvider & operator = (const TopTools_MutexForShapeProvider &);
|
||||||
|
|
||||||
|
|
||||||
NCollection_DataMap<TopoDS_Shape, Standard_Mutex *, TopTools_ShapeMapHasher> myMap;
|
NCollection_DataMap<Handle_TopoDS_TShape, Standard_Mutex *> myMap;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline Standard_Boolean IsEqual(const Handle_TopoDS_TShape & theFirstHandle,
|
||||||
|
const Handle_TopoDS_TShape & theSecondHandle)
|
||||||
|
{
|
||||||
|
return (theFirstHandle == theSecondHandle);
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
Loading…
x
Reference in New Issue
Block a user