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