]> OCCT Git - occt-copy.git/commitdiff
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 8986652964eb8e8877bcfec2c607d9facaf9867e..fbeb55f4e2d4860c0fd0ab2d4eb6be004d4e4069 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 eb24e6b96d2fa7559983f4d1247a76688383155f..7ba2e5c29b2cfe1d1b6728c84f8f1b1c703ed1c9 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 65d8d7e6e040c3abd169c87aac6a57f31b870c6b..6b2605ed5b041d258921b445b0e80b542eccb2bf 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 c0584d19644fbb174de72a87223fb518518490cb..69cfa25e3813f113df91387ffeb0ba773b372eec 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 c20af593758a85c2fdc78a2e4018ec6d83592744..bbafce4fbd33721c8f2a38219edda99d49866bdb 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 5b92b5eb1cddb9abea8466ba4dcc71045c185523..1bd5fc03195859f4af808a7ea5a38ca3fc262213 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 b3f45d36ef6dd162c3c839d71712ce5606e0015c..66aec9f8e89299e018c0ea4771e0b12a3d2a4810 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 4e1c129fbdff16951c86e7adbea87a5aee56ee96..738f9336e0c1d0a1a105b9405a0015f659958176 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 12b5e861dcedd511dc75fad407490528d9057b0c..18b163103df5c61a642ac86ef6543fe88526227f 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 2cbdec3eee45255c1bb6e8dc1be26ae57664754d..e3208e6b9b15646cb783d6cb0b9450167cfd3b40 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 a27392f55d23056d9d8b738be6c6b40dd877166d..5c78dec61ec89714e028d4562785cebf5d8ddc2b 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 d5c8b506d61cd1fc27725c65beb2137f0f4dc369..16f5323a2bb069d03aca72e30b29674c3fb2c548 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 412ba9952d7ccc6ac194abd8fc8004cb287ab6b5..8be3e7ddbdc7089afe9fdd056f705b3662d4c601 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 29237d34e8f9b1e3339fd7945749c9c0c8ed7140..9029348157789c0c75f72310610feb77a089e58a 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 7da70dc77f8e51d993496843be779073e82dc19a..2c38c9d48505c209c20e48f3fee06050ad704a94 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 d8d69ce0c444583fd800764af2e90943b906ebe4..29c253c14f1157a734263283eebd4806a295adf8 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 c478aee3a1a63f31dc2bf17990ea0ee04f21a0ab..fad66328985849ea09a90b72793ed70b8c6ea6b0 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 cacb2276ac1e91c1d9024e283fc0bc7670e91456..6fa2144fef2128bb7f2b2d3a2107a3a474a2afac 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 933a8b74c7281b3f15ac706ad657293a5af04cb3..126e671f8794ef17d44c09d20588c3f8b0871dc0 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 c7fefa84f6d428e5b0ab1fa910c147c04596debc..8593287562e3e419eb04bcbea748f0842a8e010b 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 bed115d467189108762f3974811d656b252322a8..007ecf35f506818542ac8042a29dc3eb6e671a6e 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 a8273b3f08b0d78c3b8502232f21ddf4ee02b19d..326dc8c3accf9abd46b8fe3069350568054b6163 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 1bfac79f15b93f8038b56d358c732ce925e63d56..03e7055ed405d76355512e698db89a296ddfdda4 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 99b0e0817ad76ac1d9d1ad2a385e6f218ed2f444..bff781887d56eefbf4c6484e75ea45c9a32b4b27 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 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..ca15c4ddef7d18c584189a09a5c5f6dc9fb22505 100755 (executable)
@@ -0,0 +1 @@
+CSF_TBB
\ No newline at end of file
index eadc93711e295876c03132a145804357e54fec51..fca32d9ebcbaa345eab9c6055104befb8fdd4bda 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 512bb22136d3d22ee40a6c0e559b15d6cc4c2568..2411e1162fabf8f2413958bef5068fa67b87274f 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 67f8d9e24683b5ee2109068d5ab0265500f28b25..bebcdab56b5516a348f632e1a2bec1277f71b167 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 3c1332bae4e67c0ef7af2669f99682a654c9fdce..a4b94e2f92c6ba3ab182e5bece8920689e340f0d 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;
 }