annotate cos/kernel/task.c @ 299:674789d9ff37

Added a doc
author Windel Bouwman
date Sun, 01 Dec 2013 18:37:23 +0100
parents 91f91ff07ea8
children
rev   line source
28
47b7df514243 Moved Makefiles
windel
parents: 25
diff changeset
1 /* Scheduler functions */
47b7df514243 Moved Makefiles
windel
parents: 25
diff changeset
2
25
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
3 #include "kernel.h"
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
4
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
5 // global variables:
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
6 uint64_t next_pid = 1;
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
7 task_t* ready_queue = 0; // Head of the queue of tasks.
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
8 task_t* current_task = 0; // Pointer to the currently running task.
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
9
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
10 void initialize_tasking()
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
11 {
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
12 next_pid = 1;
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
13 }
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
14
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
15 /*
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
16 Create a new task with some loaded program.
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
17 */
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
18 void new_task()
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
19 {
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
20 task_t* newtask = (task_t*)kmalloc(sizeof(task_t));
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
21 newtask->pid = next_pid++;
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
22 newtask->rip = 0;
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
23 newtask->next = 0;
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
24
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
25 // Append the new task to the ready queue:
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
26 task_t* task = ready_queue;
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
27 while (task->next != 0)
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
28 {
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
29 task = task->next;
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
30 }
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
31 task->next = newtask;
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
32 }
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
33
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
34 /* Fork function duplicates the process */
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
35 void task_fork()
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
36 {
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
37 asm volatile("cli"); // Disable interrupts
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
38 task_t *parent_task = current_task;
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
39
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
40 // Create new task:
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
41 task_t *new_task = (task_t*)kmalloc(sizeof(task_t));
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
42 new_task->pid = next_pid++;
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
43 new_task->rsp = 0;
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
44 new_task->rbp = 0;
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
45 new_task->rip = 0;
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
46 new_task->next = 0;
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
47
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
48 // Append to the queue:
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
49 task_t* tmp_task = ready_queue;
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
50 while (tmp_task->next != 0)
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
51 {
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
52 tmp_task = tmp_task->next;
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
53 }
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
54 tmp_task->next = new_task;
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
55
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
56 uint64_t rip = read_rip();
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
57
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
58 if (current_task == parent_task)
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
59 {
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
60 uint64_t rbp, rsp;
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
61 asm volatile("mov %%rsp, %0" : "=r"(rsp));
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
62 asm volatile("mov %%rbp, %0" : "=r"(rbp));
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
63 new_task->rip = rip;
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
64
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
65 asm volatile("sti");
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
66 }
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
67 }
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
68
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
69 /*
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
70 Scheduler function that switches tasks for multi tasking.
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
71 */
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
72 void task_scheduler()
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
73 {
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
74 if (current_task == 0)
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
75 {
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
76 return;
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
77 }
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
78
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
79 uint64_t rbp, rsp, rip;
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
80
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
81 rip = 0;
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
82 rsp = 0;
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
83 rbp = 0;
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
84
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
85 current_task->rip = rip; // TODO
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
86 current_task->rsp = rsp;
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
87 current_task->rbp = rbp;
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
88
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
89 // Select next task:
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
90 current_task = current_task->next;
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
91 if (current_task == 0)
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
92 {
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
93 current_task = ready_queue;
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
94 }
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
95
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
96 // Set the rbp, rsp and rip registers:
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
97 rsp = current_task->rsp;
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
98 rbp = current_task->rbp;
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
99 }
d3c4bf3720a3 Beginning of multitasking
windel
parents:
diff changeset
100