From 6d956657c4612e988f89a133cea93e50ec2dcb39 Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Fri, 2 Aug 2013 10:04:38 +0200 Subject: Adding AtStartAsTask and AtExitAsTask concepts. --- src/Main.cc | 97 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 96 insertions(+), 1 deletion(-) (limited to 'src/Main.cc') diff --git a/src/Main.cc b/src/Main.cc index 7c205d4..e872411 100644 --- a/src/Main.cc +++ b/src/Main.cc @@ -2,9 +2,12 @@ #include "TaskMan.h" #include "Printer.h" #include "AtStartExit.h" +#include "StacklessTask.h" Balau::AtStart * Balau::AtStart::s_head = 0; Balau::AtExit * Balau::AtExit::s_head = 0; +Balau::AtStartAsTask * Balau::AtStartAsTask::s_head = 0; +Balau::AtExitAsTask * Balau::AtExitAsTask::s_head = 0; Balau::AtStart::AtStart(int priority) : m_priority(priority) { if (priority < 0) @@ -36,6 +39,36 @@ Balau::AtExit::AtExit(int priority) : m_priority(priority) { *ptr = this; } +Balau::AtStartAsTask::AtStartAsTask(int priority) : m_priority(priority) { + if (priority < 0) + return; + AAssert(!Main::hasMain(), "An AtStartAsTask can't be created dynamically"); + + AtStartAsTask ** ptr = &s_head; + + m_next = 0; + + for (ptr = &s_head; *ptr && (priority > (*ptr)->m_priority); ptr = &((*ptr)->m_next)); + + m_next = *ptr; + *ptr = this; +} + +Balau::AtExitAsTask::AtExitAsTask(int priority) : m_priority(priority) { + if (priority < 0) + return; + AAssert(!Main::hasMain(), "An AtExitAsTask can't be created dynamically"); + + AtExitAsTask ** ptr = &s_head; + + m_next = 0; + + for (ptr = &s_head; *ptr && (priority > (*ptr)->m_priority); ptr = &((*ptr)->m_next)); + + m_next = *ptr; + *ptr = this; +} + Balau::Main * Balau::Main::s_application = NULL; Balau::MainTask::~MainTask() { @@ -47,6 +80,68 @@ const char * Balau::MainTask::getName() const { return "Main Task"; } +namespace Balau { + +class BootstrapTask : public StacklessTask { + public: + BootstrapTask(int argc, char ** argv, char ** enve) : m_argc(argc), m_argv(argv), m_enve(enve) { } + virtual void Do() { + Balau::Task * t; + try { + switch (m_state) { + case 0: + m_ptrStart = AtStartAsTask::s_head; + m_ptrExit = AtExitAsTask::s_head; + m_state = 1; + case 1: + if (m_ptrStart) { + t = m_ptrStart->createStartTask(); + if (m_waiting) + m_evt.ack(); + m_evt.attachToTask(t); + m_waiting = true; + waitFor(&m_evt); + TaskMan::registerTask(t); + m_ptrStart = m_ptrStart->m_next; + yield(); + } + m_state = 2; + t = new MainTask(m_argc, m_argv, m_enve); + if (m_waiting) + m_evt.ack(); + m_evt.attachToTask(t); + waitFor(&m_evt); + TaskMan::registerTask(t); + yield(); + case 2: + if (m_ptrExit) { + t = m_ptrExit->createExitTask(); + m_evt.ack(); + m_evt.attachToTask(t); + waitFor(&m_evt); + TaskMan::registerTask(t); + m_ptrExit = m_ptrExit->m_next; + yield(); + } + } + } + catch (EAgain &) { + taskSwitch(); + } + } + private: + virtual const char * getName() const { return "BootstrapTask"; } + int m_argc; + char ** m_argv; + char ** m_enve; + AtStartAsTask * m_ptrStart = NULL; + AtExitAsTask * m_ptrExit = NULL; + Events::TaskEvent m_evt; + bool m_waiting = false; +}; + +}; + int Balau::Main::bootstrap(int argc, char ** argv) { int r = 0; m_status = STARTING; @@ -56,7 +151,7 @@ int Balau::Main::bootstrap(int argc, char ** argv) { try { m_status = RUNNING; - TaskMan::registerTask(new MainTask(argc, argv, NULL)); + TaskMan::registerTask(new BootstrapTask(argc, argv, NULL)); r = TaskMan::getDefaultTaskMan()->mainLoop(); m_status = STOPPING; } -- cgit v1.2.3