#ifndef SLA_CONCURRENCY_H #define SLA_CONCURRENCY_H #include #include #include #include #include #include #include namespace Slic3r { namespace sla { // Set this to true to enable full parallelism in this module. // Only the well tested parts will be concurrent if this is set to false. const constexpr bool USE_FULL_CONCURRENCY = true; template struct _ccr {}; template<> struct _ccr { using SpinningMutex = tbb::spin_mutex; using BlockingMutex = tbb::mutex; template static IteratorOnly loop_(const tbb::blocked_range &range, Fn &&fn) { for (auto &el : range) fn(el); } template static IntegerOnly loop_(const tbb::blocked_range &range, Fn &&fn) { for (I i = range.begin(); i < range.end(); ++i) fn(i); } template static void for_each(It from, It to, Fn &&fn, size_t granularity = 1) { tbb::parallel_for(tbb::blocked_range{from, to, granularity}, [&fn, from](const auto &range) { loop_(range, std::forward(fn)); }); } template static T reduce(I from, I to, const T &init, MergeFn &&mergefn, AccessFn &&access, size_t granularity = 1 ) { return tbb::parallel_reduce( tbb::blocked_range{from, to, granularity}, init, [&](const auto &range, T subinit) { T acc = subinit; loop_(range, [&](auto &i) { acc = mergefn(acc, access(i)); }); return acc; }, std::forward(mergefn)); } template static IteratorOnly reduce(I from, I to, const T & init, MergeFn &&mergefn, size_t granularity = 1) { return reduce( from, to, init, std::forward(mergefn), [](typename I::value_type &i) { return i; }, granularity); } }; template<> struct _ccr { private: struct _Mtx { inline void lock() {} inline void unlock() {} }; public: using SpinningMutex = _Mtx; using BlockingMutex = _Mtx; template static IteratorOnly loop_(It from, It to, Fn &&fn) { for (auto it = from; it != to; ++it) fn(*it); } template static IntegerOnly loop_(I from, I to, Fn &&fn) { for (I i = from; i < to; ++i) fn(i); } template static void for_each(It from, It to, Fn &&fn, size_t /* ignore granularity */ = 1) { loop_(from, to, std::forward(fn)); } template static T reduce(I from, I to, const T & init, MergeFn &&mergefn, AccessFn &&access, size_t /*granularity*/ = 1 ) { T acc = init; loop_(from, to, [&](auto &i) { acc = mergefn(acc, access(i)); }); return acc; } template static IteratorOnly reduce(I from, I to, const T &init, MergeFn &&mergefn, size_t /*granularity*/ = 1 ) { return reduce(from, to, init, std::forward(mergefn), [](typename I::value_type &i) { return i; }); } }; using ccr = _ccr; using ccr_seq = _ccr; using ccr_par = _ccr; }} // namespace Slic3r::sla #endif // SLACONCURRENCY_H