1
0
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:
dbv 2012-07-20 17:18:29 +04:00
parent 312cd1f500
commit f67d0512ac
4 changed files with 43 additions and 26 deletions

View File

@ -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;

View File

@ -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 ) {

View File

@ -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();

View File

@ -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