OmniSciDB  95562058bd
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
threadpool.h
Go to the documentation of this file.
1 /*
2  * Copyright 2020 OmniSci, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #pragma once
18 
19 #ifdef HAVE_TBB
20 #include "tbb/task_group.h"
21 #endif
22 
23 #include <future>
24 #include <iostream>
25 #include <type_traits>
26 
27 namespace threadpool {
28 
29 template <typename T>
31  public:
32  template <class Function, class... Args>
33  void spawn(Function&& f, Args&&... args) {
34  threads_.push_back(std::async(std::launch::async, f, args...));
35  }
36 
37  protected:
38  std::vector<std::future<T>> threads_;
39 };
40 
41 template <typename T, typename ENABLE = void>
43  public:
45 
46  void join() {
47  for (auto& child : this->threads_) {
48  child.wait();
49  }
50  for (auto& child : this->threads_) {
51  child.get();
52  }
53  }
54 };
55 
56 template <typename T>
57 class FuturesThreadPool<T, std::enable_if_t<std::is_object<T>::value>>
58  : public FuturesThreadPoolBase<T> {
59  public:
61 
62  auto join() {
63  std::vector<T> results;
64  results.reserve(this->threads_.size());
65  for (auto& child : this->threads_) {
66  child.wait();
67  }
68  for (auto& child : this->threads_) {
69  results.push_back(child.get());
70  }
71  return results;
72  }
73 };
74 
75 #ifdef HAVE_TBB
76 
77 class TbbThreadPoolBase {
78  protected:
79  tbb::task_group tasks_;
80 };
81 
82 template <typename T, typename ENABLE = void>
83 class TbbThreadPool : public TbbThreadPoolBase {
84  public:
85  TbbThreadPool() {}
86 
87  template <class Function, class... Args>
88  void spawn(Function&& f, Args&&... args) {
89  tasks_.run([f, args...] { f(args...); });
90  }
91 
92  void join() { tasks_.wait(); }
93 };
94 
95 template <typename T>
96 class TbbThreadPool<T, std::enable_if_t<std::is_object<T>::value>>
97  : public TbbThreadPoolBase {
98  public:
99  TbbThreadPool() {}
100 
101  template <class Function, class... Args>
102  void spawn(Function&& f, Args&&... args) {
103  const size_t result_idx = results_.size();
104  results_.emplace_back(T{});
105  tasks_.run([this, result_idx, f, args...] { results_[result_idx] = f(args...); });
106  }
107 
108  auto join() {
109  tasks_.wait();
110  return results_;
111  }
112 
113  private:
114  std::vector<T> results_;
115 };
116 
117 #endif
118 
119 #ifdef HAVE_TBB
120 template <typename T>
121 using ThreadPool = TbbThreadPool<T>;
122 #else
123 template <typename T>
125 #endif
126 }; // namespace threadpool
std::vector< std::future< T > > threads_
Definition: threadpool.h:38
std::string join(T const &container, std::string const &delim)
void spawn(Function &&f, Args &&...args)
Definition: threadpool.h:33
FuturesThreadPool< T > ThreadPool
Definition: threadpool.h:124