annotate cos/kernel/task.c @ 25:d3c4bf3720a3

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