A Small Cooperative Multitasking Kernel

Dependencies:   mbed

Committer:
Ivop
Date:
Sun Jul 24 17:15:42 2011 +0000
Revision:
0:73b89fc74e9f
first release

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Ivop 0:73b89fc74e9f 1 /* Opus Una - A Small Cooperative Multitasking Kernel in C
Ivop 0:73b89fc74e9f 2 *
Ivop 0:73b89fc74e9f 3 * Copyright (C) 2011 by Ivo van Poorten <ivop@euronet.nl>
Ivop 0:73b89fc74e9f 4 * This file is licensed under the terms of the GNU Lesser
Ivop 0:73b89fc74e9f 5 * General Public License, version 3.
Ivop 0:73b89fc74e9f 6 */
Ivop 0:73b89fc74e9f 7
Ivop 0:73b89fc74e9f 8 #include "kernel.h"
Ivop 0:73b89fc74e9f 9 #include "timer.h"
Ivop 0:73b89fc74e9f 10
Ivop 0:73b89fc74e9f 11 void *ou_state;
Ivop 0:73b89fc74e9f 12 unsigned ou_wait, ou_current_task, ou_ticks;
Ivop 0:73b89fc74e9f 13
Ivop 0:73b89fc74e9f 14 void ou_update_tasks(void) {
Ivop 0:73b89fc74e9f 15 unsigned i;
Ivop 0:73b89fc74e9f 16 for (i=0; i<ou_ntasks; i++)
Ivop 0:73b89fc74e9f 17 if (ou_tasks[i].wait)
Ivop 0:73b89fc74e9f 18 ou_tasks[i].wait--;
Ivop 0:73b89fc74e9f 19 }
Ivop 0:73b89fc74e9f 20
Ivop 0:73b89fc74e9f 21 void ou_scheduler(void) {
Ivop 0:73b89fc74e9f 22 unsigned i, priority, delayed;
Ivop 0:73b89fc74e9f 23
Ivop 0:73b89fc74e9f 24 for(;;) {
Ivop 0:73b89fc74e9f 25 ou_current_task = priority = -1U;
Ivop 0:73b89fc74e9f 26 delayed = 0;
Ivop 0:73b89fc74e9f 27 for (i=0; i<ou_ntasks; i++) {
Ivop 0:73b89fc74e9f 28 if (ou_tasks[i].wait) continue; // task is still waiting
Ivop 0:73b89fc74e9f 29 if (ou_tasks[i].suspended) continue; // task is suspended
Ivop 0:73b89fc74e9f 30 if (ou_tasks[i].priority > priority) continue; // task has lower priority
Ivop 0:73b89fc74e9f 31
Ivop 0:73b89fc74e9f 32 if (ou_tasks[i].priority < priority)
Ivop 0:73b89fc74e9f 33 goto found_better_candidate; // higher priority
Ivop 0:73b89fc74e9f 34 if (ou_tasks[i].delayed > delayed)
Ivop 0:73b89fc74e9f 35 goto found_better_candidate; // equal priority, but waited longer
Ivop 0:73b89fc74e9f 36
Ivop 0:73b89fc74e9f 37 ou_tasks[i].delayed++; // equal priority, but waited shorter
Ivop 0:73b89fc74e9f 38 continue;
Ivop 0:73b89fc74e9f 39
Ivop 0:73b89fc74e9f 40 found_better_candidate:
Ivop 0:73b89fc74e9f 41 if (ou_current_task != -1U)
Ivop 0:73b89fc74e9f 42 ou_tasks[ou_current_task].delayed++; // previous candidate is worse
Ivop 0:73b89fc74e9f 43 priority = ou_tasks[i].priority;
Ivop 0:73b89fc74e9f 44 delayed = ou_tasks[i].delayed;
Ivop 0:73b89fc74e9f 45 ou_current_task = i;
Ivop 0:73b89fc74e9f 46 }
Ivop 0:73b89fc74e9f 47 if (ou_current_task == -1U) { // no runnable task, all are waiting or suspended
Ivop 0:73b89fc74e9f 48 ou_idle();
Ivop 0:73b89fc74e9f 49 continue;
Ivop 0:73b89fc74e9f 50 }
Ivop 0:73b89fc74e9f 51
Ivop 0:73b89fc74e9f 52 ou_state = ou_tasks[ou_current_task].state;
Ivop 0:73b89fc74e9f 53
Ivop 0:73b89fc74e9f 54 ou_tasks[ou_current_task].function(); // run!
Ivop 0:73b89fc74e9f 55
Ivop 0:73b89fc74e9f 56 ou_tasks[ou_current_task].state = ou_state; // returned values
Ivop 0:73b89fc74e9f 57 ou_tasks[ou_current_task].wait = ou_wait; // ...
Ivop 0:73b89fc74e9f 58 }
Ivop 0:73b89fc74e9f 59 }