#ifndef __COROUTINE_MANAGER_HPP__ #define __COROUTINE_MANAGER_HPP__ // Author: Adrian Böckenkamp // Date: 05.10.2011 #include #include #include // the underlying "portable coroutine library" namespace fi { class ExperimentFlow; /** * \class CoroutineManager * Manages the experiments flow encapsulated in coroutines. Each * experiment (flow) has it's associated data structure which is * represented by the ExperimentData-class. */ class CoroutineManager { private: //! the default stack size for coroutines (= experiment flows) static const unsigned STACK_SIZE_DEFAULT = 4096*4096; //! the abstraction for coroutine identification typedef coroutine_t corohandle_t; typedef std::map flowmap_t; //! the mapping "flows <-> coro-handle" flowmap_t m_Flows; //! the simulator/backend coroutine handle corohandle_t m_simCoro; //! stack of coroutines that explicitly activated another one with toggle() std::stack m_togglerstack; //! manages the run-calls for each ExperimentFlow-object static void m_invoke(void* pData); public: static const ExperimentFlow* SIM_FLOW; //!< the simulator coroutine flow CoroutineManager() : m_simCoro(co_current()) { } ~CoroutineManager(); /** * Creates a new coroutine for the specified experiment flow. * @param flow the flow to be executed in the newly created coroutine */ void create(ExperimentFlow* flow); /** * Destroys coroutine for the specified experiment flow. * @param flow the flow to be removed */ void remove(ExperimentFlow* flow); /** * Switches the control flow to the experiment \a flow. If \a flow is * equal to \c SIM_FLOW, the control will be handed back to the * simulator. The current control flow is pushed onto an * internal stack. * @param flow the destination control flow or \c SIM_FLOW (= \c NULL ) */ void toggle(ExperimentFlow* flow); /** * Gives the control back to the coroutine that toggle()d the * current one, by drawing from the internal stack built from * calls to toggle(). */ void resume(); /** * Retrieves the current (active) coroutine (= flow). * @return the current experiment flow. */ ExperimentFlow* getCurrent(); }; } // end-of-namespace: fi #endif /* __COROUTINE_MANAGER_HPP__ */