0fddce5fbd7a859f0257f7bdc5ea855a3b03d805
[occt.git] / src / BOPTools / BOPTools_Parallel.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 _BOPTools_Parallel_HeaderFile
16 #define _BOPTools_Parallel_HeaderFile
17
18 #include <Standard_Macro.hxx>
19 #include <Standard_NotImplemented.hxx>
20 #include <OSD_Parallel.hxx>
21 #include <NCollection_DataMap.hxx>
22 #include <Standard_Mutex.hxx>
23 #include <OSD_Thread.hxx>
24
25 //
26 // 1. Implementation of Functors/Starters
27 //
28 // 1.1. Pure version
29 //
30
31 //=======================================================================
32 //class    : BOPTools_Functor
33 //purpose  : 
34 //=======================================================================
35 template <class TypeSolver, class TypeSolverVector>
36 class BOPTools_Functor
37 {
38 public:
39   //! Constructor.
40   explicit BOPTools_Functor(TypeSolverVector& theSolverVec) 
41   : mySolvers(theSolverVec) {}
42
43   //! Defines functor interface.
44   void operator() (const Standard_Integer theIndex) const
45   {
46     TypeSolver& aSolver = mySolvers(theIndex);
47     aSolver.Perform();
48   }
49
50 private:
51   BOPTools_Functor(const BOPTools_Functor&);
52   BOPTools_Functor& operator= (const BOPTools_Functor&);
53
54 private:
55   TypeSolverVector& mySolvers;
56 };
57
58 //=======================================================================
59 //class    : BOPTools_Cnt
60 //purpose  : 
61 //=======================================================================
62 template <class TypeFunctor, class TypeSolverVector>
63 class BOPTools_Cnt
64 {
65 public:
66   static void Perform( const Standard_Boolean isRunParallel,
67                        TypeSolverVector&      theSolverVector )
68   {
69     TypeFunctor aFunctor(theSolverVector);
70     OSD_Parallel::For(0, theSolverVector.Length(), aFunctor, !isRunParallel);
71   }
72 };
73
74 //
75 // 1.2. Context dependent version
76 //
77
78 //=======================================================================
79 //class    : BOPTools_ContextFunctor
80 //purpose  : 
81 //=======================================================================
82 template <class TypeSolver,  class TypeSolverVector,
83           class TypeContext, typename TN>
84 class BOPTools_ContextFunctor
85 {
86   //! Auxiliary thread ID  hasher.
87   struct Hasher
88   {
89     static Standard_Integer HashCode(const Standard_ThreadId theKey,
90                                      const Standard_Integer  Upper)
91     {
92       return ::HashCode((Standard_Size)theKey, Upper);
93     }
94
95     static Standard_Boolean IsEqual(const Standard_ThreadId theKey1,
96                                     const Standard_ThreadId theKey2)
97     {
98       return theKey1 == theKey2;
99     }
100   };
101
102   typedef NCollection_DataMap<Standard_ThreadId, TypeContext, Hasher> ContextMap;
103
104 public:
105
106   //! Constructor
107   explicit BOPTools_ContextFunctor( TypeSolverVector& theVector )
108   : mySolverVector(theVector) {}
109
110   //! Binds main thread context
111   void SetContext( TypeContext& theContext )
112   {
113     myContexts.Bind(OSD_Thread::Current(), theContext);
114   }
115
116   //! Returns current thread context
117   TypeContext& GetThreadContext() const
118   {
119     const Standard_ThreadId aThreadID = OSD_Thread::Current();
120     if ( myContexts.IsBound(aThreadID) )
121     {
122       TypeContext& aContext = myContexts(aThreadID);
123       if ( aContext.IsNull() == Standard_False )
124         return aContext;
125     }
126
127     // Create new context
128     TypeContext aContext = new TN
129       ( NCollection_BaseAllocator::CommonBaseAllocator() );
130
131     Standard_Mutex::Sentry aLocker(myMutex);
132     myContexts.Bind(aThreadID, aContext);
133
134     return myContexts(aThreadID);
135   }
136
137   //! Defines functor interface
138   void operator()( const Standard_Integer theIndex ) const
139   {
140     TypeContext& aContext = GetThreadContext();
141     TypeSolver&  aSolver  = mySolverVector(theIndex);
142
143     aSolver.SetContext(aContext);
144     aSolver.Perform();
145   }
146
147 private:
148   BOPTools_ContextFunctor(const BOPTools_ContextFunctor&);
149   BOPTools_ContextFunctor& operator= (const BOPTools_ContextFunctor&);
150
151 private:
152   TypeSolverVector&      mySolverVector;
153   mutable ContextMap     myContexts;
154   mutable Standard_Mutex myMutex;
155 };
156
157 //=======================================================================
158 //class    : BOPTools_ContextCnt
159 //purpose  : 
160 //=======================================================================
161 template <class TypeFunctor, class TypeSolverVector, class TypeContext>
162 class BOPTools_ContextCnt
163 {
164 public:
165   static void Perform( const Standard_Boolean isRunParallel,
166                        TypeSolverVector&      theSolverVector,
167                        TypeContext&           theContext )
168   {
169     TypeFunctor aFunctor(theSolverVector);
170     aFunctor.SetContext(theContext);
171
172     OSD_Parallel::For(0, theSolverVector.Length(), aFunctor, !isRunParallel);
173   }
174 };
175
176 #endif