File indexing completed on 2025-07-05 08:11:53
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011 #include <optional>
0012
0013 #include <tbb/parallel_for.h>
0014 #include <tbb/queuing_mutex.h>
0015 #include <tbb/task_arena.h>
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027 namespace ActsExamples::tbbWrap {
0028
0029
0030
0031
0032
0033 static bool enableTBB(int nthreads = -99) {
0034 static bool setting = false;
0035 if (nthreads != -99) {
0036 bool newSetting = (nthreads != 1);
0037 if (!setting && newSetting) {
0038 setting = newSetting;
0039 }
0040 }
0041 return setting;
0042 }
0043
0044
0045
0046
0047
0048 class task_arena {
0049 std::optional<tbb::task_arena> tbb;
0050
0051 public:
0052 explicit task_arena(int nthreads = tbb::task_arena::automatic,
0053 unsigned res = 1) {
0054 if (enableTBB(nthreads)) {
0055 tbb.emplace(nthreads, res);
0056 }
0057 }
0058
0059 template <typename F>
0060 void execute(const F& f) {
0061 if (tbb) {
0062 tbb->execute(f);
0063 } else {
0064 f();
0065 }
0066 }
0067 };
0068
0069
0070 class parallel_for {
0071 public:
0072 template <typename R, typename F>
0073 parallel_for(const R& r, const F& f) {
0074 if (enableTBB()) {
0075 tbb::parallel_for(r, f);
0076 } else {
0077 for (auto i = r.begin(); i != r.end(); ++i) {
0078 f(R(i, i + 1));
0079 }
0080 }
0081 }
0082 };
0083
0084
0085 class queuing_mutex {
0086 std::optional<tbb::queuing_mutex> tbb;
0087
0088 public:
0089 queuing_mutex() {
0090 if (enableTBB()) {
0091 tbb.emplace();
0092 }
0093 }
0094
0095 class scoped_lock {
0096 std::optional<tbb::queuing_mutex::scoped_lock> tbb;
0097
0098 public:
0099 scoped_lock() {
0100 if (enableTBB()) {
0101 tbb.emplace();
0102 }
0103 }
0104
0105 explicit scoped_lock(queuing_mutex& m) {
0106 if (enableTBB()) {
0107 tbb.emplace(*m.tbb);
0108 }
0109 }
0110 };
0111 };
0112
0113 }