From 864eeb3a526b1a32c72e1f31a3e1f23dcc5c7409 Mon Sep 17 00:00:00 2001 From: Pixel Date: Sun, 9 Oct 2011 01:12:50 -0700 Subject: More work on the Task manager. Now "Main" is a Task, among the most important changes. Introduced the notion of Events, and managed a coherent task switch. Also, renamed a lot of the variables to have a more coherent naming scheme. --- src/TaskMan.cc | 62 ++++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 41 insertions(+), 21 deletions(-) (limited to 'src/TaskMan.cc') diff --git a/src/TaskMan.cc b/src/TaskMan.cc index bbaf35c..6730f13 100644 --- a/src/TaskMan.cc +++ b/src/TaskMan.cc @@ -6,8 +6,8 @@ static Balau::DefaultTmpl defaultTaskMan(50); static Balau::LocalTmpl localTaskMan; -Balau::TaskMan::TaskMan() : stopped(false) { - coro_create(&returnContext, 0, 0, 0, 0); +Balau::TaskMan::TaskMan() : m_stopped(false) { + coro_create(&m_returnContext, 0, 0, 0, 0); if (!localTaskMan.getGlobal()) localTaskMan.setGlobal(this); } @@ -21,21 +21,13 @@ Balau::TaskMan::~TaskMan() { void Balau::TaskMan::mainLoop() { // We need at least one round before bailing :) do { - taskList::iterator i; + taskList_t::iterator iL; + taskHash_t::iterator iH; Task * t; - // lock pending - // Adding tasks that were added, maybe from other threads - for (i = pendingAdd.begin(); i != pendingAdd.end(); i++) { - Assert(tasks.find(*i) == tasks.end()); - tasks.insert(*i); - } - pendingAdd.clear(); - // unlock pending - // checking "STARTING" tasks, and running them once - for (i = tasks.begin(); i != tasks.end(); i++) { - t = *i; + for (iH = m_tasks.begin(); iH != m_tasks.end(); iH++) { + t = *iH; if (t->getStatus() == Task::STARTING) { t->switchTo(); } @@ -43,25 +35,53 @@ void Balau::TaskMan::mainLoop() { // That's probably where we poll for events - // checking "STOPPED" tasks, and destroying them + // lock pending + // Adding tasks that were added, maybe from other threads + for (iL = m_pendingAdd.begin(); iL != m_pendingAdd.end(); iL++) { + t = *iL; + Assert(m_tasks.find(t) == m_tasks.end()); + m_tasks.insert(t); + } + m_pendingAdd.clear(); + // unlock pending + + // Dealing with stopped and faulted tasks. + // First by signalling the waiters. + for (iH = m_tasks.begin(); iH != m_tasks.end(); iH++) { + t = *iH; + if (((t->getStatus() == Task::STOPPED) || (t->getStatus() == Task::FAULTED)) && + (t->m_waitedBy.size() != 0)) { + Task::waitedByList_t::iterator i; + while ((i = t->m_waitedBy.begin()) != t->m_waitedBy.end()) { + Events::TaskEvent * e = *i; + e->doSignal(); + e->taskWaiting()->switchTo(); + t->m_waitedBy.erase(i); + } + } + } + + // Then, by destroying them. bool didDelete; do { didDelete = false; - for (i = tasks.begin(); i != tasks.end(); i++) { - t = *i; - if ((t->getStatus() == Task::STOPPED) || (t->getStatus() == Task::FAULTED)) { + for (iH = m_tasks.begin(); iH != m_tasks.end(); iH++) { + t = *iH; + if (((t->getStatus() == Task::STOPPED) || (t->getStatus() == Task::FAULTED)) && + (t->m_waitedBy.size() == 0)) { delete t; - tasks.erase(i); + m_tasks.erase(iH); didDelete = true; break; } } } while (didDelete); - } while (!stopped && tasks.size() != 0); + + } while (!m_stopped && m_tasks.size() != 0); } void Balau::TaskMan::registerTask(Balau::Task * t) { // lock pending - pendingAdd.insert(t); + m_pendingAdd.push_back(t); // unlock pending } -- cgit v1.2.3