7 #include <core/Callback.h>
8 #include <tasking/ProcessScheduler.h>
9 #include <tasking/GenericProcess.h>
10 #include <core/CallbackSubscriptor.h>
19 #include <mpl/ParamAdder.h>
20 using mel::mpl::addParam;
21 #include <mpl/LinkArgs.h>
22 using mel::mpl::linkFunctor;
23 #include <mpl/ReturnAdaptor.h>
24 using mel::mpl::returnAdaptor;
25 #include <mpl/MemberEncapsulate.h>
26 using mel::mpl::makeMemberEncapsulate;
27 #include <mpl/Functor.h>
28 using mel::mpl::chain;
29 #include <mpl/AsPtr.h>
30 using mel::mpl::asPtr;
32 #include <core/ThreadDefs.h>
34 #include <core/Future.h>
38 #include <forward_list>
39 #include <type_traits>
41 #define RUNNABLE_TASK_ALIGNMENT 8
52 #define RUNNABLE_CREATETASK( f ) \
53 addParam< ::mel::tasking::EGenericProcessResult,Process*,uint64_t,void > \
54 (addParam< ::mel::tasking::EGenericProcessResult,uint64_t,void >( f ) )
56 #define RUNNABLE_TASK_PARAMS uint64_t t,Process* p
89 static void*
operator new(
size_t s,
Runnable* owner );
90 void operator delete(
void* ptr,
Runnable*) noexcept;
91 static void operator delete(
void* ptr ) noexcept;
119 enum class EMemState:uint8_t { FREE = 0,USED = 1 } ;
120 EMemState memState = EMemState::FREE;
121 alignas(RUNNABLE_TASK_ALIGNMENT)
char task[
sizeof( ::mel::tasking::_private::RunnableTask ) ] ;
127 typedef std::forward_list<RTMemPool> ListType;
129 MemZoneList():mSize(0){}
130 size_t size(){
return mSize;};
131 void push_front(RTMemPool&& pool)
133 mList.push_front(std::move(pool));
136 ListType& getList(){
return mList;}
137 void remove(RTMemPool* pool )
140 mList.remove_if([pool](
const RTMemPool& p)
142 auto r = (pool == &p);
154 RTMemPool():pool(0),count(0){}
191 static const unsigned int DEFAULT_POOL_SIZE = 512;
196 unsigned int maxPoolSize = DEFAULT_POOL_SIZE;
199 inline ::mel::core::ThreadId getOwnerThreadId()
const { assert(mOwnerThread != 0);
return mOwnerThread; }
207 static Runnable* getCurrentRunnable();
218 static RunnableInfo* _getCurrentRunnableInfo();
219 friend class ::mel::tasking::_private:: RunnableTask;
221 RunnableInfo* mCurrentInfo;
222 std::unique_ptr<ProcessFactory> mDefaultFactory;
224 RunnableCreationOptions mOpts;
225 mel::tasking::_private::MemZoneList mRTZone;
227 std::mutex mMemPoolCS;
228 mel::core::ThreadId mOwnerThread;
231 mel::tasking::_private::RTMemPool* _addNewPool();
233 void _removePool( ::mel::tasking::_private::RTMemPool* );
243 virtual void onPostTask(std::shared_ptr<Process> process){};
263 void postTask(std::shared_ptr<Process> process,
unsigned int startTime = 0);
290 template <
bool ignoreNoThrow=false,
class AllocatorType = ::mel::tasking::DefaultAllocator,
class F,
class KF = const std::function<
bool()>&>
291 std::shared_ptr<Process> post(
293 KF&& killFunction=killFalse,
294 unsigned int period = 0,
unsigned int startTime = 0);
301 template <
bool ignoreNoThrow=false,
class AllocatorType = ::mel::tasking::DefaultAllocator,
class F,
class KF = const std::function<
bool()>&>
302 std::shared_ptr<Process> fireAndForget(
304 unsigned int startTime = 0,
305 KF&& killFunction=killTrue);
314 template <
class TRet,
class F,
class KF = const std::function<
bool()>&>
315 Future<TRet> execute( F&&
function,KF&& killFunction=killFalse) noexcept;
316 template <
class TRet,
class F,
class KF = const std::function<
bool()>&>
334 inline const std::shared_ptr<Timer> getTimer( )
const;
335 inline std::shared_ptr<Timer> getTimer( );
336 inline unsigned int getPendingTaskCount()
const
338 return (
unsigned int)getScheduler().getProcessCount();
344 inline unsigned int getActiveTaskCount()
const
346 return (
unsigned int)getScheduler().getActiveProcessCount();
348 inline unsigned int getMaxPoolSize()
const{
return mOpts.maxPoolSize;}
353 template <
bool ignoreNoThrow,
class AllocatorType,
class F,
class KF>
357 unsigned int period,
unsigned int startTime )
359 static_assert( !ignoreNoThrow || std::is_nothrow_invocable<F,uint64_t,Process*>::value,
"Runnable::post. Task must be noexcept");
360 ::std::shared_ptr<GenericProcess> p(AllocatorType::allocate(
this));
361 p->setProcessCallback( ::std::forward<F>(task_proc) );
362 p->setPeriod( period );
363 p->setKillCallback( ::std::forward<KF>(killFunction) );
367 template <
bool ignoreNoThrow,
class AllocatorType,
class F,
class KF>
370 unsigned int startTime,
373 return post<ignoreNoThrow,AllocatorType>(
374 [f=std::forward<F>(task_proc)](RUNNABLE_TASK_PARAMS)
mutable noexcept( noexcept(task_proc()) )
377 return ::mel::tasking::EGenericProcessResult::KILL;
379 ,std::forward<KF>(killFunction),0,startTime
392 const std::shared_ptr<Timer> Runnable::getTimer( )
const
396 std::shared_ptr<Timer> Runnable::getTimer( )
401 template <
class TRet,
class F,
class KF>
405 return execute(std::forward<F>(
function),future,std::forward<KF>(killFunction));
413 template <
class TRet,
class F,
class KF>
442 [output,f = std::forward<F>(f)](RUNNABLE_TASK_PARAMS)
mutable noexcept
444 if constexpr (noexcept(f()))
446 if constexpr (std::is_same<void,TRet>::value)
453 output.setValue(f());
459 if constexpr (std::is_same<void,TRet>::value)
466 output.setValue(f());
472 output.setError( std::current_exception() );
482 return ::mel::tasking::EGenericProcessResult::KILL;
483 },std::forward<KF>(killFunction)
Definition: CallbackSubscriptor_Impl.h:454
Represents a value that maybe is not present at the current moment.
Definition: Future.h:750
A Process constructed from a functor with signature EGenericProcessResult(uint64_t,...
Definition: GenericProcess.h:24
Base factory class for tasks.
Definition: Runnable.h:62
virtual GenericProcess * onCreate(Runnable *owner) const
Reimplement in children to change default behaviour.
GenericProcess * create(Runnable *owner) const
Create new process for given Runnable.
Definition: Runnable.h:65
Definition: ProcessScheduler.h:59
const std::shared_ptr< Timer > getTimer() const
Definition: ProcessScheduler.h:370
std::variant< BlockingOptions, LockFreeOptions > SchedulerOptions
Scheduler creation options. By default use BlockingOotions.
Definition: ProcessScheduler.h:138
A class representing a "running" task, with added functionality to post events requesting execution o...
Definition: Runnable.h:183
Future< TRet > execute(F &&function, KF &&killFunction=killFalse) noexcept
Executes a function in a context of the Runnable. If this Runnable is in the same thread than caller ...
Definition: Runnable.h:402
void setDefaultFactory(ProcessFactory *factory)
Change default factory used to create task through post and fireAndForget.
Definition: Runnable.h:212
std::shared_ptr< Process > fireAndForget(F &&task_proc, unsigned int startTime=0, KF &&killFunction=killTrue)
Convenient function to post no periodic task with signature void f()
Definition: Runnable.h:368
void setOwnerThreadId(mel::core::ThreadId tid)
Definition: Runnable.h:206
void processTasks()
Performs a controlled loop over the internal queue, executing pending tasks. This function must be ca...
void postTask(std::shared_ptr< Process > process, unsigned int startTime=0)
static std::function< bool()> killFalse
helper function to reject kill when receiving kill signal
Definition: Runnable.h:276
const ProcessScheduler & getScheduler() const
Definition: Runnable.h:384
static std::function< bool()> killTrue
helper function to automatically kill process when receiving kill signal
Definition: Runnable.h:274
const ProcessFactory * getDefaultFactory() const
Retrieves the current default factory for tasks.
Definition: Runnable.h:214
std::shared_ptr< Process > post(F &&task_proc, KF &&killFunction=killFalse, unsigned int period=0, unsigned int startTime=0)
Definition: Runnable.h:354
void setTimer(std::shared_ptr< Timer > timer)
Runnable(RunnableCreationOptions opts)
Constructor.
Definition: Callback_Impl.h:11
Default allocator for new tasks (through Runnable::post) using the runnable default factory Runnable:...
Definition: Runnable.h:78
static GenericProcess * allocate(Runnable *_this)
Allocation function.
Definition: Runnable.h:195
ProcessScheduler::SchedulerOptions schedulerOpts
creation options for internal scheduler
Definition: Runnable.h:197
Definition: Runnable.h:188