Files
fail/core/controller/CoroutineManager.cc
hsc b70b6fb43a another directory rename: failstar -> fail
"failstar" sounds like a name for a cruise liner from the 80s.  As "*" isn't a
desirable part of directory names, just name the whole thing "fail/", the core
parts being stored in "fail/core/".

Additionally fixing two build system dependency issues:
 - missing jobserver -> protomessages dependency
 - broken bochs -> fail dependency (add_custom_target DEPENDS only allows plain
   file dependencies ... cmake for the win)


git-svn-id: https://www4.informatik.uni-erlangen.de/i4svn/danceos/trunk/devel/fail@956 8c4709b5-6ec9-48aa-a5cd-a96041d1645a
2012-03-08 19:43:02 +00:00

97 lines
2.4 KiB
C++

// Author: Adrian Böckenkamp
// Date: 05.10.2011
#include <iostream>
#include "CoroutineManager.hpp"
#include "../controller/ExperimentFlow.hpp"
namespace fi
{
void CoroutineManager::m_invoke(void* pData)
{
//std::cerr << "CORO m_invoke " << co_current() << std::endl;
reinterpret_cast<ExperimentFlow*>(pData)->coroutine_entry();
co_exit(); // deletes the associated coroutine memory as well
// we really shouldn't get here
std::cerr << "CoroutineManager::m_invoke() shitstorm unloading" << std::endl;
while (1) ;
}
CoroutineManager::~CoroutineManager()
{
}
void CoroutineManager::toggle(ExperimentFlow* flow)
{
m_togglerstack.push(co_current());
//std::cerr << "CORO toggle from " << m_togglerstack.top() << " to ";
if (flow == SIM_FLOW) {
co_call(m_simCoro);
return;
}
flowmap_t::iterator it = m_Flows.find(flow);
assert(it != m_Flows.end() && "FATAL ERROR: Flow does not exist!");
//std::cerr << it->second << std::endl;
co_call(it->second);
}
void CoroutineManager::create(ExperimentFlow* flow)
{
corohandle_t res = co_create(CoroutineManager::m_invoke, flow, NULL,
STACK_SIZE_DEFAULT);
//std::cerr << "CORO create " << res << std::endl;
m_Flows.insert(std::pair<ExperimentFlow*,corohandle_t>(flow, res));
}
void CoroutineManager::remove(ExperimentFlow* flow)
{
// find coroutine handle for this flow
flowmap_t::iterator it = m_Flows.find(flow);
if (it == m_Flows.end()) {
assert(false && "FATAL ERROR: Cannot remove flow");
return;
}
corohandle_t coro = it->second;
//std::cerr << "CORO remove " << coro << std::endl;
// remove flow from active list
m_Flows.erase(it);
// FIXME make sure resume() keeps working
// delete coroutine (and handle the special case we're removing
// ourselves)
if (coro == co_current()) {
co_exit();
} else {
co_delete(coro);
}
}
void CoroutineManager::resume()
{
corohandle_t next = m_togglerstack.top();
m_togglerstack.pop();
//std::cerr << "CORO resume from " << co_current() << " to " << next << std::endl;
co_call(next);
}
ExperimentFlow* CoroutineManager::getCurrent()
{
coroutine_t cr = co_current();
for(std::map<ExperimentFlow*,corohandle_t>::iterator it = m_Flows.begin();
it != m_Flows.end(); it++)
if(it->second == cr)
return (it->first);
assert(false && "FATAL ERROR: The current flow could not be retrieved!");
return 0;
}
const ExperimentFlow* CoroutineManager::SIM_FLOW = NULL;
}