17#ifndef __mrtrix_thread_h__
18#define __mrtrix_thread_h__
67 std::lock_guard<std::mutex> lock (
mutex);
74 std::lock_guard<std::mutex> lock (
mutex);
102 __thread_base (
const __thread_base&) =
delete;
103 __thread_base (__thread_base&&) =
default;
112 class __single_thread :
public __thread_base {
NOMEMALIGN
114 template <
class Functor>
115 __single_thread (Functor&&
functor,
const std::string&
name =
"unnamed") :
116 __thread_base (
name) {
117 DEBUG (
"launching thread \"" +
name +
"\"...");
118 using F =
typename std::remove_reference<Functor>::type;
119 thread = std::async (std::launch::async, &F::execute, &
functor);
121 __single_thread (
const __single_thread&) =
delete;
122 __single_thread (__single_thread&&) =
default;
124 bool finished ()
const
126 return thread.wait_for(std::chrono::microseconds(0)) == std::future_status::ready;
129 void wait () noexcept (false) {
130 DEBUG (
"waiting for completion of thread \"" +
name +
"\"...");
132 DEBUG (
"thread \"" +
name +
"\" completed OK");
135 ~__single_thread () {
138 catch (Exception& E) { E.display(); }
147 template <
class Functor>
148 class __multi_thread :
public __thread_base {
NOMEMALIGN
150 __multi_thread (Functor&
functor,
size_t nthreads,
const std::string&
name =
"unnamed") :
152 DEBUG (
"launching " +
str (nthreads) +
" threads \"" +
name +
"\"...");
153 using F =
typename std::remove_reference<Functor>::type;
156 threads.push_back (std::async (std::launch::async, &F::execute, &f));
157 threads.push_back (std::async (std::launch::async, &F::execute, &
functor));
160 __multi_thread (
const __multi_thread&) =
delete;
161 __multi_thread (__multi_thread&&) =
default;
163 void wait () noexcept (false) {
164 DEBUG (
"waiting for completion of threads \"" +
name +
"\"...");
165 bool exception_thrown =
false;
170 catch (Exception& E) {
171 exception_thrown =
true;
175 if (exception_thrown)
176 throw Exception (
"exception thrown from one or more threads \"" +
name +
"\"");
177 DEBUG (
"threads \"" +
name +
"\" completed OK");
180 bool finished ()
const {
182 if (t.wait_for (std::chrono::microseconds(0)) != std::future_status::ready)
187 bool any_valid ()
const {
197 catch (Exception& E) { E.display(); }
202 vector<typename std::remove_reference<Functor>::type>
functors;
207 template <
class Functor>
210 __Multi (Functor&
object,
size_t number) :
functor (
object),
num (number) { }
211 __Multi (__Multi&& m) =
default;
212 template <
class X>
bool operator() (
const X&) { assert (0);
return false; }
213 template <
class X>
bool operator() (X&) { assert (0);
return false; }
214 template <
class X,
class Y>
bool operator() (
const X&, Y&) { assert (0);
return false; }
215 typename std::remove_reference<Functor>::type&
functor;
219 template <
class Functor>
222 using type = __single_thread;
223 type operator() (Functor&
functor,
const std::string&
name) {
228 template <
class Functor>
231 using type = __multi_thread<Functor>;
232 type operator() (__Multi<Functor>&
functor,
const std::string&
name) {
283 template <
class Functor>
284 inline __Multi<typename std::remove_reference<Functor>::type>
372 template <
class Functor>
373 inline typename __run<Functor>::type
run (Functor&&
functor,
const std::string&
name =
"unnamed")
375 return __run<typename std::remove_reference<Functor>::type>() (
functor,
name);
static void register_thread()
static void(* previous_report_to_user_func)(const std::string &msg, int type)
static void thread_report_to_user_func(const std::string &msg, int type)
static void(* previous_print_func)(const std::string &msg)
static void unregister_thread()
static void thread_print_func(const std::string &msg)
static __Backend * backend
__run< Functor >::type run(Functor &&functor, const std::string &name="unnamed")
Execute the functor's execute method in a separate thread.
size_t threads_to_execute()
nthreads_t type_nthreads()
size_t number_of_threads()
__Multi< typename std::remove_reference< Functor >::type > multi(Functor &&functor, size_t nthreads=threads_to_execute())
used to request multiple threads of the corresponding functor
std::string str(const T &value, int precision=0)
std::future< void > thread
vector< typename std::remove_reference< Functor >::type > functors
vector< std::future< void > > threads
std::remove_reference< Functor >::type & functor