-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtask.c
146 lines (138 loc) · 4.26 KB
/
task.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
#include "task.h"
#include "global_variables.h"
#include "mm/main_memory.h"
/*
Initialize the list containg all tasks
*/
task_list* init_task_list(){
task_list* tl = malloc(sizeof(task_list));
tl->list = createQueue(1024);
tl->next_pid = 0;
return tl;
}
/*
Initialize a task.
Assign page global directory (pgd), Pre page 2 pages, bookeeping.
*/
int init_task(task_list* tasks){
/* Create a task only if memory not thrashing */
if(!(gm_subsys->main_mem->thrashing)){
/* Initialize a new task */
task_struct* task = malloc(sizeof(task_struct));
task->pid = tasks->next_pid;
task->frames_used = 0;
task->ptlr = 4;
task->status = READY;
tasks->next_pid++;
/* Allocate frame for pgd */
task->pgd = malloc(sizeof(uint32_t));
uint32_t frame_no = get_zeroed_page(gm_subsys->main_mem,task,task->pgd,1);
task->pgd = ((uint32_t*)(gm_subsys->main_mem->mem_arr+(frame_no<<PT_SHIFT)));
push(tasks->list, task);
/* Pre page first 2 blocks of memory - First two pages requested from CS in the traces - Can do by calling page fault for linear address = 0x7fff8000,0x7fff7fe0 */
uint32_t linear_address[2] = {0x7fff8000,0x7fff7fe0};
uint32_t* pgd_ent = pgd_entry(task, linear_address[0]);
do_page_fault(gm_subsys->main_mem, task, pgd_ent, linear_address[0], 1);
uint32_t* pmd_ent = pmd_entry(gm_subsys->main_mem->mem_arr, *pgd_ent, linear_address[0]);
do_page_fault(gm_subsys->main_mem, task, pmd_ent, linear_address[0], 1);
uint32_t* pld_ent = pld_entry(gm_subsys->main_mem->mem_arr, *pmd_ent, linear_address[0]);
do_page_fault(gm_subsys->main_mem, task, pld_ent, linear_address[0], 1);
for(int i=0;i<2;i++){
uint32_t* pt_ent = pt_entry(gm_subsys->main_mem->mem_arr, *pld_ent, linear_address[i]);
do_page_fault(gm_subsys->main_mem, task, pt_ent, linear_address[i], 0);
}
/* Initialise SIG_ATOMIC_MAXtatistics to 0 */
task->stat.references=0;
task->stat.l1_read_miss=0;
task->stat.l1_write_miss=0;
task->stat.l1_read_access=0;
task->stat.l1_write_access=0;
task->stat.l2_miss=0;
task->stat.page_fault=0;
task->stat.page_fault_pt=0;
task->stat.page_replacements=0;
task->stat.tlb_miss=0;
task->stat.max_working_set=0;
task->stat.swapped_out=0;
return task->pid;
}
else{
return -1;
}
}
/*
Get task struct from PID
*/
task_struct* find_task(task_list* tasks, int pid){
if (isEmpty(tasks->list))
return NULL;
q_node* curr = tasks->list->front;
while(((task_struct*)(curr->data_ptr))->pid != pid) {
if(curr->next == NULL)
return NULL;
curr = curr->next;
}
return (task_struct*)curr->data_ptr;
}
/*
Set status of task to running if possible
*/
bool run_task(task_list* tasks, int pid){
task_struct* task = find_task(tasks, pid);
if(task==NULL){
return 0;
}
if(task->status == READY){
task->status = RUNNING;
}
else if(task->status == SWAPPED_OUT && !(gm_subsys->main_mem->thrashing)){
task->status = RUNNING;
}
else{
return 0;
}
return 1;
}
/*
Preempt a running task
*/
bool preempt_task(task_list* tasks, int pid){
task_struct* task = find_task(tasks, pid);
if(task==NULL){
return 0;
}
if(task->status == RUNNING){
task->status = READY;
}
return 1;
}
/*
Kill a task
Remove all pages and page tables from memory.
*/
bool destroy_task(task_list* tasks, int pid){
if (isEmpty(tasks->list))
return 0;
q_node* curr = tasks->list->front;
q_node* prev = 0;
while(((task_struct*)(curr->data_ptr))->pid != pid) {
if(curr->next == NULL)
return 0;
prev = curr;
curr = curr->next;
}
unload_task(gm_subsys->main_mem,(task_struct*)curr->data_ptr,0); /* Imported from main_memory.h */
if(curr == tasks->list->front){
tasks->list->front = tasks->list->front->next;
}
else{
prev->next = curr->next;
}
if(curr==tasks->list->rear){
tasks->list->rear = prev;
}
tasks->list->node_count--;
free(curr->data_ptr);
free(curr);
return 1;
}