File indexing completed on 2026-09-12 09:18:25
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef OSD_Parallel_HeaderFile
0015 #define OSD_Parallel_HeaderFile
0016
0017 #include <OSD_ThreadPool.hxx>
0018 #include <Standard_Type.hxx>
0019 #include <memory>
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058 class OSD_Parallel
0059 {
0060 private:
0061
0062
0063
0064 class IteratorInterface
0065 {
0066 public:
0067 virtual ~IteratorInterface() = default;
0068
0069
0070 virtual bool IsEqual(const IteratorInterface& theOther) const = 0;
0071
0072
0073 virtual void Increment() = 0;
0074
0075
0076
0077 virtual IteratorInterface* Clone() const = 0;
0078 };
0079
0080
0081
0082
0083 template <class Type>
0084 class IteratorWrapper : public IteratorInterface
0085 {
0086 public:
0087 IteratorWrapper() = default;
0088
0089 IteratorWrapper(const Type& theValue)
0090 : myValue(theValue)
0091 {
0092 }
0093
0094 bool IsEqual(const IteratorInterface& theOther) const override
0095 {
0096 return myValue == dynamic_cast<const IteratorWrapper<Type>&>(theOther).myValue;
0097 }
0098
0099 void Increment() override { ++myValue; }
0100
0101 IteratorInterface* Clone() const override { return new IteratorWrapper<Type>(myValue); }
0102
0103 const Type& Value() const { return myValue; }
0104
0105 private:
0106 Type myValue;
0107 };
0108
0109 protected:
0110
0111
0112
0113
0114
0115
0116
0117 class UniversalIterator
0118
0119
0120 {
0121 public:
0122
0123
0124 using iterator_category = std::forward_iterator_tag;
0125 using value_type = IteratorInterface*;
0126 using difference_type = ptrdiff_t;
0127 using pointer = value_type;
0128 using reference = value_type;
0129
0130 UniversalIterator() = default;
0131
0132 UniversalIterator(IteratorInterface* theOther)
0133 : myPtr(theOther)
0134 {
0135 }
0136
0137 UniversalIterator(const UniversalIterator& theOther)
0138 : myPtr(theOther.myPtr->Clone())
0139 {
0140 }
0141
0142 UniversalIterator& operator=(const UniversalIterator& theOther)
0143 {
0144 myPtr.reset(theOther.myPtr->Clone());
0145 return *this;
0146 }
0147
0148 bool operator!=(const UniversalIterator& theOther) const
0149 {
0150 return !myPtr->IsEqual(*theOther.myPtr);
0151 }
0152
0153 bool operator==(const UniversalIterator& theOther) const
0154 {
0155 return myPtr->IsEqual(*theOther.myPtr);
0156 }
0157
0158 UniversalIterator& operator++()
0159 {
0160 myPtr->Increment();
0161 return *this;
0162 }
0163
0164 UniversalIterator operator++(int)
0165 {
0166 UniversalIterator aValue(*this);
0167 myPtr->Increment();
0168 return aValue;
0169 }
0170
0171 reference operator*() const { return myPtr.get(); }
0172
0173 reference operator*() { return myPtr.get(); }
0174
0175 private:
0176 std::unique_ptr<IteratorInterface> myPtr;
0177 };
0178
0179
0180
0181
0182 class FunctorInterface
0183 {
0184 public:
0185 virtual ~FunctorInterface() = default;
0186
0187 virtual void operator()(IteratorInterface* theIterator) const = 0;
0188
0189
0190 template <typename Iterator>
0191 static const Iterator& DownCast(IteratorInterface* theIterator)
0192 {
0193 return dynamic_cast<OSD_Parallel::IteratorWrapper<Iterator>*>(theIterator)->Value();
0194 }
0195 };
0196
0197 private:
0198
0199 template <class Iterator, class Functor>
0200 class FunctorWrapperIter : public FunctorInterface
0201 {
0202 public:
0203 FunctorWrapperIter(const Functor& theFunctor)
0204 : myFunctor(theFunctor)
0205 {
0206 }
0207
0208 void operator()(IteratorInterface* theIterator) const override
0209 {
0210 const Iterator& anIt = DownCast<Iterator>(theIterator);
0211 myFunctor(*anIt);
0212 }
0213
0214 private:
0215 FunctorWrapperIter(const FunctorWrapperIter&) = delete;
0216 void operator=(const FunctorWrapperIter&) = delete;
0217 const Functor& myFunctor;
0218 };
0219
0220
0221 template <class Functor>
0222 class FunctorWrapperInt : public FunctorInterface
0223 {
0224 public:
0225 FunctorWrapperInt(const Functor& theFunctor)
0226 : myFunctor(theFunctor)
0227 {
0228 }
0229
0230 void operator()(IteratorInterface* theIterator) const override
0231 {
0232 int anIndex = DownCast<int>(theIterator);
0233 myFunctor(anIndex);
0234 }
0235
0236 private:
0237 FunctorWrapperInt(const FunctorWrapperInt&) = delete;
0238 void operator=(const FunctorWrapperInt&) = delete;
0239 const Functor& myFunctor;
0240 };
0241
0242
0243 template <class Functor>
0244 class FunctorWrapperForThreadPool
0245 {
0246 public:
0247 FunctorWrapperForThreadPool(const Functor& theFunctor)
0248 : myFunctor(theFunctor)
0249 {
0250 }
0251
0252 void operator()(int theThreadIndex, int theElemIndex) const
0253 {
0254 (void)theThreadIndex;
0255 myFunctor(theElemIndex);
0256 }
0257
0258 private:
0259 FunctorWrapperForThreadPool(const FunctorWrapperForThreadPool&) = delete;
0260 void operator=(const FunctorWrapperForThreadPool&) = delete;
0261 const Functor& myFunctor;
0262 };
0263
0264 private:
0265
0266
0267
0268
0269
0270
0271
0272
0273
0274
0275
0276 Standard_EXPORT static void forEachOcct(UniversalIterator& theBegin,
0277 UniversalIterator& theEnd,
0278 const FunctorInterface& theFunctor,
0279 int theNbItems);
0280
0281
0282 Standard_EXPORT static void forEachExternal(UniversalIterator& theBegin,
0283 UniversalIterator& theEnd,
0284 const FunctorInterface& theFunctor,
0285 int theNbItems);
0286
0287 public:
0288
0289
0290
0291 Standard_EXPORT static bool ToUseOcctThreads();
0292
0293
0294
0295 Standard_EXPORT static void SetUseOcctThreads(bool theToUseOcct);
0296
0297
0298 Standard_EXPORT static int NbLogicalProcessors();
0299
0300
0301
0302
0303
0304
0305
0306
0307
0308
0309
0310
0311
0312 template <typename InputIterator, typename Functor>
0313 static void ForEach(InputIterator theBegin,
0314 InputIterator theEnd,
0315 const Functor& theFunctor,
0316 const bool isForceSingleThreadExecution = false,
0317 int theNbItems = -1)
0318 {
0319 if (isForceSingleThreadExecution || theNbItems == 1)
0320 {
0321 for (InputIterator it(theBegin); it != theEnd; ++it)
0322 theFunctor(*it);
0323 }
0324 else
0325 {
0326 UniversalIterator aBegin(new IteratorWrapper<InputIterator>(theBegin));
0327 UniversalIterator aEnd(new IteratorWrapper<InputIterator>(theEnd));
0328 FunctorWrapperIter<InputIterator, Functor> aFunctor(theFunctor);
0329 if (ToUseOcctThreads())
0330 {
0331 forEachOcct(aBegin, aEnd, aFunctor, theNbItems);
0332 }
0333 else
0334 {
0335 forEachExternal(aBegin, aEnd, aFunctor, theNbItems);
0336 }
0337 }
0338 }
0339
0340
0341
0342
0343
0344
0345
0346
0347
0348
0349
0350
0351 template <typename Functor>
0352 static void For(const int theBegin,
0353 const int theEnd,
0354 const Functor& theFunctor,
0355 const bool isForceSingleThreadExecution = false)
0356 {
0357 const int aRange = theEnd - theBegin;
0358 if (isForceSingleThreadExecution || aRange == 1)
0359 {
0360 for (int it(theBegin); it != theEnd; ++it)
0361 theFunctor(it);
0362 }
0363 else if (ToUseOcctThreads())
0364 {
0365 const occ::handle<OSD_ThreadPool>& aThreadPool = OSD_ThreadPool::DefaultPool();
0366 OSD_ThreadPool::Launcher aPoolLauncher(*aThreadPool, aRange);
0367 FunctorWrapperForThreadPool<Functor> aFunctor(theFunctor);
0368 aPoolLauncher.Perform(theBegin, theEnd, aFunctor);
0369 }
0370 else
0371 {
0372 UniversalIterator aBegin(new IteratorWrapper<int>(theBegin));
0373 UniversalIterator aEnd(new IteratorWrapper<int>(theEnd));
0374 FunctorWrapperInt<Functor> aFunctor(theFunctor);
0375 forEachExternal(aBegin, aEnd, aFunctor, aRange);
0376 }
0377 }
0378 };
0379
0380 #endif