38#include "threadpool/AIObjectQueue.h"
39#include "threadpool/AIThreadPool.h"
46 while(n > 1) r *= n--;
57 enum task_state_type {
58 Task_start = direct_base_type::state_end,
67 static constexpr state_type state_end = Task_done + 1;
69 m_calculate_factorial(this, 1, &factorial) { }
72 AIPackagedTask<int(
int)> m_calculate_factorial;
75void Task::multiplex_impl(state_type run_state)
81 m_calculate_factorial(5);
82 set_state(Task_dispatch);
86 if (!m_calculate_factorial.dispatch())
96 std::cout <<
"The factorial of 5 = " << m_calculate_factorial.get() << std::endl;
161template<
typename R,
typename ...Args>
165 enum { standby, deferred, executing, finished } m_phase;
167 AIDelayedFunction<R(Args...)> m_delayed_function;
168 AIQueueHandle m_queue_handle;
180 AIFriendOfStatefulTask(parent_task), m_phase(standby), m_condition(condition), m_delayed_function(fp), m_queue_handle(object_queue_handle) { }
193 AIFriendOfStatefulTask(parent_task), m_phase(standby), m_condition(condition), m_delayed_function(object, memfp), m_queue_handle(object_queue_handle) { }
199 void swap(AIPackagedTask& other)
noexcept
201 std::swap(m_condition, other.m_condition);
202 m_delayed_function.swap(other.m_delayed_function);
203 std::swap(m_queue_handle, other.m_queue_handle);
207 void operator()(Args... args);
221 template<
bool has_args =
sizeof... (Args) != 0,
typename std::enable_if<has_args, int>::type = 0>
232 ASSERT(m_phase == finished);
233 return m_delayed_function.get();
240template<
typename R,
typename ...Args>
241AIPackagedTask<R(Args...)>::~AIPackagedTask()
249 ASSERT(m_phase != executing);
253template<
typename R,
typename ...Args>
254inline void AIPackagedTask<R(Args...)>::invoke()
256 m_delayed_function.invoke();
258 m_task->signal(m_condition);
262template<
typename R,
typename ...Args>
263template<bool has_args, typename std::enable_if<has_args, int>::type>
264void AIPackagedTask<R(Args...)>::operator()()
270template<
typename R,
typename ...Args>
271void AIPackagedTask<R(Args...)>::operator()(Args... args)
275 if (
sizeof...(Args) == 0 &&
276 AI_UNLIKELY(m_phase == executing))
283 ASSERT(m_phase == standby);
286 m_delayed_function(args...);
295template<
typename R,
typename ...Args>
296bool AIPackagedTask<R(Args...)>::dispatch()
300 AIThreadPool& thread_pool = AIThreadPool::instance();
301 auto queues_r = thread_pool.queues_read_access();
303 auto& queue_ref = thread_pool.get_queue(queues_r, m_queue_handle);
305 auto queue = queue_ref.producer_access();
306 if (queue.length() == queue_ref.capacity())
313 queue.move_in(std::function<
bool()>([
this](){ this->invoke();
return false; }));
316 queue_ref.notify_one();
320 wait_until([
this](){
return m_phase == finished; }, m_condition);
Declaration of AIDelayedFunction, an object storing a function pointer and its arguments.
Base class of classes that extend AIStatefulTask derived tasks as member function.
Definition: AIFriendOfStatefulTask.h:61
AIPackagedTask(AIStatefulTask *parent_task, AIStatefulTask::condition_type condition, R(*fp)(Args...), AIQueueHandle object_queue_handle)
Definition: AIPackagedTask.h:179
R get() const
Definition: AIPackagedTask.h:230
void swap(AIPackagedTask &other) noexcept
Exchange the state with that of other.
Definition: AIPackagedTask.h:199
AIPackagedTask(AIStatefulTask *parent_task, AIStatefulTask::condition_type condition, C *object, R(C::*memfp)(Args...), AIQueueHandle object_queue_handle)
Definition: AIPackagedTask.h:192
Definition: AIStatefulTask.h:96
AIStatefulTask(bool debug)
Definition: AIStatefulTask.h:352
virtual void multiplex_impl(state_type run_state)=0
Called for base state bs_multiplex.
uint32_t condition_type
The type of the skip_wait and idle bit masks.
Definition: AIStatefulTask.h:99
virtual char const * state_str_impl(state_type run_state) const
Called to stringify a run state for debugging output. Must be overridden.
Definition: AIStatefulTask.cxx:1273