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

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