00af0ebb |
1 | // Created on: 2014-08-19 |
2 | // Created by: Alexander Zaikin |
3 | // Copyright (c) 1996-1999 Matra Datavision |
4 | // Copyright (c) 2013-2014 OPEN CASCADE SAS |
5 | // |
6 | // This file is part of Open CASCADE Technology software library. |
7 | // |
8 | // This library is free software; you can redistribute it and/or modify it under |
9 | // the terms of the GNU Lesser General Public License version 2.1 as published |
10 | // by the Free Software Foundation, with special exception defined in the file |
11 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT |
12 | // distribution for complete text of the license and disclaimer of any warranty. |
13 | // |
14 | // Alternatively, this file may be used under the terms of Open CASCADE |
15 | // commercial license or contractual agreement. |
16 | |
00af0ebb |
17 | #include <OSD_Parallel.hxx> |
18 | |
6f498847 |
19 | #include <OSD_ThreadPool.hxx> |
20 | |
00af0ebb |
21 | #include <NCollection_Array1.hxx> |
22 | #include <Standard_Mutex.hxx> |
23 | #include <OSD_Thread.hxx> |
24 | |
25 | namespace |
26 | { |
27 | //! Class implementing tools for parallel processing |
28 | //! using threads (when TBB is not available); |
29 | //! it is derived from OSD_Parallel to get access to |
30 | //! Iterator and FunctorInterface nested types. |
6f498847 |
31 | class OSD_Parallel_Threads : public OSD_ThreadPool, public OSD_Parallel |
00af0ebb |
32 | { |
33 | public: |
34 | //! Auxiliary class which ensures exclusive |
35 | //! access to iterators of processed data pool. |
36 | class Range |
37 | { |
38 | public: //! @name public methods |
39 | |
40 | //! Constructor |
41 | Range(const OSD_Parallel::UniversalIterator& theBegin, |
42 | const OSD_Parallel::UniversalIterator& theEnd) |
43 | : myBegin(theBegin), |
44 | myEnd(theEnd), |
45 | myIt(theBegin) |
46 | { |
47 | } |
48 | |
49 | //! Returns const link on the first element. |
50 | inline const OSD_Parallel::UniversalIterator& Begin() const |
51 | { |
52 | return myBegin; |
53 | } |
54 | |
55 | //! Returns const link on the last element. |
56 | inline const OSD_Parallel::UniversalIterator& End() const |
57 | { |
58 | return myEnd; |
59 | } |
60 | |
61 | //! Returns first non processed element or end. |
62 | //! Thread-safe method. |
63 | inline OSD_Parallel::UniversalIterator It() const |
64 | { |
65 | Standard_Mutex::Sentry aMutex(myMutex); |
66 | return (myIt != myEnd) ? myIt++ : myEnd; |
67 | } |
68 | |
69 | private: //! @name private methods |
70 | |
71 | //! Empty copy constructor |
72 | Range(const Range& theCopy); |
73 | |
74 | //! Empty copy operator. |
75 | Range& operator=(const Range& theCopy); |
76 | |
77 | private: //! @name private fields |
78 | |
79 | const OSD_Parallel::UniversalIterator& myBegin; //!< Fisrt element of range. |
80 | const OSD_Parallel::UniversalIterator& myEnd; //!< Last element of range. |
81 | mutable OSD_Parallel::UniversalIterator myIt; //!< First non processed element of range. |
82 | mutable Standard_Mutex myMutex; //!< Access controller for the first non processed element. |
83 | }; |
84 | |
85 | //! Auxiliary wrapper class for thread function. |
6f498847 |
86 | class Task : public JobInterface |
00af0ebb |
87 | { |
88 | public: //! @name public methods |
89 | |
90 | //! Constructor. |
91 | Task(const OSD_Parallel::FunctorInterface& thePerformer, Range& theRange) |
92 | : myPerformer(thePerformer), |
93 | myRange(theRange) |
94 | { |
95 | } |
96 | |
97 | //! Method is executed in the context of thread, |
98 | //! so this method defines the main calculations. |
6f498847 |
99 | virtual void Perform (int ) Standard_OVERRIDE |
00af0ebb |
100 | { |
6f498847 |
101 | for (OSD_Parallel::UniversalIterator anIter = myRange.It(); anIter != myRange.End(); anIter = myRange.It()) |
102 | { |
103 | myPerformer (anIter); |
104 | } |
00af0ebb |
105 | } |
106 | |
107 | private: //! @name private methods |
108 | |
109 | //! Empty copy constructor. |
110 | Task(const Task& theCopy); |
111 | |
112 | //! Empty copy operator. |
113 | Task& operator=(const Task& theCopy); |
114 | |
115 | private: //! @name private fields |
6f498847 |
116 | const FunctorInterface& myPerformer; //!< Link on functor |
117 | const Range& myRange; //!< Link on processed data block |
118 | }; |
119 | |
120 | //! Launcher specialization. |
121 | class UniversalLauncher : public Launcher |
122 | { |
123 | public: |
124 | //! Constructor. |
125 | UniversalLauncher (OSD_ThreadPool& thePool, int theMaxThreads = -1) |
126 | : Launcher (thePool, theMaxThreads) {} |
00af0ebb |
127 | |
6f498847 |
128 | //! Primitive for parallelization of "for" loops. |
129 | void Perform (OSD_Parallel::UniversalIterator& theBegin, |
130 | OSD_Parallel::UniversalIterator& theEnd, |
131 | const OSD_Parallel::FunctorInterface& theFunctor) |
132 | { |
133 | Range aData (theBegin, theEnd); |
134 | Task aJob (theFunctor, aData); |
135 | perform (aJob); |
136 | } |
00af0ebb |
137 | }; |
138 | }; |
139 | } |
140 | |
141 | //======================================================================= |
fc867b96 |
142 | //function : forEachOcct |
143 | //purpose : |
00af0ebb |
144 | //======================================================================= |
fc867b96 |
145 | void OSD_Parallel::forEachOcct (UniversalIterator& theBegin, |
146 | UniversalIterator& theEnd, |
147 | const FunctorInterface& theFunctor, |
148 | Standard_Integer theNbItems) |
00af0ebb |
149 | { |
6f498847 |
150 | const Handle(OSD_ThreadPool)& aThreadPool = OSD_ThreadPool::DefaultPool(); |
151 | const Standard_Integer aNbThreads = theNbItems != -1 ? Min (theNbItems, aThreadPool->NbDefaultThreadsToLaunch()) : -1; |
152 | OSD_Parallel_Threads::UniversalLauncher aLauncher (*aThreadPool, aNbThreads); |
153 | aLauncher.Perform (theBegin, theEnd, theFunctor); |
00af0ebb |
154 | } |
155 | |
fc867b96 |
156 | // Version of parallel executor used when TBB is not available |
157 | #ifndef HAVE_TBB |
158 | //======================================================================= |
159 | //function : forEachExternal |
160 | //purpose : |
161 | //======================================================================= |
162 | void OSD_Parallel::forEachExternal (UniversalIterator& theBegin, |
163 | UniversalIterator& theEnd, |
164 | const FunctorInterface& theFunctor, |
165 | Standard_Integer theNbItems) |
166 | { |
167 | forEachOcct (theBegin, theEnd, theFunctor, theNbItems); |
168 | } |
169 | |
6f498847 |
170 | #endif /* ! HAVE_TBB */ |