diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Printer.cc | 19 | ||||
-rw-r--r-- | src/Task.cc | 9 | ||||
-rw-r--r-- | src/TaskMan.cc | 48 |
3 files changed, 71 insertions, 5 deletions
diff --git a/src/Printer.cc b/src/Printer.cc index cb94084..ef0cbf5 100644 --- a/src/Printer.cc +++ b/src/Printer.cc @@ -19,6 +19,10 @@ Balau::Printer::Printer() : m_verbosity(M_STATUS | M_WARNING | M_ERROR) { localPrinter.setGlobal(this); } +void Balau::Printer::setLocal() { + localPrinter.set(this); +} + Balau::Printer * Balau::Printer::getPrinter() { return localPrinter.get(); } void Balau::Printer::_log(uint32_t level, const char * fmt, va_list ap) { @@ -31,11 +35,20 @@ void Balau::Printer::_log(uint32_t level, const char * fmt, va_list ap) { if (l & level) break; - print(prefixes[i]); - print(fmt, ap); - print("\n"); + Printer * printer = getPrinter(); + + printer->_print(prefixes[i]); + printer->_print(fmt, ap); + printer->_print("\n"); } void Balau::Printer::_print(const char * fmt, va_list ap) { vfprintf(stderr, fmt, ap); } + +void Balau::Printer::_print(const char * fmt, ...) { + va_list ap; + va_start(ap, fmt); + _print(fmt, ap); + va_end(ap); +} diff --git a/src/Task.cc b/src/Task.cc index d41f088..9bdad0c 100644 --- a/src/Task.cc +++ b/src/Task.cc @@ -9,10 +9,16 @@ Balau::Task::Task() { stack = malloc(size); coro_create(&ctx, coroutine, this, stack, size); taskMan = TaskMan::getTaskMan(); + taskMan->registerTask(this); tls = tlsManager->createTLS(); status = STARTING; } +Balau::Task::~Task() { + free(stack); + free(tls); +} + void Balau::Task::coroutine(void * arg) { Task * task = reinterpret_cast<Task *>(arg); Assert(task); @@ -38,7 +44,8 @@ void Balau::Task::switchTo() { tlsManager->setTLS(tls); coro_transfer(&taskMan->returnContext, &ctx); tlsManager->setTLS(oldTLS); - status = IDLE; + if (status == RUNNING) + status = IDLE; } void Balau::Task::suspend() { diff --git a/src/TaskMan.cc b/src/TaskMan.cc index 783c683..bbaf35c 100644 --- a/src/TaskMan.cc +++ b/src/TaskMan.cc @@ -1,11 +1,12 @@ #include "TaskMan.h" +#include "Task.h" #include "Main.h" #include "Local.h" static Balau::DefaultTmpl<Balau::TaskMan> defaultTaskMan(50); static Balau::LocalTmpl<Balau::TaskMan> localTaskMan; -Balau::TaskMan::TaskMan() { +Balau::TaskMan::TaskMan() : stopped(false) { coro_create(&returnContext, 0, 0, 0, 0); if (!localTaskMan.getGlobal()) localTaskMan.setGlobal(this); @@ -18,4 +19,49 @@ Balau::TaskMan::~TaskMan() { } void Balau::TaskMan::mainLoop() { + // We need at least one round before bailing :) + do { + taskList::iterator i; + 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; + if (t->getStatus() == Task::STARTING) { + t->switchTo(); + } + } + + // That's probably where we poll for events + + // checking "STOPPED" tasks, and 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)) { + delete t; + tasks.erase(i); + didDelete = true; + break; + } + } + } while (didDelete); + } while (!stopped && tasks.size() != 0); +} + +void Balau::TaskMan::registerTask(Balau::Task * t) { + // lock pending + pendingAdd.insert(t); + // unlock pending } |