7 #include <execution/Executor.h> 
    8 #include <tasking/Runnable.h> 
   11 #include <parallelism/Barrier.h> 
   12 #include <type_traits> 
   23             bool independentTasks =
 
   38                 : mRunnable( std::move( ex.mRunnable ) ), mOpts( ex.mOpts )
 
   42                 : mRunnable( ex.mRunnable ), mOpts( ex.mOpts )
 
   45             Executor( std::shared_ptr<Runnable> runnable )
 
   46                 : mRunnable( runnable ){};
 
   49                 mRunnable = ex.mRunnable;
 
   55                 mRunnable = std::move( ex.mRunnable );
 
   61             inline const std::weak_ptr<Runnable>& getRunnable()
 const 
   65             inline std::weak_ptr<Runnable>& getRunnable() { 
return mRunnable; }
 
   68             template <
class TRet, 
class TArg, 
class F>
 
   72                 if ( !mRunnable.expired() )
 
   78                     mRunnable.lock()->execute<TRet>(
 
   79                         [f = std::forward<F>( f ),
 
   80                          arg = std::forward<TArg>(
 
   81                              arg )]() 
mutable noexcept( std::
 
   85                             -> TRet { 
return f( std::forward<TArg>( arg ) ); },
 
   92                     output.setError( 
new std::runtime_error(
 
   93                         "RunnableExecutor::launch. Runnable has expired!!!" ) );
 
   96             template <
class TRet, 
class F>
 
   99                 if ( !mRunnable.expired() )
 
  101                     mRunnable.lock()->execute<TRet>(
 
  102                         std::forward<F>( f ),
 
  109                     output.setError( 
new std::runtime_error(
 
  110                         "RunnableExecutor::launch. Runnable has expired!!!" ) );
 
  113             template <
class I, 
class F>
 
  116             template <
class TArg, 
class... FTypes>
 
  118                                                   std::exception_ptr& excpt,
 
  119                                                   FTypes&&... functions );
 
  120             template <
class ReturnTuple, 
class TArg, 
class... FTypes>
 
  123                               std::exception_ptr& excpt, ReturnTuple& result,
 
  124                               FTypes&&... functions );
 
  127             std::weak_ptr<Runnable> mRunnable;
 
  128             RunnableExecutorOpts mOpts;
 
  132             template <
class F, 
class TArg>
 
  133             void _invoke( ExFuture<Runnable, TArg> fut,
 
  135                           std::exception_ptr& except, F&& f )
 
  137                 static_assert( std::is_invocable<F, TArg>::value,
 
  138                                "_invoke bad signature" );
 
  139                 if constexpr ( std::is_nothrow_invocable<F, TArg>::value )
 
  145                         [f = std::forward<F>( f ),
 
  146                          b]( ExFuture<Runnable, TArg>& fut ) 
mutable noexcept
 
  148                             f( fut.getValue().value() );
 
  157                         [f = std::forward<F>( f ), b,
 
  158                          &except]( ExFuture<Runnable, TArg> fut ) 
mutable 
  162                                 f( fut.getValue().value() );
 
  167                                     except = std::current_exception();
 
  176             void _invoke( ExFuture<Runnable, void> fut,
 
  178                           std::exception_ptr& except, F&& f )
 
  180                 if constexpr ( std::is_nothrow_invocable<F>::value )
 
  184                         [f = std::forward<F>( f ),
 
  185                          b]( ExFuture<Runnable, void>& fut ) 
mutable noexcept
 
  196                         [f = std::forward<F>( f ), b,
 
  197                          &except]( ExFuture<Runnable, void>& fut ) 
mutable 
  206                                     except = std::current_exception();
 
  213             template <
class TArg, 
class F, 
class... FTypes>
 
  214             void _invoke( ExFuture<Runnable, TArg> fut,
 
  216                           std::exception_ptr& except, F&& f, FTypes&&... fs )
 
  218                 _invoke( fut, b, except, std::forward<F>( f ) );
 
  219                 _invoke( fut, b, except, std::forward<FTypes>( fs )... );
 
  221             template <
int n, 
class ResultTuple, 
class F, 
class TArg>
 
  222             void _invoke_with_result( ExFuture<Runnable, TArg> fut,
 
  224                                       std::exception_ptr& except,
 
  225                                       ResultTuple& output, F&& f )
 
  227                 static_assert( std::is_invocable<F, TArg>::value,
 
  228                                "_invoke_with_result bad signature" );
 
  229                 if constexpr ( std::is_nothrow_invocable<F, TArg>::value )
 
  233                         [f = std::forward<F>( f ), b, &output](
 
  234                             ExFuture<Runnable, TArg>& fut ) 
mutable noexcept
 
  236                             if constexpr ( std::is_same<
 
  237                                                std::invoke_result_t<F, TArg>,
 
  239                                 f( fut.getValue().value() );
 
  241                                 std::get<n>( output ) =
 
  242                                     f( fut.getValue().value() );
 
  251                         [f = std::forward<F>( f ), b, &output,
 
  252                          &except]( ExFuture<Runnable, TArg>& fut ) 
mutable 
  256                                 if constexpr ( std::is_same<
 
  257                                                    std::invoke_result_t<F,
 
  260                                     f( fut.getValue().value() );
 
  262                                     std::get<n>( output ) =
 
  263                                         f( fut.getValue().value() );
 
  268                                     except = std::current_exception();
 
  276             template <
int n, 
class ResultTuple, 
class F>
 
  277             void _invoke_with_result( ExFuture<Runnable, void>& fut,
 
  279                                       std::exception_ptr& except,
 
  280                                       ResultTuple& output, F&& f )
 
  282                 if constexpr ( std::is_nothrow_invocable<F>::value )
 
  286                         [f = std::forward<F>( f ), b, &output](
 
  287                             ExFuture<Runnable, void>& fut ) 
mutable noexcept
 
  289                             if constexpr ( std::is_same<std::invoke_result_t<F>,
 
  293                                 std::get<n>( output ) = f();
 
  302                         [f = std::forward<F>( f ), b, &output,
 
  303                          &except]( ExFuture<Runnable, void>& fut ) 
mutable 
  307                                 if constexpr ( std::is_same<
 
  308                                                    std::invoke_result_t<F>,
 
  312                                     std::get<n>( output ) = f();
 
  317                                     except = std::current_exception();
 
  326             template <
int n, 
class ResultTuple, 
class TArg, 
class F,
 
  328             void _invoke_with_result( ExFuture<Runnable, TArg> fut,
 
  330                                       std::exception_ptr& except,
 
  331                                       ResultTuple& output, F&& f,
 
  334                 _invoke_with_result<n>( fut, b, except, output,
 
  335                                         std::forward<F>( f ) );
 
  336                 _invoke_with_result<n + 1>( fut, b, except, output,
 
  337                                             std::forward<FTypes>( fs )... );
 
  352         template <
class I, 
class F>
 
  357             typedef typename std::decay<I>::type DecayedIt;
 
  358             constexpr 
bool isArithIterator =
 
  360             if ( getRunnable().expired() )
 
  362                 throw std::runtime_error( 
"Runnable has been destroyed" );
 
  364             bool autoKill = getOpts().autoKill;
 
  365             bool independentTasks = getOpts().independentTasks;
 
  367             if constexpr ( isArithIterator )
 
  368                 length = ( end - begin );
 
  370                 length = std::distance( begin, end );
 
  371             int nElements = independentTasks
 
  372                                 ? ( length + increment - 1 ) / increment
 
  374             auto ptr = getRunnable().lock();
 
  378             if ( independentTasks )
 
  380                 for ( 
auto i = begin; i < end; i += increment )
 
  383                         [functor, barrier, i]() 
mutable noexcept(
 
  384                             ( std::is_nothrow_invocable<F, I>::value ) )
 
  390                         autoKill ? Runnable::killTrue : Runnable::killFalse );
 
  396                     [functor, barrier, begin, end,
 
  397                      increment]() 
mutable noexcept( std::
 
  398                                                         is_nothrow_invocable<
 
  401                         for ( 
auto i = begin; i < end; i += increment )
 
  407                     0, autoKill ? Runnable::killTrue : Runnable::killFalse );
 
  411         template <
class TArg, 
class... FTypes>
 
  414                                       std::exception_ptr& except,
 
  415                                       FTypes&&... functions )
 
  418             _private::_invoke( fut, barrier, except,
 
  419                                std::forward<FTypes>( functions )... );
 
  422         template <
class ReturnTuple, 
class TArg, 
class... FTypes>
 
  424             ExFuture<Runnable, TArg> fut, std::exception_ptr& except,
 
  425             ReturnTuple& result, FTypes&&... functions )
 
  428             _private::_invoke_with_result<0>(
 
  429                 fut, barrier, except, result,
 
  430                 std::forward<FTypes>( functions )... );
 
  441                 has_microthreading = 
true 
Typical Traits for types.
 
Represents a value that maybe is not present at the current moment.
Definition: Future.h:750
 
Extension of mel::core::Future to apply to executors.
Definition: ExFuture.h:21
 
Executor specialization using Runnable as execution agent.
Definition: RunnableExecutor.h:34
 
void launch(F &&f, TArg &&arg, ExFuture< Runnable, TRet > output) const noexcept
Definition: RunnableExecutor.h:69
 
Definition: Executor.h:26
 
Definition: TypeTraits.h:296
 
Multithread barrier.
Definition: Barrier.h:43
 
void set()
Definition: Barrier.h:59
 
A class representing a "running" task, with added functionality to post events requesting execution o...
Definition: Runnable.h:183
 
static std::function< bool()> killFalse
helper function to reject kill when receiving kill signal
Definition: Runnable.h:276
 
static std::function< bool()> killTrue
helper function to automatically kill process when receiving kill signal
Definition: Runnable.h:274
 
ExFuture< ExecutorAgent, std::invoke_result_t< F > > launch(Executor< ExecutorAgent > ex, F &&f)
Launch given functor in given executor.
Definition: Executor.h:65
 
ExFuture< ExecutorAgent, TArg > parallel(ExFuture< ExecutorAgent, TArg > source, FTypes... functions)
Execute given functions in a (possibly, depending on concrete executor) parallel way If an exception ...
Definition: Executor.h:499
 
ExFuture< ExecutorAgent, TArg > loop(ExFuture< ExecutorAgent, TArg > source, I getIteratorsFunc, F functor, int increment=1)
parallel (possibly, depending on executor capabilities) loop
Definition: Executor.h:290
 
ExFuture< ExecutorAgent, typename ::mel::execution::_private::GetReturn< TArg, FTypes... >::type > parallel_convert(ExFuture< ExecutorAgent, TArg > source, FTypes... functions)
Same as parallel but returning a tuple with the values for each functor.
Definition: Executor.h:726
 
Definition: Callback_Impl.h:11
 
Default traits for any executor.
Definition: Executor.h:46
 
Concrete options for this type of executor.
Definition: RunnableExecutor.h:22
 
bool autoKill
Definition: RunnableExecutor.h:25