import cbaos v0.1
[cbaos.git] / doc / sched.txt
blob572e97b4eb82fc0fd8a803aefd79cf992b7edcaa
1 cbaos scheduler usage
2 =====================
4 Call
5         sched_init()
7 then create tasks with
8         task_new(&task, task_func, arg, prio)
10 task is the structure, that needs to have these filled:
11         task = (struct task) {
12                 .name = "my name",
13                 .stack = stack_space,
14                 .stack_len = number_of_stack_words,
15         };
17 task_func is a normal function, which is called with u32 arg.
19 Task priority is prio, 0 is the highest priority, TASK_PRIORITY-1 is lowest.
21 Tasks of same priority are preempted every TIME_SLICE miliseconds
23 Tasks will only get scheduled when tasks with higher priority are sleeping or
24 waiting on a semaphore, which should normally be the case. Tasks hogging the
25 CPU are usually a sign of bad design.
26 I don't avoid "priority inversion", I consider apps like that badly designed.
29 When you have tasks setup call
30         sched_start();
32 API
33 Suspend task for >= msecs miliseconds.
34 Returns the number of miliseconds remaining (currently always 0, since task
35 can't be interrupted?)
36         u32 msleep(u32 msecs)
38 Get current tick counter.
39         u32 ticks_now();
41 Checks if timestamps in ticks are before/after another.
42         int time_before(u32 a, u32 b)
43         int time_after(u32 a, u32 b)
45 Semaphores... TODO
49 cbaos scheduler internals
50 =========================
52 Tasks are split into
53         struct list tasks_ready[TASK_PRIORITIES];
54         struct list tasks_waiting[TASK_PRIORITIES];
55         struct task cba;
57 Tasks have TASK_PRIORITIES priorities, 0 being highest.
59 Every task is either on one of task_ready lists, which means it'll get
60 scheduled soon; or on task_waiting lists, which means it's waiting for a
61 timeout (msleep) or on a semaphore.
63 cba task is special, it's on neither of lists, and it only gets ran when
64 there are no tasks on tasks_ready.
65 It should use as little power as possible. It's also special in that it must
66 not use msleep() or take semaphores (as sleeping is done in cba task).
68 sched_start() first runs the cba task to free global stack, and then starts
69 the tick timer.
71 Tick timer is at first started for immediate wakeup, but later, only when
72 needed with sched_next_wake().
73 When tick is triggered, it calls sched_interrupt(), which in turn calls
74 sched_run().
76 Nah, text maybe isn't the best way, lets just list entry points
79 sched_run()
80  |      Entered through tick interrupt, or sched_timeout().
81  |      Updates task lists, picks next task, switches to it.
82  |
83  |- sched_process_timeout(now) - some task finished mdelay()
84  |   |- move the tasks that finished the delay to start of their list
85  |
86  |- pick next task to run (and move it to the end of its list)
87  |- schedule next tick wakeup
88  |- switch to new task (if different)
91 sched_timeout(u32 ticks)
92  |      Entered through msleep() and down().
93  |      Suspends a task for ticks ticks, or until an event happens
94  |
95  |- task_make_waiting(current)
96  |- update next wake up time
97  |- sched_run()
100 task->dont_reschedulea
101         It seems this protects a task from being scheduled while in the middle
102         of acquiring a semaphore (prevents a race).