Ivo van Poorten
/
opus-una
A Small Cooperative Multitasking Kernel
Diff: kernel.c
- Revision:
- 0:73b89fc74e9f
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kernel.c Sun Jul 24 17:15:42 2011 +0000 @@ -0,0 +1,59 @@ +/* Opus Una - A Small Cooperative Multitasking Kernel in C + * + * Copyright (C) 2011 by Ivo van Poorten <ivop@euronet.nl> + * This file is licensed under the terms of the GNU Lesser + * General Public License, version 3. + */ + +#include "kernel.h" +#include "timer.h" + +void *ou_state; +unsigned ou_wait, ou_current_task, ou_ticks; + +void ou_update_tasks(void) { + unsigned i; + for (i=0; i<ou_ntasks; i++) + if (ou_tasks[i].wait) + ou_tasks[i].wait--; +} + +void ou_scheduler(void) { + unsigned i, priority, delayed; + + for(;;) { + ou_current_task = priority = -1U; + delayed = 0; + for (i=0; i<ou_ntasks; i++) { + if (ou_tasks[i].wait) continue; // task is still waiting + if (ou_tasks[i].suspended) continue; // task is suspended + if (ou_tasks[i].priority > priority) continue; // task has lower priority + + if (ou_tasks[i].priority < priority) + goto found_better_candidate; // higher priority + if (ou_tasks[i].delayed > delayed) + goto found_better_candidate; // equal priority, but waited longer + + ou_tasks[i].delayed++; // equal priority, but waited shorter + continue; + +found_better_candidate: + if (ou_current_task != -1U) + ou_tasks[ou_current_task].delayed++; // previous candidate is worse + priority = ou_tasks[i].priority; + delayed = ou_tasks[i].delayed; + ou_current_task = i; + } + if (ou_current_task == -1U) { // no runnable task, all are waiting or suspended + ou_idle(); + continue; + } + + ou_state = ou_tasks[ou_current_task].state; + + ou_tasks[ou_current_task].function(); // run! + + ou_tasks[ou_current_task].state = ou_state; // returned values + ou_tasks[ou_current_task].wait = ou_wait; // ... + } +} \ No newline at end of file