A Small Cooperative Multitasking Kernel

Dependencies:   mbed

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