8f79013460231401bd19baa7404aa69cf91aa780
[occt.git] / src / BOPCol / BOPCol_TBB.hxx
1 // Created by: Peter KURNEV
2 // Copyright (c) 1999-2013 OPEN CASCADE SAS
3 //
4 // This file is part of Open CASCADE Technology software library.
5 //
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
11 //
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
14
15 #ifndef _BOPDS_Col_HeaderFile
16 #define _BOPDS_Col_HeaderFile
17
18 #include <Standard_Macro.hxx>
19 #include <Standard_NotImplemented.hxx>
20
21 #ifdef HAVE_TBB
22 // On Windows, function TryEnterCriticalSection has appeared in Windows NT
23 // and is surrounded by #ifdef in MS VC++ 7.1 headers.
24 // Thus to use it we need to define appropriate macro saying that we wil
25 // run on Windows NT 4.0 at least
26 #if ((defined(_WIN32) || defined(__WIN32__)) && !defined(_WIN32_WINNT))
27   #define _WIN32_WINNT 0x0501
28 #endif
29
30 #include <tbb/tbb.h>
31 using namespace tbb;
32
33 #define flexible_range blocked_range
34 #define flexible_for   parallel_for
35
36 #else // not HAVE_TBB
37
38 #define flexible_range serial_range
39 #define flexible_for   serial_for
40
41 //=======================================================================
42 //class : serial_range
43 //purpose  : 
44 //=======================================================================
45 template <class Type> class serial_range {
46  public:
47   serial_range(const Type& aBegin,
48                const Type& aEnd)
49     : myBegin(aBegin), myEnd(aEnd) {
50   }
51   //
52   ~serial_range() {
53   }
54   //
55   const Type& begin() const{
56     return myBegin;
57   }
58   //
59   const Type& end() const{
60     return myEnd;
61   };
62   //
63  protected:
64   Type myBegin;
65   Type myEnd;
66 };
67
68 //=======================================================================
69 //function : serial_for
70 //purpose  : 
71 //=======================================================================
72 template<typename Range, typename Body>
73 static void serial_for( const Range& range, const Body& body ) {
74   body.operator()(range);
75 };
76 #endif // not HAVE_TBB
77 //
78 // 2. Implementation of Functors/Starters
79 //
80 // 2.1. Pure version
81 //
82 //=======================================================================
83 //class    : BOPCol_TBBFunctor
84 //purpose  : 
85 //=======================================================================
86 template <class TypeSolver, 
87           class TypeSolverVector> class BOPCol_TBBFunctor {
88  
89  public:
90   BOPCol_TBBFunctor(TypeSolverVector& aV) 
91     : myPV(&aV) {
92   }
93   //
94   ~BOPCol_TBBFunctor() {
95   }
96   //
97   void operator()( const flexible_range<Standard_Integer>& aBR ) const{
98     Standard_Integer i, iBeg, iEnd;
99     //
100     TypeSolverVector& aV=*myPV;
101     //
102     iBeg=aBR.begin();
103     iEnd=aBR.end();
104     for(i=iBeg; i!=iEnd; ++i) {
105       TypeSolver& aSolver=aV(i);
106       //
107       aSolver.Perform();
108     }
109   }
110   //
111  protected:
112   TypeSolverVector* myPV;
113 };
114 //=======================================================================
115 //class    : BOPCol_TBBCnt
116 //purpose  : 
117 //=======================================================================
118 template <class TypeFunctor, 
119           class TypeSolverVector> class BOPCol_TBBCnt {
120  public:
121   //-------------------------------
122   // Perform
123   Standard_EXPORT 
124     static void Perform(const Standard_Boolean bRunParallel,
125                         TypeSolverVector& aV) {
126     //
127     TypeFunctor aFunctor(aV);
128     Standard_Integer aNb=aV.Extent();
129     //
130     if (bRunParallel) {
131 #ifdef HAVE_TBB
132       try {
133         flexible_for(flexible_range<Standard_Integer>(0,aNb), aFunctor);
134       }
135       //
136       catch( captured_exception&  ) {
137         Standard_NotImplemented::Raise("");
138       } 
139       catch( ... ) {
140         Standard_NotImplemented::Raise("");
141       }
142 #else // not HAVE_TBB
143       flexible_for(flexible_range<Standard_Integer>(0,aNb), aFunctor);
144 #endif      
145     }
146     else {
147       aFunctor.operator()(flexible_range<Standard_Integer>(0,aNb));
148     }
149   }
150 };
151 //
152 // 2.2. Context dependent version
153 //
154
155 //=======================================================================
156 //class    : BOPCol_TBBContextFunctor
157 //purpose  : 
158 //=======================================================================
159 template <class TypeSolver, 
160           class TypeSolverVector,
161           class TypeContext, 
162           typename TN> class BOPCol_TBBContextFunctor  {
163  
164  public:
165   BOPCol_TBBContextFunctor(TypeSolverVector& aV) 
166     : myPV(&aV) {
167   }
168   //
169   ~BOPCol_TBBContextFunctor() {
170   }
171   //
172   void SetContext(TypeContext& aCtx) {
173     myContext=aCtx;
174   }
175   //
176   void operator()( const flexible_range<Standard_Integer>& aBR ) const{
177     Standard_Integer i, iBeg, iEnd;
178     TypeContext aCtx;
179     //
180     if (myContext.IsNull()) {
181       aCtx=new TN
182         (NCollection_BaseAllocator::CommonBaseAllocator());
183     }
184     else {
185       aCtx=myContext;
186     }
187     //
188     TypeSolverVector& aV=*myPV;
189     //
190     iBeg=aBR.begin();
191     iEnd=aBR.end();
192     for(i=iBeg; i!=iEnd; ++i) {
193       TypeSolver& aSolver=aV(i);
194       //
195       aSolver.SetContext(aCtx);
196       aSolver.Perform();
197     }
198   }
199   //
200  protected:
201   TypeSolverVector* myPV;
202   TypeContext myContext;
203   //
204 };
205
206 //=======================================================================
207 //class    : BOPCol_TBBContextCnt
208 //purpose  : 
209 //=======================================================================
210 template <class TypeFunctor, 
211           class TypeSolverVector,
212           class TypeContext> class BOPCol_TBBContextCnt {
213  public:
214   //-------------------------------
215   // Perform
216   Standard_EXPORT 
217     static void Perform(const Standard_Boolean bRunParallel,
218                         TypeSolverVector& aV,
219                         TypeContext& aCtx) {
220     //
221     TypeFunctor aFunctor(aV);
222     Standard_Integer aNb=aV.Extent();
223     //
224     if (bRunParallel) {
225 #ifdef HAVE_TBB
226       try {
227         flexible_for(flexible_range<Standard_Integer>(0,aNb), aFunctor);
228       }
229       //
230       catch(captured_exception& ) {
231         //cout<<" captured_exception: " << ex.what() << endl;
232         Standard_NotImplemented::Raise("");
233       } 
234       catch( ... ) {
235         Standard_NotImplemented::Raise("");
236       }
237 #else // not HAVE_TBB
238       flexible_for(flexible_range<Standard_Integer>(0,aNb), aFunctor);
239 #endif      
240     }
241     else {
242       aFunctor.SetContext(aCtx);
243       aFunctor.operator()(flexible_range<Standard_Integer>(0,aNb));
244     }
245   }
246 };
247
248 #endif