A Small Cooperative Multitasking Kernel

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers kernel.c Source File

kernel.c

00001 /* Opus Una - A Small Cooperative Multitasking Kernel in C
00002  *
00003  * Copyright (C) 2011 by Ivo van Poorten <ivop@euronet.nl>
00004  * This file is licensed under the terms of the GNU Lesser
00005  * General Public License, version 3.
00006  */
00007 
00008 #include "kernel.h"
00009 #include "timer.h"
00010 
00011 void *ou_state;
00012 unsigned ou_wait, ou_current_task, ou_ticks;
00013 
00014 void ou_update_tasks(void) {
00015     unsigned i;
00016     for (i=0; i<ou_ntasks; i++)
00017         if (ou_tasks[i].wait)
00018             ou_tasks[i].wait--;
00019 }
00020 
00021 void ou_scheduler(void) {
00022     unsigned i, priority, delayed;
00023 
00024     for(;;) {
00025         ou_current_task = priority = -1U;
00026         delayed = 0;
00027         for (i=0; i<ou_ntasks; i++) {
00028             if (ou_tasks[i].wait)                continue;      // task is still waiting
00029             if (ou_tasks[i].suspended)           continue;      // task is suspended
00030             if (ou_tasks[i].priority > priority) continue;      // task has lower priority
00031 
00032             if (ou_tasks[i].priority < priority)
00033                 goto found_better_candidate;        // higher priority
00034             if (ou_tasks[i].delayed > delayed)
00035                 goto found_better_candidate;        // equal priority, but waited longer
00036 
00037             ou_tasks[i].delayed++;                  // equal priority, but waited shorter
00038             continue;
00039 
00040 found_better_candidate:
00041             if (ou_current_task != -1U)
00042                 ou_tasks[ou_current_task].delayed++; // previous candidate is worse
00043             priority        = ou_tasks[i].priority;
00044             delayed         = ou_tasks[i].delayed;
00045             ou_current_task = i;
00046         }
00047         if (ou_current_task == -1U) {      // no runnable task, all are waiting or suspended
00048             ou_idle();
00049             continue;
00050         }
00051 
00052         ou_state = ou_tasks[ou_current_task].state;
00053 
00054         ou_tasks[ou_current_task].function();   // run!
00055 
00056         ou_tasks[ou_current_task].state = ou_state;     // returned values
00057         ou_tasks[ou_current_task].wait  = ou_wait;      // ...
00058     }
00059 }