0024826: Wrapping of parallelisation algorithms
authormsv <msv@opencascade.com>
Thu, 5 Feb 2015 12:49:35 +0000 (15:49 +0300)
committerbugmaster <bugmaster@opencascade.com>
Thu, 5 Feb 2015 12:51:05 +0000 (15:51 +0300)
Simple primitives to parallelize loops type "for" and "foreach" were implemented. The primitives encapsulates complete logic for creating and managing parallel context of loops. Moreover the primitives may be a wrapper for some primitives from 3rd-party library - TBB.

To use it is necessary to implement TBB like interface which is based on functors. For example:

Class Functor
{
public:
  void operator() ([proccesing instance]) const
  {
    //...
  }
};

In the body of the operator () should be implemented thread-safe logic of computations that can be performed in parallel context. If parallelized loop iterates on the collections with direct access by index (such as Vector, Array), it is more efficient to use the primitive ParallelFor (because it has no critical section).

All parts of  OCC code which are using tbb were changed on new primitives.

0024826: Wrapping of parallelisation algorithms

Small fix.

34 files changed:
src/BOPAlgo/BOPAlgo_BuilderSolid.cxx
src/BOPAlgo/BOPAlgo_Builder_2.cxx
src/BOPAlgo/BOPAlgo_Builder_3.cxx
src/BOPAlgo/BOPAlgo_PaveFiller_2.cxx
src/BOPAlgo/BOPAlgo_PaveFiller_3.cxx
src/BOPAlgo/BOPAlgo_PaveFiller_4.cxx
src/BOPAlgo/BOPAlgo_PaveFiller_5.cxx
src/BOPAlgo/BOPAlgo_PaveFiller_6.cxx
src/BOPAlgo/BOPAlgo_PaveFiller_7.cxx
src/BOPAlgo/BOPAlgo_PaveFiller_9.cxx
src/BOPAlgo/BOPAlgo_ShellSplitter.cxx
src/BOPAlgo/BOPAlgo_WireSplitter.cxx
src/BOPCol/BOPCol_Parallel.hxx [new file with mode: 0644]
src/BOPCol/BOPCol_TBB.hxx [deleted file]
src/BOPCol/FILES
src/BOPDS/BOPDS_Iterator.cxx
src/BOPTest/BOPTest_CheckCommands.cxx
src/BOPTest/BOPTest_Chronometer.hxx [deleted file]
src/BOPTest/BOPTest_PartitionCommands.cxx
src/BOPTest/FILES
src/BOPTools/BOPTools_AlgoTools_1.cxx
src/BRepMesh/BRepMesh_FastDiscret.cxx
src/BRepMesh/BRepMesh_IncrementalMesh.cxx
src/BRepMesh/BRepMesh_WireChecker.cxx
src/BRepMesh/BRepMesh_WireInterferenceChecker.cxx
src/BRepMesh/BRepMesh_WireInterferenceChecker.hxx
src/MeshTest/MeshTest_PluginCommands.cxx
src/OSD/EXTERNLIB
src/OSD/FILES
src/OSD/OSD_Parallel.cxx [new file with mode: 0644]
src/OSD/OSD_Parallel.hxx [new file with mode: 0644]
src/OpenGl/OpenGl_SceneGeometry.cxx
src/QABugs/QABugs_19.cxx
src/QANCollection/QANCollection_Stl.cxx

index 8986652..fbeb55f 100644 (file)
@@ -62,7 +62,7 @@
 #include <BOPCol_BoxBndTree.hxx>
 #include <BOPCol_ListOfInteger.hxx>
 #include <BOPCol_NCVector.hxx>
-#include <BOPCol_TBB.hxx>
+#include <BOPCol_Parallel.hxx>
 //
 #include <BOPTools.hxx>
 #include <BOPTools_CoupleOfShape.hxx>
@@ -247,13 +247,13 @@ class BOPAlgo_FaceSolid : public BOPAlgo_Algo {
 typedef BOPCol_NCVector
   <BOPAlgo_FaceSolid> BOPAlgo_VectorOfFaceSolid; 
 //
-typedef BOPCol_TBBContextFunctor 
+typedef BOPCol_ContextFunctor 
   <BOPAlgo_FaceSolid,
   BOPAlgo_VectorOfFaceSolid,
   Handle(IntTools_Context), 
   IntTools_Context> BOPAlgo_FaceSolidFunctor;
 //
-typedef BOPCol_TBBContextCnt 
+typedef BOPCol_ContextCnt 
   <BOPAlgo_FaceSolidFunctor,
   BOPAlgo_VectorOfFaceSolid,
   Handle(IntTools_Context)> BOPAlgo_FaceSolidCnt;
index eb24e6b..7ba2e5c 100644 (file)
@@ -36,7 +36,7 @@
 #include <BOPCol_DataMapOfIntegerListOfShape.hxx>
 #include <BOPCol_DataMapOfShapeShape.hxx>
 #include <BOPCol_NCVector.hxx>
-#include <BOPCol_TBB.hxx>
+#include <BOPCol_Parallel.hxx>
 //
 #include <IntTools_Context.hxx>
 //
@@ -138,13 +138,13 @@ class BOPAlgo_PairOfShapeBoolean : public BOPAlgo_Algo {
 typedef BOPCol_NCVector<BOPAlgo_PairOfShapeBoolean> \
   BOPAlgo_VectorOfPairOfShapeBoolean;
 //
-typedef BOPCol_TBBContextFunctor 
+typedef BOPCol_ContextFunctor 
   <BOPAlgo_PairOfShapeBoolean,
   BOPAlgo_VectorOfPairOfShapeBoolean,
   Handle(IntTools_Context), 
   IntTools_Context> BOPCol_BuilderSDFaceFunctor;
 //
-typedef BOPCol_TBBContextCnt 
+typedef BOPCol_ContextCnt 
   <BOPCol_BuilderSDFaceFunctor,
   BOPAlgo_VectorOfPairOfShapeBoolean,
   Handle(IntTools_Context)> BOPAlgo_BuilderSDFaceCnt;
@@ -154,11 +154,11 @@ typedef BOPCol_TBBContextCnt
 //
 typedef BOPCol_NCVector<BOPAlgo_BuilderFace> BOPAlgo_VectorOfBuilderFace;
 //
-typedef BOPCol_TBBFunctor 
+typedef BOPCol_Functor 
   <BOPAlgo_BuilderFace,
   BOPAlgo_VectorOfBuilderFace> BOPAlgo_BuilderFaceFunctor;
 //
-typedef BOPCol_TBBCnt 
+typedef BOPCol_Cnt 
   <BOPAlgo_BuilderFaceFunctor,
   BOPAlgo_VectorOfBuilderFace> BOPAlgo_BuilderFaceCnt;
 //
@@ -223,13 +223,13 @@ class BOPAlgo_VFI : public BOPAlgo_Algo {
 //
 typedef BOPCol_NCVector<BOPAlgo_VFI> BOPAlgo_VectorOfVFI; 
 //
-typedef BOPCol_TBBContextFunctor 
+typedef BOPCol_ContextFunctor 
   <BOPAlgo_VFI,
   BOPAlgo_VectorOfVFI,
   Handle(IntTools_Context), 
   IntTools_Context> BOPAlgo_VFIFunctor;
 //
-typedef BOPCol_TBBContextCnt 
+typedef BOPCol_ContextCnt 
   <BOPAlgo_VFIFunctor,
   BOPAlgo_VectorOfVFI,
   Handle(IntTools_Context)> BOPAlgo_VFICnt;
index 65d8d7e..6b2605e 100644 (file)
@@ -52,7 +52,7 @@
 #include <BOPCol_ListOfInteger.hxx>
 #include <BOPCol_DataMapOfIntegerShape.hxx>
 #include <BOPCol_NCVector.hxx>
-#include <BOPCol_TBB.hxx>
+#include <BOPCol_Parallel.hxx>
 //
 #include <IntTools_Context.hxx>
 //
@@ -84,11 +84,11 @@ static
 typedef BOPCol_NCVector
   <BOPAlgo_BuilderSolid> BOPAlgo_VectorOfBuilderSolid;
 //
-typedef BOPCol_TBBFunctor 
+typedef BOPCol_Functor 
   <BOPAlgo_BuilderSolid,
   BOPAlgo_VectorOfBuilderSolid> BOPAlgo_BuilderSolidFunctor;
 //
-typedef BOPCol_TBBCnt 
+typedef BOPCol_Cnt 
   <BOPAlgo_BuilderSolidFunctor,
   BOPAlgo_VectorOfBuilderSolid> BOPAlgo_BuilderSolidCnt;
 //
index c0584d1..69cfa25 100644 (file)
@@ -22,7 +22,7 @@
 #include <BRep_Tool.hxx>
 
 #include <BOPCol_NCVector.hxx>
-#include <BOPCol_TBB.hxx>
+#include <BOPCol_Parallel.hxx>
 
 #include <IntTools_Context.hxx>
 
@@ -118,13 +118,13 @@ class BOPAlgo_VertexEdge : public BOPAlgo_Algo {
 typedef BOPCol_NCVector
   <BOPAlgo_VertexEdge> BOPAlgo_VectorOfVertexEdge; 
 //
-typedef BOPCol_TBBContextFunctor 
+typedef BOPCol_ContextFunctor 
   <BOPAlgo_VertexEdge,
   BOPAlgo_VectorOfVertexEdge,
   Handle(IntTools_Context), 
   IntTools_Context> BOPAlgo_VertexEdgeFunctor;
 //
-typedef BOPCol_TBBContextCnt 
+typedef BOPCol_ContextCnt 
   <BOPAlgo_VertexEdgeFunctor,
   BOPAlgo_VectorOfVertexEdge,
   Handle(IntTools_Context)> BOPAlgo_VertexEdgeCnt;
index c20af59..bbafce4 100644 (file)
@@ -47,7 +47,7 @@
 #include <BOPCol_IndexedDataMapOfShapeBox.hxx>
 #include <BOPCol_BoxBndTree.hxx>
 #include <BOPCol_NCVector.hxx>
-#include <BOPCol_TBB.hxx>
+#include <BOPCol_Parallel.hxx>
 //
 #include <IntTools_Context.hxx>
 #include <IntTools_ShrunkRange.hxx>
@@ -116,11 +116,11 @@ class BOPAlgo_EdgeEdge :
 typedef BOPCol_NCVector
   <BOPAlgo_EdgeEdge> BOPAlgo_VectorOfEdgeEdge; 
 //
-typedef BOPCol_TBBFunctor 
+typedef BOPCol_Functor 
   <BOPAlgo_EdgeEdge,
   BOPAlgo_VectorOfEdgeEdge> BOPAlgo_EdgeEdgeFunctor;
 //
-typedef BOPCol_TBBCnt 
+typedef BOPCol_Cnt 
   <BOPAlgo_EdgeEdgeFunctor,
   BOPAlgo_VectorOfEdgeEdge> BOPAlgo_EdgeEdgeCnt;
 //
@@ -163,11 +163,11 @@ class BOPAlgo_TNV : public BOPCol_BoxBndTreeSelector{
 typedef BOPCol_NCVector
   <BOPAlgo_TNV> BOPAlgo_VectorOfTNV; 
 //
-typedef BOPCol_TBBFunctor 
+typedef BOPCol_Functor 
   <BOPAlgo_TNV,
   BOPAlgo_VectorOfTNV> BOPAlgo_TNVFunctor;
 //
-typedef BOPCol_TBBCnt 
+typedef BOPCol_Cnt 
   <BOPAlgo_TNVFunctor,
   BOPAlgo_VectorOfTNV> BOPAlgo_TNVCnt;
 /////////////////////////////////////////////////////////////////////////
@@ -254,13 +254,13 @@ class BOPAlgo_PVE {
 typedef BOPCol_NCVector
   <BOPAlgo_PVE> BOPAlgo_VectorOfPVE; 
 //
-typedef BOPCol_TBBContextFunctor 
+typedef BOPCol_ContextFunctor 
   <BOPAlgo_PVE,
   BOPAlgo_VectorOfPVE,
   Handle(IntTools_Context), 
   IntTools_Context> BOPAlgo_PVEFunctor;
 //
-typedef BOPCol_TBBContextCnt 
+typedef BOPCol_ContextCnt 
   <BOPAlgo_PVEFunctor,
   BOPAlgo_VectorOfPVE,
   Handle(IntTools_Context)> BOPAlgo_PVECnt;
index 5b92b5e..1bd5fc0 100644 (file)
@@ -27,7 +27,7 @@
 //
 #include <BOPCol_MapOfInteger.hxx>
 #include <BOPCol_NCVector.hxx>
-#include <BOPCol_TBB.hxx>
+#include <BOPCol_Parallel.hxx>
 //
 #include <IntTools_Context.hxx>
 //
@@ -125,13 +125,13 @@ class BOPAlgo_VertexFace : public BOPAlgo_Algo {
 typedef BOPCol_NCVector<BOPAlgo_VertexFace>
   BOPAlgo_VectorOfVertexFace; 
 //
-typedef BOPCol_TBBContextFunctor 
+typedef BOPCol_ContextFunctor 
   <BOPAlgo_VertexFace,
   BOPAlgo_VectorOfVertexFace,
   Handle(IntTools_Context), 
   IntTools_Context> BOPAlgo_VertexFaceFunctor;
 //
-typedef BOPCol_TBBContextCnt 
+typedef BOPCol_ContextCnt 
   <BOPAlgo_VertexFaceFunctor,
   BOPAlgo_VectorOfVertexFace,
   Handle(IntTools_Context)> BOPAlgo_VertexFaceCnt;
index b3f45d3..66aec9f 100644 (file)
@@ -38,7 +38,7 @@
 //
 #include <BOPCol_MapOfInteger.hxx>
 #include <BOPCol_NCVector.hxx>
-#include <BOPCol_TBB.hxx>
+#include <BOPCol_Parallel.hxx>
 //
 #include <IntTools_Context.hxx>
 #include <IntTools_Tools.hxx>
@@ -119,13 +119,13 @@ class BOPAlgo_EdgeFace :
 //=======================================================================
 typedef BOPCol_NCVector<BOPAlgo_EdgeFace> BOPAlgo_VectorOfEdgeFace; 
 //
-typedef BOPCol_TBBContextFunctor 
+typedef BOPCol_ContextFunctor 
   <BOPAlgo_EdgeFace,
   BOPAlgo_VectorOfEdgeFace,
   Handle(IntTools_Context), 
   IntTools_Context> BOPAlgo_EdgeFaceFunctor;
 //
-typedef BOPCol_TBBContextCnt 
+typedef BOPCol_ContextCnt 
   <BOPAlgo_EdgeFaceFunctor,
   BOPAlgo_VectorOfEdgeFace,
   Handle(IntTools_Context)> BOPAlgo_EdgeFaceCnt;
index 4e1c129..738f933 100644 (file)
@@ -69,7 +69,7 @@
 #include <BOPCol_IndexedMapOfInteger.hxx>
 #include <BOPCol_DataMapOfIntegerReal.hxx>
 #include <BOPCol_NCVector.hxx>
-#include <BOPCol_TBB.hxx>
+#include <BOPCol_Parallel.hxx>
 
 #include <BOPDS_Interf.hxx>
 #include <BOPDS_Iterator.hxx>
@@ -168,11 +168,11 @@ class BOPAlgo_FaceFace :
 typedef BOPCol_NCVector
   <BOPAlgo_FaceFace> BOPAlgo_VectorOfFaceFace; 
 //
-typedef BOPCol_TBBFunctor 
+typedef BOPCol_Functor 
   <BOPAlgo_FaceFace,
   BOPAlgo_VectorOfFaceFace> BOPAlgo_FaceFaceFunctor;
 //
-typedef BOPCol_TBBCnt 
+typedef BOPCol_Cnt 
   <BOPAlgo_FaceFaceFunctor,
   BOPAlgo_VectorOfFaceFace> BOPAlgo_FaceFaceCnt;
 /////////////////////////////////////////////////////////////////////////
index 12b5e86..18b1631 100644 (file)
@@ -41,7 +41,7 @@
 #include <Geom2d_Curve.hxx>
 
 #include <BOPCol_NCVector.hxx>
-#include <BOPCol_TBB.hxx>
+#include <BOPCol_Parallel.hxx>
 #include <BOPCol_MapOfShape.hxx>
 
 #include <BOPDS_VectorOfListOfPaveBlock.hxx>
@@ -153,11 +153,11 @@ class BOPAlgo_SplitEdge : public BOPAlgo_Algo  {
 typedef BOPCol_NCVector
   <BOPAlgo_SplitEdge> BOPAlgo_VectorOfSplitEdge; 
 //
-typedef BOPCol_TBBFunctor 
+typedef BOPCol_Functor 
   <BOPAlgo_SplitEdge,
   BOPAlgo_VectorOfSplitEdge> BOPAlgo_SplitEdgeFunctor;
 //
-typedef BOPCol_TBBCnt 
+typedef BOPCol_Cnt 
   <BOPAlgo_SplitEdgeFunctor,
   BOPAlgo_VectorOfSplitEdge> BOPAlgo_SplitEdgeCnt;
 //
@@ -220,11 +220,11 @@ class BOPAlgo_MPC : public BOPAlgo_Algo  {
 typedef BOPCol_NCVector
   <BOPAlgo_MPC> BOPAlgo_VectorOfMPC; 
 //
-typedef BOPCol_TBBFunctor 
+typedef BOPCol_Functor 
   <BOPAlgo_MPC,
   BOPAlgo_VectorOfMPC> BOPAlgo_MPCFunctor;
 //
-typedef BOPCol_TBBCnt 
+typedef BOPCol_Cnt 
   <BOPAlgo_MPCFunctor,
   BOPAlgo_VectorOfMPC> BOPAlgo_MPCCnt;
 //
@@ -260,11 +260,11 @@ class BOPAlgo_BPC {
 typedef BOPCol_NCVector
   <BOPAlgo_BPC> BOPAlgo_VectorOfBPC; 
 //
-typedef BOPCol_TBBFunctor 
+typedef BOPCol_Functor 
   <BOPAlgo_BPC,
   BOPAlgo_VectorOfBPC> BOPAlgo_BPCFunctor;
 //
-typedef BOPCol_TBBCnt 
+typedef BOPCol_Cnt 
   <BOPAlgo_BPCFunctor,
   BOPAlgo_VectorOfBPC> BOPAlgo_BPCCnt;
 //
index 2cbdec3..e3208e6 100644 (file)
@@ -21,7 +21,7 @@
 
 #include <BOPCol_NCVector.hxx>
 #include <BOPCol_MapOfInteger.hxx>
-#include <BOPCol_TBB.hxx>
+#include <BOPCol_Parallel.hxx>
 
 #include <BOPDS_ShapeInfo.hxx>
 #include <BOPDS_PaveBlock.hxx>
@@ -75,13 +75,13 @@ class BOPAlgo_ShrunkRange : public IntTools_ShrunkRange {
 typedef BOPCol_NCVector
   <BOPAlgo_ShrunkRange> BOPAlgo_VectorOfShrunkRange; 
 //
-typedef BOPCol_TBBContextFunctor 
+typedef BOPCol_ContextFunctor 
   <BOPAlgo_ShrunkRange,
   BOPAlgo_VectorOfShrunkRange,
   Handle(IntTools_Context), 
   IntTools_Context> BOPAlgo_ShrunkRangeFunctor;
 //
-typedef BOPCol_TBBContextCnt 
+typedef BOPCol_ContextCnt 
   <BOPAlgo_ShrunkRangeFunctor,
   BOPAlgo_VectorOfShrunkRange,
   Handle(IntTools_Context)> BOPAlgo_ShrunkRangeCnt;
index a27392f..5c78dec 100644 (file)
@@ -25,7 +25,7 @@
 #include <BRep_Builder.hxx>
 #include <TopExp_Explorer.hxx>
 //
-#include <BOPCol_TBB.hxx>
+#include <BOPCol_Parallel.hxx>
 #include <BOPCol_IndexedMapOfShape.hxx>
 #include <BOPCol_MapOfShape.hxx>
 #include <BOPCol_MapOfOrientedShape.hxx>
@@ -77,11 +77,11 @@ class BOPAlgo_CBK {
 typedef BOPCol_NCVector
   <BOPAlgo_CBK> BOPAlgo_VectorOfCBK; 
 //
-typedef BOPCol_TBBFunctor 
+typedef BOPCol_Functor 
   <BOPAlgo_CBK,
   BOPAlgo_VectorOfCBK> BOPAlgo_CBKFunctor;
 //
-typedef BOPCol_TBBCnt 
+typedef BOPCol_Cnt 
   <BOPAlgo_CBKFunctor,
   BOPAlgo_VectorOfCBK> BOPAlgo_CBKCnt;
 //
index d5c8b50..16f5323 100644 (file)
@@ -28,7 +28,7 @@
 #include <BOPCol_IndexedMapOfShape.hxx>
 #include <BOPCol_MapOfShape.hxx>
 #include <BOPCol_IndexedDataMapOfShapeListOfShape.hxx>
-#include <BOPCol_TBB.hxx>
+#include <BOPCol_Parallel.hxx>
 #include <BOPCol_NCVector.hxx>
 
 #include <BOPTools.hxx>
@@ -262,56 +262,47 @@ typedef BOPCol_NCVector<BOPTools_ConnexityBlock> \
 //class    : WireSplitterFunctor
 //purpose  : 
 //=======================================================================
-class BOPAlgo_WireSplitterFunctor {
- protected:
+class BOPAlgo_WireSplitterFunctor
+{
+protected:
   TopoDS_Face myFace;
   BOPTools_VectorOfConnexityBlock* myPVCB;
-  //
- public:
+
+public:
   //
   BOPAlgo_WireSplitterFunctor(const TopoDS_Face& aF,
-                             BOPTools_VectorOfConnexityBlock& aVCB) 
-    : myFace(aF), myPVCB(&aVCB) {
+                              BOPTools_VectorOfConnexityBlock& aVCB)
+  : myFace(aF), myPVCB(&aVCB)
+  {
   }
   //
-  void operator()( const flexible_range<Standard_Size>& aBR ) const{
-    Standard_Size i, iBeg, iEnd;
-    //
-    BOPTools_VectorOfConnexityBlock& aVCB=*myPVCB;
-    //
-    iBeg=aBR.begin();
-    iEnd=aBR.end();
-    for(i=iBeg; i!=iEnd; ++i) {
-      BOPTools_ConnexityBlock& aCB=aVCB((Standard_Integer)i);
-      //
-      BOPAlgo_WireSplitter::SplitBlock(myFace, aCB);
-    }
+  void operator()( const Standard_Integer& theIndex ) const
+  {
+    BOPTools_VectorOfConnexityBlock& aVCB = *myPVCB;
+    BOPTools_ConnexityBlock& aCB = aVCB(theIndex);
+    BOPAlgo_WireSplitter::SplitBlock(myFace, aCB);
   }
 };
 //=======================================================================
 //class    : BOPAlgo_WireSplitterCnt
 //purpose  : 
 //=======================================================================
-class BOPAlgo_WireSplitterCnt {
- public:
+class BOPAlgo_WireSplitterCnt
+{
+public:
   //-------------------------------
   // Perform
   Standard_EXPORT 
-    static void Perform(const Standard_Boolean bRunParallel,
-                       const TopoDS_Face& aF, 
-                       BOPTools_VectorOfConnexityBlock& aVCB) {
+  static void Perform(const Standard_Boolean bRunParallel,
+                      const TopoDS_Face& aF,
+                      BOPTools_VectorOfConnexityBlock& aVCB)
+  {
     //
     BOPAlgo_WireSplitterFunctor aWSF(aF, aVCB);
-    Standard_Size aNbVCB=aVCB.Extent();
+    Standard_Size aNbVCB = aVCB.Extent();
     //
-    if (bRunParallel) {
-      flexible_for(flexible_range<Standard_Size>(0,aNbVCB), aWSF);
-    }
-    else {
-      aWSF.operator()(flexible_range<Standard_Size>(0,aNbVCB));
-    }
+    OSD_Parallel::For(0, aNbVCB, aWSF, !bRunParallel);
   }
-  //
 };
 //=======================================================================
 //function : MakeWires
diff --git a/src/BOPCol/BOPCol_Parallel.hxx b/src/BOPCol/BOPCol_Parallel.hxx
new file mode 100644 (file)
index 0000000..d8088ae
--- /dev/null
@@ -0,0 +1,174 @@
+// Created by: Peter KURNEV
+// Copyright (c) 1999-2013 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _BOPDS_Col_HeaderFile
+#define _BOPDS_Col_HeaderFile
+
+#include <Standard_Macro.hxx>
+#include <Standard_NotImplemented.hxx>
+#include <OSD_Parallel.hxx>
+#include <NCollection_DataMap.hxx>
+
+//
+// 1. Implementation of Functors/Starters
+//
+// 1.1. Pure version
+//
+
+//=======================================================================
+//class    : BOPCol_Functor
+//purpose  : 
+//=======================================================================
+template <class TypeSolver, class TypeSolverVector>
+class BOPCol_Functor
+{
+public:
+  //! Constructor.
+  explicit BOPCol_Functor(TypeSolverVector& theSolverVec) 
+  : mySolvers(theSolverVec) {}
+
+  //! Defines functor interface.
+  void operator() (const Standard_Integer theIndex) const
+  {
+    TypeSolver& aSolver = mySolvers(theIndex);
+    aSolver.Perform();
+  }
+
+private:
+  BOPCol_Functor(const BOPCol_Functor&);
+  BOPCol_Functor& operator= (const BOPCol_Functor&);
+
+private:
+  TypeSolverVector& mySolvers;
+};
+
+//=======================================================================
+//class    : BOPCol_Cnt
+//purpose  : 
+//=======================================================================
+template <class TypeFunctor, class TypeSolverVector>
+class BOPCol_Cnt
+{
+public:
+  static void Perform( const Standard_Boolean isRunParallel,
+                       TypeSolverVector&      theSolverVector )
+  {
+    TypeFunctor aFunctor(theSolverVector);
+    OSD_Parallel::For(0, theSolverVector.Extent(), aFunctor, !isRunParallel);
+  }
+};
+
+//
+// 1.2. Context dependent version
+//
+
+//=======================================================================
+//class    : BOPCol_ContextFunctor
+//purpose  : 
+//=======================================================================
+template <class TypeSolver,  class TypeSolverVector,
+          class TypeContext, typename TN>
+class BOPCol_ContextFunctor
+{
+  //! Auxiliary thread ID  hasher.
+  struct Hasher
+  {
+    static Standard_Integer HashCode(const Standard_ThreadId theKey,
+                                     const Standard_Integer  Upper)
+    {
+      return ::HashCode(reinterpret_cast<Standard_Address>(theKey), Upper);
+    }
+
+    static Standard_Boolean IsEqual(const Standard_ThreadId theKey1,
+                                    const Standard_ThreadId theKey2)
+    {
+      return theKey1 == theKey2;
+    }
+  };
+
+  typedef NCollection_DataMap<Standard_ThreadId, TypeContext, Hasher> ContextMap;
+
+public:
+
+  //! Constructor
+  explicit BOPCol_ContextFunctor( TypeSolverVector& theVector )
+  : mySolverVector(theVector) {}
+
+  //! Binds main thread context
+  void SetContext( TypeContext& theContext )
+  {
+    myContexts.Bind(OSD_Thread::Current(), theContext);
+  }
+
+  //! Returns current thread context
+  TypeContext& GetThreadContext() const
+  {
+    const Standard_ThreadId aThreadID = OSD_Thread::Current();
+    if ( myContexts.IsBound(aThreadID) )
+    {
+      TypeContext& aContext = myContexts(aThreadID);
+      if ( aContext.IsNull() == Standard_False )
+        return aContext;
+    }
+
+    // Create new context
+    TypeContext aContext = new TN
+      ( NCollection_BaseAllocator::CommonBaseAllocator() );
+
+    Standard_Mutex::Sentry aLocker(myMutex);
+    myContexts.Bind(aThreadID, aContext);
+
+    return myContexts(aThreadID);
+  }
+
+  //! Defines functor interface
+  void operator()( const Standard_Integer theIndex ) const
+  {
+    TypeContext& aContext = GetThreadContext();
+    TypeSolver&  aSolver  = mySolverVector(theIndex);
+
+    aSolver.SetContext(aContext);
+    aSolver.Perform();
+  }
+
+private:
+  BOPCol_ContextFunctor(const BOPCol_ContextFunctor&);
+  BOPCol_ContextFunctor& operator= (const BOPCol_ContextFunctor&);
+
+private:
+  TypeSolverVector&      mySolverVector;
+  mutable ContextMap     myContexts;
+  mutable Standard_Mutex myMutex;
+};
+
+//=======================================================================
+//class    : BOPCol_ContextCnt
+//purpose  : 
+//=======================================================================
+template <class TypeFunctor, class TypeSolverVector, class TypeContext>
+class BOPCol_ContextCnt
+{
+public:
+  static void Perform( const Standard_Boolean isRunParallel,
+                       TypeSolverVector&      theSolverVector,
+                       TypeContext&           theContext )
+  {
+    TypeFunctor aFunctor(theSolverVector);
+    aFunctor.SetContext(theContext);
+
+    OSD_Parallel::For(0, theSolverVector.Extent(), aFunctor, !isRunParallel);
+  }
+};
+
+#endif
diff --git a/src/BOPCol/BOPCol_TBB.hxx b/src/BOPCol/BOPCol_TBB.hxx
deleted file mode 100755 (executable)
index 8f79013..0000000
+++ /dev/null
@@ -1,248 +0,0 @@
-// Created by: Peter KURNEV
-// Copyright (c) 1999-2013 OPEN CASCADE SAS
-//
-// This file is part of Open CASCADE Technology software library.
-//
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License version 2.1 as published
-// by the Free Software Foundation, with special exception defined in the file
-// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
-// distribution for complete text of the license and disclaimer of any warranty.
-//
-// Alternatively, this file may be used under the terms of Open CASCADE
-// commercial license or contractual agreement.
-
-#ifndef _BOPDS_Col_HeaderFile
-#define _BOPDS_Col_HeaderFile
-
-#include <Standard_Macro.hxx>
-#include <Standard_NotImplemented.hxx>
-
-#ifdef HAVE_TBB
-// On Windows, function TryEnterCriticalSection has appeared in Windows NT
-// and is surrounded by #ifdef in MS VC++ 7.1 headers.
-// Thus to use it we need to define appropriate macro saying that we wil
-// run on Windows NT 4.0 at least
-#if ((defined(_WIN32) || defined(__WIN32__)) && !defined(_WIN32_WINNT))
-  #define _WIN32_WINNT 0x0501
-#endif
-
-#include <tbb/tbb.h>
-using namespace tbb;
-
-#define flexible_range blocked_range
-#define flexible_for   parallel_for
-
-#else // not HAVE_TBB
-
-#define flexible_range serial_range
-#define flexible_for   serial_for
-
-//=======================================================================
-//class : serial_range
-//purpose  : 
-//=======================================================================
-template <class Type> class serial_range {
- public:
-  serial_range(const Type& aBegin,
-               const Type& aEnd)
-    : myBegin(aBegin), myEnd(aEnd) {
-  }
-  //
-  ~serial_range() {
-  }
-  //
-  const Type& begin() const{
-    return myBegin;
-  }
-  //
-  const Type& end() const{
-    return myEnd;
-  };
-  //
- protected:
-  Type myBegin;
-  Type myEnd;
-};
-
-//=======================================================================
-//function : serial_for
-//purpose  : 
-//=======================================================================
-template<typename Range, typename Body>
-static void serial_for( const Range& range, const Body& body ) {
-  body.operator()(range);
-};
-#endif // not HAVE_TBB
-//
-// 2. Implementation of Functors/Starters
-//
-// 2.1. Pure version
-//
-//=======================================================================
-//class    : BOPCol_TBBFunctor
-//purpose  : 
-//=======================================================================
-template <class TypeSolver, 
-          class TypeSolverVector> class BOPCol_TBBFunctor {
- public:
-  BOPCol_TBBFunctor(TypeSolverVector& aV) 
-    : myPV(&aV) {
-  }
-  //
-  ~BOPCol_TBBFunctor() {
-  }
-  //
-  void operator()( const flexible_range<Standard_Integer>& aBR ) const{
-    Standard_Integer i, iBeg, iEnd;
-    //
-    TypeSolverVector& aV=*myPV;
-    //
-    iBeg=aBR.begin();
-    iEnd=aBR.end();
-    for(i=iBeg; i!=iEnd; ++i) {
-      TypeSolver& aSolver=aV(i);
-      //
-      aSolver.Perform();
-    }
-  }
-  //
- protected:
-  TypeSolverVector* myPV;
-};
-//=======================================================================
-//class    : BOPCol_TBBCnt
-//purpose  : 
-//=======================================================================
-template <class TypeFunctor, 
-          class TypeSolverVector> class BOPCol_TBBCnt {
- public:
-  //-------------------------------
-  // Perform
-  Standard_EXPORT 
-    static void Perform(const Standard_Boolean bRunParallel,
-                        TypeSolverVector& aV) {
-    //
-    TypeFunctor aFunctor(aV);
-    Standard_Integer aNb=aV.Extent();
-    //
-    if (bRunParallel) {
-#ifdef HAVE_TBB
-      try {
-        flexible_for(flexible_range<Standard_Integer>(0,aNb), aFunctor);
-      }
-      //
-      catch( captured_exception&  ) {
-        Standard_NotImplemented::Raise("");
-      } 
-      catch( ... ) {
-        Standard_NotImplemented::Raise("");
-      }
-#else // not HAVE_TBB
-      flexible_for(flexible_range<Standard_Integer>(0,aNb), aFunctor);
-#endif      
-    }
-    else {
-      aFunctor.operator()(flexible_range<Standard_Integer>(0,aNb));
-    }
-  }
-};
-//
-// 2.2. Context dependent version
-//
-
-//=======================================================================
-//class    : BOPCol_TBBContextFunctor
-//purpose  : 
-//=======================================================================
-template <class TypeSolver, 
-          class TypeSolverVector,
-          class TypeContext, 
-          typename TN> class BOPCol_TBBContextFunctor  {
- public:
-  BOPCol_TBBContextFunctor(TypeSolverVector& aV) 
-    : myPV(&aV) {
-  }
-  //
-  ~BOPCol_TBBContextFunctor() {
-  }
-  //
-  void SetContext(TypeContext& aCtx) {
-    myContext=aCtx;
-  }
-  //
-  void operator()( const flexible_range<Standard_Integer>& aBR ) const{
-    Standard_Integer i, iBeg, iEnd;
-    TypeContext aCtx;
-    //
-    if (myContext.IsNull()) {
-      aCtx=new TN
-        (NCollection_BaseAllocator::CommonBaseAllocator());
-    }
-    else {
-      aCtx=myContext;
-    }
-    //
-    TypeSolverVector& aV=*myPV;
-    //
-    iBeg=aBR.begin();
-    iEnd=aBR.end();
-    for(i=iBeg; i!=iEnd; ++i) {
-      TypeSolver& aSolver=aV(i);
-      //
-      aSolver.SetContext(aCtx);
-      aSolver.Perform();
-    }
-  }
-  //
- protected:
-  TypeSolverVector* myPV;
-  TypeContext myContext;
-  //
-};
-
-//=======================================================================
-//class    : BOPCol_TBBContextCnt
-//purpose  : 
-//=======================================================================
-template <class TypeFunctor, 
-          class TypeSolverVector,
-          class TypeContext> class BOPCol_TBBContextCnt {
- public:
-  //-------------------------------
-  // Perform
-  Standard_EXPORT 
-    static void Perform(const Standard_Boolean bRunParallel,
-                        TypeSolverVector& aV,
-                        TypeContext& aCtx) {
-    //
-    TypeFunctor aFunctor(aV);
-    Standard_Integer aNb=aV.Extent();
-    //
-    if (bRunParallel) {
-#ifdef HAVE_TBB
-      try {
-        flexible_for(flexible_range<Standard_Integer>(0,aNb), aFunctor);
-      }
-      //
-      catch(captured_exception& ) {
-        //cout<<" captured_exception: " << ex.what() << endl;
-        Standard_NotImplemented::Raise("");
-      } 
-      catch( ... ) {
-        Standard_NotImplemented::Raise("");
-      }
-#else // not HAVE_TBB
-      flexible_for(flexible_range<Standard_Integer>(0,aNb), aFunctor);
-#endif      
-    }
-    else {
-      aFunctor.SetContext(aCtx);
-      aFunctor.operator()(flexible_range<Standard_Integer>(0,aNb));
-    }
-  }
-};
-
-#endif
index 412ba99..8be3e7d 100644 (file)
@@ -28,7 +28,7 @@ BOPCol_SequenceOfReal.hxx
 BOPCol_DataMapOfIntegerShape.hxx
 BOPCol_IndexedDataMapOfIntegerListOfInteger.hxx
 BOPCol_IndexedDataMapOfShapeInteger.hxx
-BOPCol_TBB.hxx
+BOPCol_Parallel.hxx
 BOPCol_NCVector.hxx
 
 BOPCol_BoxBndTree.hxx
index 29237d3..9029348 100644 (file)
@@ -25,7 +25,7 @@
 #include <TopoDS_Shape.hxx>
 //
 #include <BOPCol_NCVector.hxx>
-#include <BOPCol_TBB.hxx>
+#include <BOPCol_Parallel.hxx>
 #include <BOPCol_BoxBndTree.hxx>
 //
 #include <BOPDS_IndexRange.hxx>
@@ -70,8 +70,8 @@ class BOPDS_TSR : public BOPCol_BoxBndTreeSelector{
 //
 //=======================================================================
 typedef BOPCol_NCVector <BOPDS_TSR> BOPDS_VectorOfTSR; 
-typedef BOPCol_TBBFunctor <BOPDS_TSR,BOPDS_VectorOfTSR> BOPDS_TSRFunctor;
-typedef BOPCol_TBBCnt <BOPDS_TSRFunctor, BOPDS_VectorOfTSR> BOPDS_TSRCnt;
+typedef BOPCol_Functor <BOPDS_TSR,BOPDS_VectorOfTSR> BOPDS_TSRFunctor;
+typedef BOPCol_Cnt <BOPDS_TSRFunctor, BOPDS_VectorOfTSR> BOPDS_TSRCnt;
 /////////////////////////////////////////////////////////////////////////
 
 
index 7da70dc..2c38c9d 100644 (file)
 #include <BOPAlgo_CheckerSI.hxx>
 #include <BOPAlgo_ArgumentAnalyzer.hxx>
 #include <BOPAlgo_CheckResult.hxx>
-
 #include <BOPTools_AlgoTools.hxx>
 
-#include <BOPTest_Chronometer.hxx>
+#include <OSD_Timer.hxx>
 #include <BOPTest_Objects.hxx>
 
 //
@@ -204,7 +203,7 @@ Standard_Integer bopcheck (Draw_Interpretor& di,
     if (!strcmp(a[i], "-t")) {
       bShowTime=Standard_True;
     }
-  }
+      }
   //
   //aLevel = (n==3) ? Draw::Atoi(a[2]) : aNbInterfTypes-1;
   //-------------------------------------------------------------------
@@ -218,7 +217,6 @@ Standard_Integer bopcheck (Draw_Interpretor& di,
   BOPAlgo_CheckerSI aChecker;
   BOPCol_ListOfShape aLS;
   BOPDS_MapIteratorMapOfPassKey aItMPK;
-  BOPTest_Chronometer aChrono;
   //
   if (aLevel < (aNbInterfTypes-1)) {
     di << "Info:\nThe level of check is set to " 
@@ -239,11 +237,13 @@ Standard_Integer bopcheck (Draw_Interpretor& di,
   aChecker.SetRunParallel(bRunParallel);
   aChecker.SetFuzzyValue(aTol);
   //
-  aChrono.Start();
+  OSD_Timer aTimer;
+  aTimer.Start();
   //
   aChecker.Perform();
   //
-  aChrono.Stop();
+  aTimer.Stop();
+  aTimer.Show();
   //
   iErr=aChecker.ErrorStatus();
   //
@@ -316,11 +316,9 @@ Standard_Integer bopcheck (Draw_Interpretor& di,
   if (!iCnt) {
     di << " This shape seems to be OK." << "\n";
   }
-  if (bShowTime) {
-    Standard_Real aTime;
-    //
-    aTime=aChrono.Time();
-    Sprintf(buf, "  Tps: %7.2lf\n", aTime);
+  if (bShowTime)
+  {
+    Sprintf(buf, "  Tps: %7.2lf\n", aTimer.ElapsedTime());
     di << buf;
   }
   return 0;
@@ -924,7 +922,7 @@ Standard_Integer xdistef(Draw_Interpretor& di,
                          Standard_Integer n,
                          const char** a)
 {
-  if(n < 3) { 
+  if(n < 3) {
     di << "use xdistef edge face\n";
     return 1;
   }
diff --git a/src/BOPTest/BOPTest_Chronometer.hxx b/src/BOPTest/BOPTest_Chronometer.hxx
deleted file mode 100644 (file)
index ba88bf0..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-// Created by: Peter KURNEV
-// Copyright (c) 2010-2014 OPEN CASCADE SAS
-//
-// This file is part of Open CASCADE Technology software library.
-//
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License version 2.1 as published
-// by the Free Software Foundation, with special exception defined in the file
-// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
-// distribution for complete text of the license and disclaimer of any warranty.
-//
-// Alternatively, this file may be used under the terms of Open CASCADE
-// commercial license or contractual agreement.
-
-#ifndef  BOPTest_Chronometer_HeaderFile
-#define  BOPTest_Chronometer_HeaderFile
-//
-#include <OSD_Timer.hxx>
-//=======================================================================
-//class    : BOPTest_Chronometer
-//purpose  : 
-//=======================================================================
-class BOPTest_Chronometer {
- public:
-  BOPTest_Chronometer() {
-  }
-  //
-  ~BOPTest_Chronometer() {
-  }
-  //
-  void Start() {
-    myChronometer.Reset();
-    myChronometer.Start();
-  }
-  //
-  void Stop() {
-    myChronometer.Stop();
-    myTime=myChronometer.ElapsedTime();
-  }
-  //
-  double Time() const{
-    return myTime;
-  };
-  //
- protected:
-  OSD_Timer myChronometer;
-  double myTime;
-};
-
-#endif
index d8d69ce..29c253c 100644 (file)
@@ -35,7 +35,7 @@
 #include <BOPTest_DrawableShape.hxx>
 #include <BOPTest_Objects.hxx>
 
-#include <BOPTest_Chronometer.hxx>
+#include <OSD_Timer.hxx>
 
 static Standard_Integer bfillds  (Draw_Interpretor&, Standard_Integer, const char**); 
 static Standard_Integer bbuild   (Draw_Interpretor&, Standard_Integer, const char**);
@@ -76,8 +76,6 @@ Standard_Integer bfillds(Draw_Interpretor& di,
   Standard_Real aTol;
   BOPCol_ListIteratorOfListOfShape aIt;
   BOPCol_ListOfShape aLC;
-  BOPTest_Chronometer aChrono;
-  
   BOPCol_ListOfShape& aLS=BOPTest_Objects::Shapes();
   aNbS=aLS.Extent();
   if (!aNbS) {
@@ -94,7 +92,7 @@ Standard_Integer bfillds(Draw_Interpretor& di,
     if (!strcmp(a[i], "-t")) {
       bShowTime=Standard_True;
     }
-  }
+    }
   //
   BOPCol_ListOfShape& aLT=BOPTest_Objects::Tools();
   //
@@ -107,7 +105,7 @@ Standard_Integer bfillds(Draw_Interpretor& di,
   aIt.Initialize(aLT);
   for (; aIt.More(); aIt.Next()) {
     const TopoDS_Shape& aS=aIt.Value();
-    aLC.Append(aS);
+     aLC.Append(aS);
   }
   //
   BOPAlgo_PaveFiller& aPF=BOPTest_Objects::PaveFiller();
@@ -116,7 +114,8 @@ Standard_Integer bfillds(Draw_Interpretor& di,
   aPF.SetRunParallel(bRunParallel);
   aPF.SetFuzzyValue(aTol);
   //
-  aChrono.Start();
+  OSD_Timer aTimer;
+  aTimer.Start();
   //
   aPF.Perform();
   iErr=aPF.ErrorStatus();
@@ -126,13 +125,12 @@ Standard_Integer bfillds(Draw_Interpretor& di,
     return 0;
   }
   //
-  aChrono.Stop();
+  aTimer.Stop();
+  aTimer.Show();
   //
-  if (bShowTime) {
-    Standard_Real aTime;
-    //
-    aTime=aChrono.Time();
-    Sprintf(buf, "  Tps: %7.2lf\n", aTime);
+  if (bShowTime)
+  {
+    Sprintf(buf, "  Tps: %7.2lf\n", aTimer.ElapsedTime());
     di << buf;
   }
   //
@@ -160,8 +158,7 @@ Standard_Integer bbuild(Draw_Interpretor& di,
   char buf[128];
   Standard_Boolean bRunParallel, bShowTime;
   Standard_Integer i, iErr;
-  
-  BOPTest_Chronometer aChrono;
+
   BOPCol_ListIteratorOfListOfShape aIt;
   //
   BOPAlgo_PaveFiller& aPF=BOPTest_Objects::PaveFiller();
@@ -193,7 +190,8 @@ Standard_Integer bbuild(Draw_Interpretor& di,
   aBuilder.SetRunParallel(bRunParallel);
   //
   //
-  aChrono.Start();
+  OSD_Timer aTimer;
+  aTimer.Start();
   //
   aBuilder.PerformWithFiller(aPF); 
   iErr=aBuilder.ErrorStatus();
@@ -203,13 +201,12 @@ Standard_Integer bbuild(Draw_Interpretor& di,
     return 0;
   }
   //
-  aChrono.Stop();
+  aTimer.Stop();
+  aTimer.Show();
   //
-  if (bShowTime) {
-    Standard_Real aTime;
-    //
-    aTime=aChrono.Time();
-    Sprintf(buf, "  Tps: %7.2lf\n", aTime);
+  if (bShowTime)
+  {
+    Sprintf(buf, "  Tps: %7.2lf\n", aTimer.ElapsedTime());
     di << buf;
   }
   //
@@ -246,7 +243,6 @@ Standard_Integer bbop(Draw_Interpretor& di,
   Standard_Integer iErr, iOp, i;
   BOPAlgo_Operation aOp;
   BOPCol_ListIteratorOfListOfShape aIt; 
-  BOPTest_Chronometer aChrono;
   //
   iOp=Draw::Atoi(a[2]);
   if (iOp<0 || iOp>4) {
@@ -306,7 +302,8 @@ Standard_Integer bbop(Draw_Interpretor& di,
   //
   pBuilder->SetRunParallel(bRunParallel);
   //
-  aChrono.Start();
+  OSD_Timer aTimer;
+  aTimer.Start();
   //
   pBuilder->PerformWithFiller(aPF);
   iErr=pBuilder->ErrorStatus();
@@ -316,13 +313,11 @@ Standard_Integer bbop(Draw_Interpretor& di,
     return 0;
   }
   //
-  aChrono.Stop();
+  aTimer.Stop();
+  aTimer.Show();
   //
   if (bShowTime) {
-    Standard_Real aTime;
-    //
-    aTime=aChrono.Time();
-    Sprintf(buf, "  Tps: %7.2lf\n", aTime);
+    Sprintf(buf, "  Tps: %7.2lf\n", aTimer.ElapsedTime());
     di << buf;
   }
   //
index c478aee..fad6632 100755 (executable)
@@ -6,4 +6,3 @@ BOPTest_TolerCommands.cxx
 BOPTest_ObjCommands.cxx
 BOPTest_APICommands.cxx
 BOPTest_OptionCommands.cxx
-BOPTest_Chronometer.hxx
\ No newline at end of file
index cacb227..6fa2144 100644 (file)
@@ -80,7 +80,7 @@
 #include <IntTools_Tools.hxx>
 //
 #include <BOPCol_NCVector.hxx>
-#include <BOPCol_TBB.hxx>
+#include <BOPCol_Parallel.hxx>
 #include <BRepLib_CheckCurveOnSurface.hxx>
 
 static 
@@ -158,11 +158,11 @@ class BOPTools_CPC {
 //=======================================================================
 typedef BOPCol_NCVector<BOPTools_CPC> BOPTools_VectorOfCPC; 
 //
-typedef BOPCol_TBBFunctor 
+typedef BOPCol_Functor 
   <BOPTools_CPC,
   BOPTools_VectorOfCPC> BOPTools_CPCFunctor;
 //
-typedef BOPCol_TBBCnt 
+typedef BOPCol_Cnt 
   <BOPTools_CPCFunctor,
   BOPTools_VectorOfCPC> BOPTools_CPCCnt;
 //
@@ -192,11 +192,11 @@ class BOPTools_CWT {
 //=======================================================================
 typedef BOPCol_NCVector<BOPTools_CWT> BOPTools_VectorOfCWT; 
 //
-typedef BOPCol_TBBFunctor 
+typedef BOPCol_Functor 
   <BOPTools_CWT,
   BOPTools_VectorOfCWT> BOPTools_CWTFunctor;
 //
-typedef BOPCol_TBBCnt 
+typedef BOPCol_Cnt 
   <BOPTools_CWTFunctor,
   BOPTools_VectorOfCWT> BOPTools_CWTCnt;
 //
@@ -237,11 +237,11 @@ class BOPTools_CDT {
 //=======================================================================
 typedef BOPCol_NCVector<BOPTools_CDT> BOPTools_VectorOfCDT; 
 //
-typedef BOPCol_TBBFunctor 
+typedef BOPCol_Functor 
   <BOPTools_CDT,
   BOPTools_VectorOfCDT> BOPTools_CDTFunctor;
 //
-typedef BOPCol_TBBCnt 
+typedef BOPCol_Cnt 
   <BOPTools_CDTFunctor,
   BOPTools_VectorOfCDT> BOPTools_CDTCnt;
 //
@@ -272,11 +272,11 @@ class BOPTools_CVT {
 //=======================================================================
 typedef BOPCol_NCVector<BOPTools_CVT> BOPTools_VectorOfCVT; 
 //
-typedef BOPCol_TBBFunctor 
+typedef BOPCol_Functor 
   <BOPTools_CVT,
   BOPTools_VectorOfCVT> BOPTools_CVTFunctor;
 //
-typedef BOPCol_TBBCnt 
+typedef BOPCol_Cnt 
   <BOPTools_CVTFunctor,
   BOPTools_VectorOfCVT> BOPTools_CVTCnt;
 //
@@ -306,17 +306,17 @@ class BOPTools_CET {
 //=======================================================================
 typedef BOPCol_NCVector<BOPTools_CET> BOPTools_VectorOfCET; 
 //
-typedef BOPCol_TBBFunctor 
+typedef BOPCol_Functor 
   <BOPTools_CET,
   BOPTools_VectorOfCET> BOPTools_CETFunctor;
 //
-typedef BOPCol_TBBCnt 
+typedef BOPCol_Cnt 
   <BOPTools_CETFunctor,
   BOPTools_VectorOfCET> BOPTools_CETCnt;
 //
 //
 //=======================================================================
-//
+  //
 //=======================================================================
 // Function : CorrectTolerances
 // purpose : 
@@ -1063,6 +1063,6 @@ Standard_Boolean BOPTools_AlgoTools::ComputeTolerance
   //
   theMaxDist = aCS.MaxDistance();
   theMaxPar  = aCS.MaxParameter();
-  //
+    //
   return Standard_True;
 }
index 933a8b7..126e671 100644 (file)
@@ -62,6 +62,8 @@
 #include <TopExp.hxx>
 #include <TopExp_Explorer.hxx>
 
+#include <OSD_Parallel.hxx>
+
 #include <Standard_ErrorHandler.hxx>
 #include <Standard_Failure.hxx>
 #include <NCollection_IncAllocator.hxx>
 
 #include <vector>
 
-#ifdef HAVE_TBB
-  // paralleling using Intel TBB
-  #include <tbb/parallel_for_each.h>
-#endif
-
 #define UVDEFLECTION 1.e-05
 
 IMPLEMENT_STANDARD_HANDLE (BRepMesh_FastDiscret, Standard_Transient)
@@ -176,20 +173,7 @@ void BRepMesh_FastDiscret::Perform(const TopoDS_Shape& theShape)
     aFaces.push_back(aFace);
   }
 
-#ifdef HAVE_TBB
-  if ( myInParallel )
-  {
-    tbb::parallel_for_each(aFaces.begin(), aFaces.end(), *this);
-  }
-  else
-  {
-#endif
-    std::vector<TopoDS_Face>::const_iterator anIt(aFaces.begin());
-    for (; anIt != aFaces.end(); anIt++)
-      Process(*anIt);
-#ifdef HAVE_TBB
-  }
-#endif
+  OSD_Parallel::ForEach(aFaces.begin(), aFaces.end(), *this, !myInParallel);
 }
 
 
index c7fefa8..8593287 100644 (file)
@@ -16,6 +16,7 @@
 
 #include <BRepMesh_IncrementalMesh.hxx>
 
+#include <OSD_Parallel.hxx>
 #include <Precision.hxx>
 #include <Standard_ErrorHandler.hxx>
 
 
 #include <GCPnts_TangentialDeflection.hxx>
 
-#ifdef HAVE_TBB
-  // paralleling using Intel TBB
-  #include <tbb/parallel_for_each.h>
-#endif
-
 namespace
 {
   //! Default flag to control parallelization for BRepMesh_IncrementalMesh
@@ -223,19 +219,7 @@ void BRepMesh_IncrementalMesh::update()
     update(aFaceIt.Value());
 
   // Mesh faces
-#ifdef HAVE_TBB
-  if (myInParallel)
-  {
-    tbb::parallel_for_each(myFaces.begin(), myFaces.end(), *myMesh);
-  }
-  else
-  {
-#endif
-    for (aFaceIt.Init(myFaces); aFaceIt.More(); aFaceIt.Next())
-      myMesh->Process(aFaceIt.Value());
-#ifdef HAVE_TBB
-  }
-#endif
+  OSD_Parallel::ForEach(myFaces.begin(), myFaces.end(), *myMesh, !myInParallel);
 
   commit();
   clear();
@@ -577,12 +561,7 @@ Standard_Integer BRepMesh_IncrementalMesh::Discret(
 //=======================================================================
 Standard_Boolean BRepMesh_IncrementalMesh::IsParallelDefault()
 {
-#ifdef HAVE_TBB
   return IS_IN_PARALLEL;
-#else
-  // no alternative parallelization yet - flag has no meaning
-  return Standard_False;
-#endif
 }
 
 //=======================================================================
index bed115d..007ecf3 100644 (file)
 #include <BRepMesh_DataStructureOfDelaun.hxx>
 #include <BRepMesh_Classifier.hxx>
 #include <BRepMesh_WireInterferenceChecker.hxx>
+#include <OSD_Parallel.hxx>
 
-#ifdef HAVE_TBB
-  // paralleling using Intel TBB
-  #include <tbb/parallel_for.h>
-  #include <tbb/blocked_range.h>
-#endif
 
 //=======================================================================
 //function : Selector::Constructor
@@ -196,27 +192,18 @@ void BRepMesh_WireChecker::ReCompute(BRepMesh::HClassifier& theClassifier)
   BRepMesh::Array1OfSegmentsTree aWiresBiPoints(1, aNbWires);
   fillSegmentsTree(aDWires, aWiresBiPoints);
 
-#ifdef HAVE_TBB
-  Standard_Mutex aWireMutex;
-  BRepMesh_WireInterferenceChecker aIntChecker(aWiresBiPoints, 
-    &myStatus, &aWireMutex);
-
   if (myIsInParallel && aNbWires > 1)
   {
-    // check wires in parallel threads using TBB
-    tbb::parallel_for(tbb::blocked_range<Standard_Integer>(1, aNbWires + 1), 
-      aIntChecker);
+    // Check wires in parallel threads.
+    Standard_Mutex aWireMutex;
+    BRepMesh_WireInterferenceChecker aIntChecker(aWiresBiPoints, &myStatus, &aWireMutex);
+    OSD_Parallel::For(1, aNbWires + 1, aIntChecker);
   }
   else
   {
-#else
     BRepMesh_WireInterferenceChecker aIntChecker(aWiresBiPoints, &myStatus);
-#endif
-    for (Standard_Integer i = 1; i <= aNbWires; ++i)
-      aIntChecker(i);
-#ifdef HAVE_TBB
+    OSD_Parallel::For(1, aNbWires + 1, aIntChecker, Standard_True);
   }
-#endif
 
   if (myStatus == BRepMesh_SelfIntersectingWire)
     return;
index a8273b3..326dc8c 100644 (file)
@@ -20,7 +20,6 @@
 // TODO: remove this variable after implementation of LoopChecker2d.
 static const Standard_Real MIN_LOOP_S = 2 * M_PI * 2.E-5;
 
-#ifdef HAVE_TBB
 //=======================================================================
 //function : Constructor
 //purpose  :
@@ -35,30 +34,6 @@ BRepMesh_WireInterferenceChecker::BRepMesh_WireInterferenceChecker(
 {
 }
 
-//=======================================================================
-//function : Checker's body
-//purpose  : 
-//=======================================================================
-void BRepMesh_WireInterferenceChecker::operator ()(
-  const tbb::blocked_range<Standard_Integer>& theWireRange) const
-{
-  for (Standard_Integer i = theWireRange.begin(); i != theWireRange.end(); ++i)
-    this->operator ()(i);
-}
-#else
-//=======================================================================
-//function : Constructor
-//purpose  : 
-//=======================================================================
-BRepMesh_WireInterferenceChecker::BRepMesh_WireInterferenceChecker(
-  const BRepMesh::Array1OfSegmentsTree& theWires,
-  BRepMesh_Status*                      theStatus)
-: myWires (theWires),
-  myStatus(theStatus)
-{
-}
-#endif
-
 //=======================================================================
 //function : Checker's body
 //purpose  : 
@@ -75,11 +50,9 @@ void BRepMesh_WireInterferenceChecker::operator ()(
 
   for (Standard_Integer aWireIt = theWireId; aWireIt <= myWires.Upper(); ++aWireIt)
   {
-#ifdef HAVE_TBB
-    // Break execution in case if flag was raised by another thread
+    // Break execution in case if flag was raised by another thread.
     if (*myStatus == BRepMesh_SelfIntersectingWire)
       return;
-#endif
 
     const Standard_Boolean isSelfIntCheck = (aWireIt == theWireId);
     const BRepMesh::SegmentsTree& aWireSegTree2 = 
@@ -93,11 +66,9 @@ void BRepMesh_WireInterferenceChecker::operator ()(
     Standard_Integer aSegmentId1 = aWireSegments1->Lower();
     for (; aSegmentId1 <= aWireSegments1->Upper(); ++aSegmentId1)
     {
-#ifdef HAVE_TBB
       // Break execution in case if flag was raised by another thread
       if (*myStatus == BRepMesh_SelfIntersectingWire)
         return;
-#endif
 
       aSelector.Clear();
       aSelector.SetBox(aWireBoxTree1->FindNode(aSegmentId1).Bnd());
@@ -112,11 +83,9 @@ void BRepMesh_WireInterferenceChecker::operator ()(
       const Standard_Integer aSelectedNb = aSelector.IndicesNb();
       for (Standard_Integer aBndIt = 0; aBndIt < aSelectedNb; ++aBndIt)
       {
-#ifdef HAVE_TBB
         // Break execution in case if flag was raised by another thread
         if (*myStatus == BRepMesh_SelfIntersectingWire)
           return;
-#endif
 
         const Standard_Integer aSegmentId2 = aSelected(aBndIt);
         const BRepMesh::Segment& aSegment2 = aWireSegments2->Value(aSegmentId2);
@@ -154,10 +123,9 @@ void BRepMesh_WireInterferenceChecker::operator ()(
               continue;
           }
 
-#ifdef HAVE_TBB
           Standard_Mutex::Sentry aSentry(myMutex);
-#endif
           *myStatus = BRepMesh_SelfIntersectingWire;
+
           return;
         }
       }
index 1bfac79..03e7055 100644 (file)
 #include <BRepMesh_WireChecker.hxx>
 #include <BRepMesh_Status.hxx>
 
-#ifdef HAVE_TBB
-  // paralleling using Intel TBB
-  #include <tbb/blocked_range.h>
-#endif
-
 //! Auxilary class implementing functionality for 
 //! checking interference between two discretized wires.
 class BRepMesh_WireInterferenceChecker
@@ -43,7 +38,6 @@ public:
     Same
   };
 
-#ifdef HAVE_TBB
   //! Constructor
   //! @param theWires wires that should be checked.
   //! @param theStatus shared flag to set status of the check.
@@ -51,19 +45,7 @@ public:
   BRepMesh_WireInterferenceChecker(
     const BRepMesh::Array1OfSegmentsTree& theWires,
     BRepMesh_Status*                      theStatus,
-    Standard_Mutex*                       theMutex);
-
-  //! Checker's body.
-  //! @param theWireRange range of wires to be checked.
-  void operator ()(const tbb::blocked_range<Standard_Integer>& theWireRange) const;
-#else
-  //! Constructor
-  //! @param theWires wires that should be checked.
-  //! @param theStatus shared flag to set status of the check.
-  BRepMesh_WireInterferenceChecker(
-    const BRepMesh::Array1OfSegmentsTree& theWires,
-    BRepMesh_Status*                      theStatus);
-#endif
+    Standard_Mutex*                       theMutex = NULL);
 
   //! Checker's body.
   //! @param theWireId Id of discretized wire to be checked.
@@ -79,10 +61,7 @@ private:
 private:
   const BRepMesh::Array1OfSegmentsTree& myWires;
   BRepMesh_Status*                      myStatus;
-
-#ifdef HAVE_TBB
   Standard_Mutex*                       myMutex;
-#endif
 };
 
 #endif
index 99b0e08..bff7818 100644 (file)
@@ -83,7 +83,6 @@ void MeshTest::PluginCommands(Draw_Interpretor& theCommands)
     __FILE__, mpparallel, g);
   theCommands.Add("triarea","shape [eps]  (computes triangles and surface area)",__FILE__, triarea, g);
   theCommands.Add("tricheck", "shape   (checks triangulation of shape)", __FILE__, tricheck, g);
-  
 }
 
 //=======================================================================
index e69de29..ca15c4d 100755 (executable)
@@ -0,0 +1 @@
+CSF_TBB
\ No newline at end of file
index eadc937..fca32d9 100755 (executable)
@@ -17,5 +17,7 @@ OSD_MAllocHook.cxx
 OSD_MAllocHook.hxx
 OSD_MemInfo.hxx
 OSD_MemInfo.cxx
+OSD_Parallel.hxx
+OSD_Parallel.cxx
 OSD_OpenFile.hxx
 OSD_OpenFile.cxx
diff --git a/src/OSD/OSD_Parallel.cxx b/src/OSD/OSD_Parallel.cxx
new file mode 100644 (file)
index 0000000..8b80fba
--- /dev/null
@@ -0,0 +1,93 @@
+// Created on: 2014-08-19
+// Created by: Alexander Zaikin
+// Copyright (c) 1996-1999 Matra Datavision
+// Copyright (c) 2013-2014 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <OSD_Parallel.hxx>
+
+#ifdef _WIN32
+    #include <windows.h>
+    #include <process.h>
+#else
+    #include <sys/types.h>
+
+    #ifdef __sun
+        #include <sys/processor.h>
+        #include <sys/procset.h>
+    #else
+        #include <sched.h>
+    #endif
+#endif
+
+#ifdef _WIN32
+namespace {
+  // for a 64-bit app running under 64-bit Windows, this is FALSE
+  static bool isWow64()
+  {
+    typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE , PBOOL);
+    BOOL bIsWow64 = FALSE;
+    HMODULE aKern32Module = GetModuleHandleW(L"kernel32");
+    LPFN_ISWOW64PROCESS aFunIsWow64 = (aKern32Module == NULL) ? (LPFN_ISWOW64PROCESS )NULL
+      : (LPFN_ISWOW64PROCESS)GetProcAddress(aKern32Module, "IsWow64Process");
+
+    return aFunIsWow64 != NULL &&
+           aFunIsWow64(GetCurrentProcess(), &bIsWow64) &&
+           bIsWow64 != FALSE;
+  }
+}
+#endif
+
+//=======================================================================
+//function : NbLogicalProcessors
+//purpose  : Returns number of logical proccessors.
+//=======================================================================
+Standard_Integer OSD_Parallel::NbLogicalProcessors()
+{
+  static Standard_Integer aNumLogicalProcessors = 0;
+  if ( aNumLogicalProcessors != 0 )
+  {
+    return aNumLogicalProcessors;
+  }
+#ifdef _WIN32
+  // GetSystemInfo() will return the number of processors in a data field in a SYSTEM_INFO structure.
+  SYSTEM_INFO aSysInfo;
+  if ( isWow64() )
+  {
+    typedef BOOL (WINAPI *LPFN_GSI)(LPSYSTEM_INFO );
+    HMODULE aKern32 = GetModuleHandleW(L"kernel32");
+    LPFN_GSI aFuncSysInfo = (LPFN_GSI )GetProcAddress(aKern32, "GetNativeSystemInfo");
+    // So, they suggest 32-bit apps should call this instead of the other in WOW64
+    if ( aFuncSysInfo != NULL )
+    {
+      aFuncSysInfo(&aSysInfo);
+    }
+    else
+    {
+      GetSystemInfo(&aSysInfo);
+    }
+  }
+  else
+  {
+    GetSystemInfo(&aSysInfo);
+  }
+  aNumLogicalProcessors = aSysInfo.dwNumberOfProcessors;
+#else
+  // These are the choices. We'll check number of processors online.
+  // _SC_NPROCESSORS_CONF   Number of processors configured
+  // _SC_NPROCESSORS_MAX    Max number of processors supported by platform
+  // _SC_NPROCESSORS_ONLN   Number of processors online
+  aNumLogicalProcessors = (Standard_Integer)sysconf(_SC_NPROCESSORS_ONLN);
+#endif
+  return aNumLogicalProcessors;
+}
diff --git a/src/OSD/OSD_Parallel.hxx b/src/OSD/OSD_Parallel.hxx
new file mode 100644 (file)
index 0000000..7ac171a
--- /dev/null
@@ -0,0 +1,298 @@
+// Copyright (c) 2013-2014 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef OSD_Parallel_HeaderFile
+#define OSD_Parallel_HeaderFile
+
+#include <OSD_Thread.hxx>
+#include <Standard_Mutex.hxx>
+#include <Standard_NotImplemented.hxx>
+#include <Standard_Atomic.hxx>
+#include <NCollection_Array1.hxx>
+
+#ifdef HAVE_TBB
+#include <tbb/parallel_for.h>
+#include <tbb/parallel_for_each.h>
+#include <tbb/blocked_range.h>
+#endif
+
+//! @class OSD_Parallel
+//! @brief Simplifies code parallelization.
+//!
+//! The Class provides an interface of parallel processing "for" and "foreach" loops.
+//! These primitives encapsulates complete logic for creating and managing parallel context of loops.
+//! Moreover the primitives may be a wrapper for some primitives from 3rd-party library - TBB.
+//! To use it is necessary to implement TBB like interface which is based on functors.
+//!
+//! @code
+//! class Functor
+//! {
+//! public:
+//!   void operator() ([proccesing instance]) const
+//!   {
+//!     //...
+//!   }
+//! };
+//! @endcode
+//!
+//! In the body of the operator () should be implemented thread-safe logic of computations that can be performed in parallel context.
+//! If parallelized loop iterates on the collections with direct access by index (such as Vector, Array),
+//! it is more efficient to use the primitive ParallelFor (because it has no critical section).
+class OSD_Parallel
+{
+  //! Auxiliary class which ensures exclusive
+  //! access to iterators of processed data pool.
+  template <typename Value>
+  class Range
+  {
+  public: //! @name public methods
+
+    typedef Value Iterator;
+
+    //! Constructor
+    Range(const Value& theBegin, const Value& theEnd)
+    : myBegin(theBegin),
+      myEnd  (theEnd),
+      myIt   (theBegin)
+    {
+    }
+
+    //! Returns const link on the first element.
+    inline const Value& Begin() const
+    {
+      return myBegin;
+    }
+
+    //! Returns const link on the last element.
+    inline const Value& End() const
+    {
+      return myEnd;
+    }
+
+    //! Returns first non processed element or end.
+    //! Thread-safe method.
+    inline Iterator It() const
+    {
+      Standard_Mutex::Sentry aMutex( myMutex );
+      return ( myIt != myEnd ) ? myIt++ : myEnd;
+    }
+
+  private: //! @name private methods
+
+    //! Empty copy constructor
+    Range(const Range& theCopy);
+
+    //! Empty copy operator.
+    Range& operator=(const Range& theCopy);
+
+  private: //! @name private fields
+
+    const Value&           myBegin; //!< Fisrt element of range.
+    const Value&           myEnd;   //!< Last element of range.
+    mutable Value          myIt;    //!< First non processed element of range.
+    mutable Standard_Mutex myMutex; //!< Access controller for the first non processed element.
+  };
+
+  //! Auxiliary wrapper class for thread function.
+  template <typename Functor, typename InputIterator>
+  class Task
+  {
+  public: //! @name public methods
+
+    //! Constructor.
+    Task(const Functor& thePerformer, Range<InputIterator>& theRange)
+    : myPerformer(thePerformer),
+      myRange    (theRange)
+    {
+    }
+
+    //! Method is executed in the context of thread,
+    //! so this method defines the main calculations.
+    static Standard_Address RunWithIterator(Standard_Address theTask)
+    {
+      Task<Functor, InputIterator>& aTask =
+        *( static_cast< Task<Functor, InputIterator>* >(theTask) );
+
+      const Range<InputIterator>& aData( aTask.myRange );
+      typename Range<InputIterator>::Iterator i = aData.It();
+
+      for ( ; i != aData.End(); i = aData.It() )
+      {
+        aTask.myPerformer(*i);
+      }
+
+      return NULL;
+    }
+
+    //! Method is executed in the context of thread,
+    //! so this method defines the main calculations.
+    static Standard_Address RunWithIndex(Standard_Address theTask)
+    {
+      Task<Functor, InputIterator>& aTask =
+        *( static_cast< Task<Functor, Standard_Integer>* >(theTask) );
+
+      const Range<Standard_Integer>& aData( aTask.myRange );
+      Standard_Integer i = aData.It();
+
+      for ( ; i < aData.End(); i = aData.It())
+      {
+        aTask.myPerformer(i);
+      }
+
+      return NULL;
+    }
+
+  private: //! @name private methods
+
+    //! Empty copy constructor.
+    Task(const Task& theCopy);
+
+    //! Empty copy operator.
+    Task& operator=(const Task& theCopy);
+
+  private: //! @name private fields
+
+    const Functor&              myPerformer; //!< Link on functor.
+    const Range<InputIterator>& myRange;     //!< Link on processed data block.
+  };
+
+public: //! @name public methods
+
+  //! Returns number of logical proccesrs.
+  Standard_EXPORT static Standard_Integer NbLogicalProcessors();
+
+  //! Simple primitive for parallelization of "foreach" loops.
+  template <typename InputIterator, typename Functor>
+  static void ForEach( InputIterator  theBegin,
+                       InputIterator  theEnd,
+                       const Functor& theFunctor,
+                       const Standard_Boolean isForceSingleThreadExecution
+                         = Standard_False );
+
+  //! Simple primitive for parallelization of "for" loops.
+  template <typename Functor>
+  static void For( const Standard_Integer theBegin,
+                   const Standard_Integer theEnd,
+                   const Functor&         theFunctor,
+                   const Standard_Boolean isForceSingleThreadExecution
+                     = Standard_False );
+};
+
+//=======================================================================
+//function : OSD_Parallel::Range::It
+//purpose  : Template concretization.
+//=======================================================================
+template<> inline Standard_Integer OSD_Parallel::Range<Standard_Integer>::It() const
+{
+  return Standard_Atomic_Increment( reinterpret_cast<volatile int*>(&myIt) ) - 1;
+}
+
+//=======================================================================
+//function : ParallelForEach
+//purpose  : 
+//=======================================================================
+template <typename InputIterator, typename Functor>
+void OSD_Parallel::ForEach( InputIterator          theBegin,
+                            InputIterator          theEnd,
+                            const Functor&         theFunctor,
+                            const Standard_Boolean isForceSingleThreadExecution )
+{
+  if ( isForceSingleThreadExecution )
+  {
+    for ( InputIterator it(theBegin); it != theEnd; it++ )
+      theFunctor(*it);
+
+    return;
+  }
+  #ifdef HAVE_TBB
+  {
+    try
+    {
+      tbb::parallel_for_each(theBegin, theEnd, theFunctor);
+    }
+    catch ( tbb::captured_exception& anException )
+    {
+      Standard_NotImplemented::Raise(anException.what());
+    }
+  }
+  #else
+  {
+    Range<InputIterator> aData(theBegin, theEnd);
+    Task<Functor, InputIterator> aTask(theFunctor, aData);
+
+    const Standard_Integer aNbThreads = OSD_Parallel::NbLogicalProcessors();
+    NCollection_Array1<OSD_Thread> aThreads(0, aNbThreads - 1);
+
+    for ( Standard_Integer i = 0; i < aNbThreads; ++i )
+    {
+      OSD_Thread& aThread = aThreads(i);
+      aThread.SetFunction(&Task<Functor, InputIterator>::RunWithIterator);
+      aThread.Run(&aTask);
+    }
+
+    for ( Standard_Integer i = 0; i < aNbThreads; ++i )
+      aThreads(i).Wait();
+  }
+  #endif
+}
+
+//=======================================================================
+//function : ParallelFor
+//purpose  : 
+//=======================================================================
+template <typename Functor>
+void OSD_Parallel::For( const Standard_Integer theBegin,
+                        const Standard_Integer theEnd,
+                        const Functor&         theFunctor,
+                        const Standard_Boolean isForceSingleThreadExecution )
+{
+  if ( isForceSingleThreadExecution )
+  {
+    for ( Standard_Integer i = theBegin; i < theEnd; ++i )
+      theFunctor(i);
+
+    return;
+  }
+  #ifdef HAVE_TBB
+  {
+    try
+    {
+      tbb::parallel_for( theBegin, theEnd, theFunctor );
+    }
+    catch ( tbb::captured_exception& anException )
+    {
+      Standard_NotImplemented::Raise(anException.what());
+    }
+  }
+  #else
+  {
+    Range<Standard_Integer> aData(theBegin, theEnd);
+    Task<Functor, Standard_Integer> aTask(theFunctor, aData);
+
+    const Standard_Integer aNbThreads = OSD_Parallel::NbLogicalProcessors();
+    NCollection_Array1<OSD_Thread> aThreads(0, aNbThreads - 1);
+
+    for ( Standard_Integer i = 0; i < aNbThreads; ++i )
+    {
+      OSD_Thread& aThread = aThreads(i);
+      aThread.SetFunction(&Task<Functor, Standard_Integer>::RunWithIndex);
+      aThread.Run(&aTask);
+    }
+
+    for ( Standard_Integer i = 0; i < aNbThreads; ++i )
+      aThreads(i).Wait();
+  }
+  #endif
+}
+
+#endif
index 512bb22..2411e11 100755 (executable)
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
-#ifdef HAVE_TBB
-  // On Windows, function TryEnterCriticalSection has appeared in Windows NT
-  // and is surrounded by #ifdef in MS VC++ 7.1 headers.
-  // Thus to use it we need to define appropriate macro saying that we will
-  // run on Windows NT 4.0 at least
-  #if defined(_WIN32) && !defined(_WIN32_WINNT)
-    #define _WIN32_WINNT 0x0501
-  #endif
-
-  #include <tbb/tbb.h>
-#endif
+#include <Standard_Assert.hxx>
+#include <OSD_Parallel.hxx>
 
 #include <OpenGl_SceneGeometry.hxx>
 
@@ -208,8 +199,6 @@ void OpenGl_RaytraceGeometry::Clear()
   Materials.swap (anEmptyMaterials);
 }
 
-#ifdef HAVE_TBB
-
 struct OpenGL_BVHParallelBuilder
 {
   BVH_ObjectSet<Standard_ShortReal, 3>* Set;
@@ -220,23 +209,16 @@ struct OpenGL_BVHParallelBuilder
     //
   }
 
-  void operator() (const tbb::blocked_range<size_t>& theRange) const
+  void operator() (const Standard_Integer theObjectIdx) const
   {
-    for (size_t anObjectIdx = theRange.begin(); anObjectIdx != theRange.end(); ++anObjectIdx)
-    {
-      OpenGl_TriangleSet* aTriangleSet = dynamic_cast<OpenGl_TriangleSet*> (
-        Set->Objects().ChangeValue (static_cast<Standard_Integer> (anObjectIdx)).operator->());
+    OpenGl_TriangleSet* aTriangleSet = dynamic_cast<OpenGl_TriangleSet*> (
+      Set->Objects().ChangeValue (static_cast<Standard_Integer> (theObjectIdx)).operator->());
 
-      if (aTriangleSet != NULL)
-      {
-        aTriangleSet->BVH();
-      }
-    }
+    if (aTriangleSet != NULL)
+      aTriangleSet->BVH();
   }
 };
 
-#endif
-
 // =======================================================================
 // function : ProcessAcceleration
 // purpose  : Performs post-processing of high-level BVH
@@ -254,12 +236,7 @@ Standard_Boolean OpenGl_RaytraceGeometry::ProcessAcceleration()
   aTimer.Start();
 #endif
 
-#ifdef HAVE_TBB
-  // If Intel TBB is available, perform the preliminary
-  // construction of bottom-level scene BVHs
-  tbb::parallel_for (tbb::blocked_range<size_t> (0, Size()),
-    OpenGL_BVHParallelBuilder (this));
-#endif
+  OSD_Parallel::For(0, Size(), OpenGL_BVHParallelBuilder(this));
 
   myBottomLevelTreeDepth = 0;
 
index 67f8d9e..bebcdab 100755 (executable)
@@ -39,8 +39,9 @@
 #include <cstdio>
 #include <cmath>
 #include <iostream>
-#include <OSD_PerfMeter.hxx>
 #include <OSD_Timer.hxx>
+#include <OSD_Parallel.hxx>
+#include <OSD_PerfMeter.hxx>
 #include <BRepPrimAPI_MakeBox.hxx>
 #include <BRepPrimAPI_MakeSphere.hxx>
 #include <BRepAlgo_Cut.hxx>
@@ -157,32 +158,23 @@ static Standard_Integer OCC23237 (Draw_Interpretor& di, Standard_Integer /*argc*
   return 0;
 }
 
-#ifdef HAVE_TBB
-
-#include <tbb/blocked_range.h>
-#include <tbb/parallel_for.h>
-
 class IncrementerDecrementer
 {
 public:
     IncrementerDecrementer (Standard_Integer* theVal, Standard_Boolean thePositive) : myVal (theVal), myPositive (thePositive)
     {}
-    void operator() (const tbb::blocked_range<size_t>& r) const
+    void operator() (const size_t) const
     {
-        if (myPositive)
-            for (size_t i = r.begin(); i != r.end(); ++i)
-                Standard_Atomic_Increment (myVal);
-        else
-            for (size_t i = r.begin(); i != r.end(); ++i)
-                Standard_Atomic_Decrement (myVal);
+      if ( myPositive )
+        Standard_Atomic_Increment(myVal);
+      else
+        Standard_Atomic_Decrement(myVal);
     }
 private:
     Standard_Integer*   myVal;
-    Standard_Boolean   myPositive;
+    Standard_Boolean    myPositive;
 };
-#endif
 
-#ifdef HAVE_TBB
 static Standard_Integer OCC22980 (Draw_Interpretor& di, Standard_Integer /*argc*/, const char ** /*argv*/)
 {
   int aSum = 0;
@@ -200,26 +192,16 @@ static Standard_Integer OCC22980 (Draw_Interpretor& di, Standard_Integer /*argc*
   const int N = 1 << 24; //big enough to ensure concurrency
 
   //increment
-  tbb::parallel_for (tbb::blocked_range<size_t> (0, N), IncrementerDecrementer (&aSum, true));
+  OSD_Parallel::For(0, N, IncrementerDecrementer (&aSum, true));
   QCOMPARE (aSum, N);
 
   //decrement
-  tbb::parallel_for (tbb::blocked_range<size_t> (0, N), IncrementerDecrementer (&aSum, false));
+  OSD_Parallel::For(0, N, IncrementerDecrementer (&aSum, false));
   QCOMPARE (aSum, 0);
 
   return 0;
 }
 
-#else /* HAVE_TBB */
-
-static Standard_Integer OCC22980 (Draw_Interpretor& di, Standard_Integer /*argc*/, const char **argv)
-{
-  di << "Test skipped: command " << argv[0] << " requires TBB library\n";
-  return 0;
-}
-
-#endif /* HAVE_TBB */
-
 #include <TDocStd_Application.hxx>
 #include <XCAFApp_Application.hxx>
 #include <TDocStd_Document.hxx>
@@ -2902,6 +2884,92 @@ static Standard_Integer OCC25340 (Draw_Interpretor& /*theDI*/,
   return 0;
 }
 
+//=======================================================================
+//function : OCC24826
+//purpose  :
+//=======================================================================
+class ParallelTest_Saxpy
+{
+public:
+  typedef NCollection_Array1<Standard_Real> Vector;
+
+  //! Constructor
+  ParallelTest_Saxpy(const Vector& theX, Vector& theY, Standard_Real theScalar)
+  : myX(theX),
+    myY(theY),
+    myScalar(theScalar)
+  {
+  }
+
+  //! Dummy calculation
+  void operator() (const Standard_Integer theIndex) const
+  {
+    myY(theIndex) = myScalar * myX(theIndex) + myY(theIndex);
+  }
+
+private:
+  ParallelTest_Saxpy( const ParallelTest_Saxpy& );
+  ParallelTest_Saxpy& operator =( ParallelTest_Saxpy& );
+
+private:
+  const Vector&       myX;
+  Vector&             myY;
+  const Standard_Real myScalar;
+};
+
+//---------------------------------------------------------------------
+static Standard_Integer OCC24826(Draw_Interpretor& theDI,
+                                 Standard_Integer  trheArgc,
+                                 const char**      theArgv)
+{
+  if ( trheArgc != 2 )
+  {
+    theDI << "Usage: "
+          << theArgv[0]
+          << " vec_length\n";
+    return 1;
+  }
+
+  // Generate data;
+  Standard_Integer aLength = Draw::Atoi(theArgv[1]);
+
+  NCollection_Array1<Standard_Real> aX (0, aLength - 1);
+  NCollection_Array1<Standard_Real> anY(0, aLength - 1);
+
+  for ( Standard_Integer i = 0; i < aLength; ++i )
+  {
+    aX(i) = anY(i) = (Standard_Real) i;
+  }
+
+  OSD_Timer aTimer;
+
+  aTimer.Start();
+
+  //! Serial proccesing
+  for ( Standard_Integer i = 0; i < aLength; ++i )
+  {
+    anY(i) = 1e-6 * aX(i) + anY(i);
+  }
+
+  aTimer.Stop();
+  cout << "Processing time (sequential mode):\n";
+  aTimer.Show();
+
+  const ParallelTest_Saxpy aFunctor(aX, anY, 1e-6);
+
+  aTimer.Reset();
+  aTimer.Start();
+
+  // Parallel processing
+  OSD_Parallel::For(0, aLength, aFunctor);
+
+  aTimer.Stop();
+  cout << "Processing time (parallel mode):\n";
+  aTimer.Show();
+
+  return 0;
+}
+
 /*****************************************************************************/
 
 #include <GeomAPI_IntSS.hxx>
@@ -3328,6 +3396,7 @@ void QABugs::Commands_19(Draw_Interpretor& theCommands) {
                    __FILE__, OCC24925, group);
   theCommands.Add ("OCC23010", "OCC23010 STEP_file", __FILE__, OCC23010, group);
   theCommands.Add ("OCC25043", "OCC25043 shape", __FILE__, OCC25043, group);
+  theCommands.Add ("OCC24826,", "This test performs simple saxpy test.\n Usage: OCC24826 length", __FILE__, OCC24826, group);
   theCommands.Add ("OCC24606", "OCC24606 : Tests ::FitAll for V3d view ('vfit' is for NIS view)", __FILE__, OCC24606, group);
   theCommands.Add ("OCC25202", "OCC25202 res shape numF1 face1 numF2 face2", __FILE__, OCC25202, group);
   theCommands.Add ("OCC7570", "OCC7570 shape", __FILE__, OCC7570, group);
index 3c1332b..a4b94e2 100644 (file)
 #include <NCollection_IndexedDataMap.hxx>
 #include <Standard_Assert.hxx>
 #include <OSD_Timer.hxx>
-
-#ifdef HAVE_TBB
-  // On Windows, function TryEnterCriticalSection has appeared in Windows NT
-  // and is surrounded by #ifdef in MS VC++ 7.1 headers.
-  // Thus to use it we need to define appropriate macro saying that we will
-  // run on Windows NT 4.0 at least
-  #if ((defined(_WIN32) || defined(__WIN32__)) && !defined(_WIN32_WINNT))
-    #define _WIN32_WINNT 0x0501
-  #endif
-
-  #include <tbb/tbb.h>
-  #include <tbb/parallel_for.h>
-#endif
-
+#include <OSD_Parallel.hxx>
 #include <algorithm>
 #include <list>
 #include <set>
@@ -343,8 +330,6 @@ Standard_Boolean TestSort()
   return aResult;
 }
 
-#ifdef HAVE_TBB
-
 template <typename T>
 struct Invoker
 {
@@ -355,19 +340,19 @@ struct Invoker
 };
 
 //=======================================================================
-//function : TestTBB
+//function : TestParallel
 //purpose  :
 //=======================================================================
 template<class CollectionType, class StlType>
-Standard_Boolean TestTBB()
+Standard_Boolean TestParallel()
 {
   StlType* aVector (NULL);
   CollectionType* aCollec (NULL);
 
   CollectionFiller<CollectionType, StlType>::Perform (&aVector, &aCollec);
 
-  tbb::parallel_for_each (aVector->begin(), aVector->end(), Invoker<typename StlType::value_type>());
-  tbb::parallel_for_each (aCollec->begin(), aCollec->end(), Invoker<typename CollectionType::value_type>());
+  OSD_Parallel::ForEach(aVector->begin(), aVector->end(), Invoker<typename StlType::value_type>());
+  OSD_Parallel::ForEach(aCollec->begin(), aCollec->end(), Invoker<typename CollectionType::value_type>());
 
   typename StlType::iterator aVecIter = aVector->begin();
   typename CollectionType::iterator aColIter = aCollec->begin();
@@ -392,18 +377,18 @@ Standard_Boolean TestTBB()
 }
 
 //=======================================================================
-//function : TestDataMapTBB
+//function : TestDataMapParallel
 //purpose  :
 //=======================================================================
 template<class CollectionType, class T>
-Standard_Boolean TestDataMapTBB()
+Standard_Boolean TestDataMapParallel()
 {
   CollectionType* aCollec1 (NULL);
   CollectionType* aCollec2 (NULL);
 
   MapFiller<CollectionType, T>::Perform (&aCollec1, &aCollec2);
 
-  tbb::parallel_for_each (aCollec1->begin(), aCollec1->end(), Invoker<T>());
+  OSD_Parallel::ForEach(aCollec1->begin(), aCollec1->end(), Invoker<T>());
 
   // create OCCT-style iterator
   typename CollectionType::Iterator aOccIter (*aCollec2);
@@ -430,8 +415,6 @@ Standard_Boolean TestDataMapTBB()
   return aResult;
 }
 
-#endif
-
 //=======================================================================
 //function : TestMapIteration
 //purpose  :
@@ -605,18 +588,14 @@ static Standard_Integer QANListStlIterator (Draw_Interpretor&, Standard_Integer,
   std::cout << "NCollection_List<double> Replace:               " <<
     (aResult ? "SUCCESS" : "FAIL") << std::endl;
 
-#ifdef HAVE_TBB
-
-  aResult = TestTBB<NCollection_List<int>, std::list<int> >();
-  std::cout << "NCollection_List<int> TBB:                      " <<
+  aResult = TestParallel< NCollection_List<int>, std::list<int> >();
+  std::cout << "NCollection_List<int> Parallel:                 " <<
     (aResult ? "SUCCESS" : "FAIL") << std::endl;
 
-  aResult = TestTBB<NCollection_List<double>, std::list<double> >();
-  std::cout << "NCollection_List<double> TBB:                   " <<
+  aResult = TestParallel<NCollection_List<double>, std::list<double> >();
+  std::cout << "NCollection_List<double> Parallel:              " <<
     (aResult ? "SUCCESS" : "FAIL") << std::endl;
 
-#endif
-
   return 0;
 }
 
@@ -682,18 +661,14 @@ static Standard_Integer QANDataMapStlIterator (Draw_Interpretor&, Standard_Integ
   std::cout << "NCollection_DataMap<double> Iteration:          " <<
     (aResult ? "SUCCESS" : "FAIL") << std::endl;
 
-#ifdef HAVE_TBB
-  
-  aResult = TestDataMapTBB<NCollection_DataMap<Standard_Integer, Standard_Integer>, Standard_Integer>();
-  std::cout << "NCollection_DataMap<int> TBB:                   " <<
+  aResult = TestDataMapParallel<NCollection_DataMap<Standard_Integer, Standard_Integer>, Standard_Integer>();
+  std::cout << "NCollection_DataMap<int> Parallel:              " <<
     (aResult ? "SUCCESS" : "FAIL") << std::endl;
 
-  aResult = TestDataMapTBB<NCollection_DataMap<Standard_Real, Standard_Real>, Standard_Real>();
-  std::cout << "NCollection_DataMap<double> TBB:                " <<
+  aResult = TestDataMapParallel<NCollection_DataMap<Standard_Real, Standard_Real>, Standard_Real>();
+  std::cout << "NCollection_DataMap<double> Parallel:           " <<
     (aResult ? "SUCCESS" : "FAIL") << std::endl;
 
-#endif
-
   return 0;
 }
 
@@ -716,18 +691,14 @@ static Standard_Integer QANIndexedDataMapStlIterator (Draw_Interpretor&, Standar
   std::cout << "NCollection_IndexedDataMap<double> Iteration:   " <<
     (aResult ? "SUCCESS" : "FAIL") << std::endl;
 
-#ifdef HAVE_TBB
-
-  aResult = TestDataMapTBB<NCollection_IndexedDataMap<Standard_Integer, Standard_Integer>, Standard_Integer>();
-  std::cout << "NCollection_IndexedDataMap<int> TBB:            " <<
+  aResult = TestDataMapParallel<NCollection_IndexedDataMap<Standard_Integer, Standard_Integer>, Standard_Integer>();
+  std::cout << "NCollection_IndexedDataMap<int> Parallel:       " <<
     (aResult ? "SUCCESS" : "FAIL") << std::endl;
 
-  aResult = TestDataMapTBB<NCollection_IndexedDataMap<Standard_Real, Standard_Real>, Standard_Real>();
-  std::cout << "NCollection_IndexedDataMap<double> TBB:         " <<
+  aResult = TestDataMapParallel<NCollection_IndexedDataMap<Standard_Real, Standard_Real>, Standard_Real>();
+  std::cout << "NCollection_IndexedDataMap<double> Parallel:    " <<
     (aResult ? "SUCCESS" : "FAIL") << std::endl;
 
-#endif
-
   return 0;
 }
 
@@ -774,18 +745,14 @@ static Standard_Integer QANSequenceStlIterator (Draw_Interpretor&, Standard_Inte
   std::cout << "NCollection_Sequence<double> Reverse:           " <<
     (aResult ? "SUCCESS" : "FAIL") << std::endl;
 
-#ifdef HAVE_TBB
-
-  aResult = TestTBB<NCollection_Sequence<int>, std::list<int> >();
-  std::cout << "NCollection_Sequence<int> TBB:                  " <<
+  aResult = TestParallel<NCollection_Sequence<int>, std::list<int> >();
+  std::cout << "NCollection_Sequence<int> Parallel:             " <<
     (aResult ? "SUCCESS" : "FAIL") << std::endl;
 
-  aResult = TestTBB<NCollection_Sequence<double>, std::list<double> >();
-  std::cout << "NCollection_Sequence<double> TBB:               " <<
+  aResult = TestParallel<NCollection_Sequence<double>, std::list<double> >();
+  std::cout << "NCollection_Sequence<double> Parallel:          " <<
     (aResult ? "SUCCESS" : "FAIL") << std::endl;
 
-#endif
-
   return 0;
 }
 
@@ -841,18 +808,14 @@ static Standard_Integer QANVectorStlIterator (Draw_Interpretor&, Standard_Intege
   std::cout << "NCollection_Vector<double> Sort:                " <<
     (aResult ? "SUCCESS" : "FAIL") << std::endl;
 
-#ifdef HAVE_TBB
-
-  aResult = TestTBB<NCollection_Vector<int>, std::vector<int> >();
-  std::cout << "NCollection_Vector<int> TBB:                    " <<
+  aResult = TestParallel<NCollection_Vector<int>, std::vector<int> >();
+  std::cout << "NCollection_Vector<int> Parallel:               " <<
     (aResult ? "SUCCESS" : "FAIL") << std::endl;
 
-  aResult = TestTBB<NCollection_Vector<double>, std::vector<double> >();
-  std::cout << "NCollection_Vector<double> TBB:                 " <<
+  aResult = TestParallel<NCollection_Vector<double>, std::vector<double> >();
+  std::cout << "NCollection_Vector<double> Parallel:            " <<
     (aResult ? "SUCCESS" : "FAIL") << std::endl;
 
-#endif
-
   return 0;
 }
 
@@ -908,18 +871,14 @@ static Standard_Integer QANArray1StlIterator (Draw_Interpretor&, Standard_Intege
   std::cout << "NCollection_Array1<double> Sort:                " <<
     (aResult ? "SUCCESS" : "FAIL") << std::endl;
 
-#ifdef HAVE_TBB
-
-  aResult = TestTBB<NCollection_Array1<int>, std::vector<int> >();
-  std::cout << "NCollection_Array1<int> TBB:                    " <<
+  aResult = TestParallel<NCollection_Array1<int>, std::vector<int> >();
+  std::cout << "NCollection_Array1<int> Parallel:               " <<
     (aResult ? "SUCCESS" : "FAIL") << std::endl;
 
-  aResult = TestTBB<NCollection_Array1<double>, std::vector<double> >();
-  std::cout << "NCollection_Array1<double> TBB:                 " <<
+  aResult = TestParallel<NCollection_Array1<double>, std::vector<double> >();
+  std::cout << "NCollection_Array1<double> Parallel:            " <<
     (aResult ? "SUCCESS" : "FAIL") << std::endl;
 
-#endif
-
   return 0;
 }