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