Ivo van Poorten
/
opus-una
A Small Cooperative Multitasking Kernel
kernel.c@0:73b89fc74e9f, 2011-07-24 (annotated)
- Committer:
- Ivop
- Date:
- Sun Jul 24 17:15:42 2011 +0000
- Revision:
- 0:73b89fc74e9f
first release
Who changed what in which revision?
User | Revision | Line number | New 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 | } |