jsos
college code for operating system fundamentals in js
git clone https://9o.is/git/jsos.git
memoryManager.js
(5450B)
1 /*
2 * Manages the OS memory.
3 */
4 function MemoryManager() {
5 this.processes = new Array(); // array of pcb's
6
7 /*
8 * Loads a hex program into memory.
9 * @param hex an array of bytes
10 */
11 this.load = function(hex, priority) {
12 var pid = this.getAvailablePage();
13 var availableSwap = undefined;
14
15 // if we get available page
16 if (pid > -1) {
17 var page = pid % TOTAL_PAGES;
18 var bytes = this.hex2Dec(hex);
19 var base = page * MAX_MEMORY_PROGRAM;
20 var limit = (page+1) * MAX_MEMORY_PROGRAM - 1;
21 var process = new pcb(pid, PCB_STATE_RESIDENT, base, limit, base, priority);
22 this.processes[page] = process;
23 _Memory.allocateBytes(bytes, base);
24 this.output();
25 return pid;
26 } else {
27 availableSwap = this.getAvailableSwap();
28 }
29
30 // if we get available swap
31 if (availableSwap.pid > -1) {
32 pid = availableSwap.pid;
33 var block = availableSwap.tsb;
34
35 if(block == undefined) {
36 block = krnFilesystemDriver.getAvailableBlock();
37 krnFilesystemDriver.initBlockSwap(block);
38 }
39
40 var page = pid - (((pid - TOTAL_PAGES) % (SWAPPABLE + 1)) + 1);
41 var bytes = this.hex2Dec(hex);
42 var base = page * MAX_MEMORY_PROGRAM;
43 var limit = (page+1) * MAX_MEMORY_PROGRAM - 1;
44 var process = new pcb(pid, PCB_STATE_RESIDENT, base, limit, base, priority);
45 process.tsb = block;
46
47 this.processes[pid] = process;
48 var swap = new Swap(block);
49 swap.write(swap.data().slice(0, swap.HEADER_SIZE).concat(this.dec2Hex(hex)), true);
50 this.output();
51 }
52
53 return pid;
54 }
55
56 /*
57 * Gets the next available page in memory. Returns -1 if
58 * there is no page available.
59 */
60 this.getAvailablePage = function() {
61 for(var i=0; i<TOTAL_PAGES; i++) {
62 var p = this.processes[i];
63 if(p == undefined)
64 return i;
65 if(p.state == PCB_STATE_TERMINATED)
66 return p.PID;
67 }
68 return -1;
69 }
70
71 /*
72 * Gets the next available swap in disk. Returns -1 if
73 * there is no swap available.
74 */
75 this.getAvailableSwap = function() {
76 for(var i=TOTAL_PAGES; i<TOTAL_PAGES+SWAPPABLE; i++) {
77 var p = this.processes[i];
78 if(p == undefined) {
79 return {pid: i, tsb: undefined};
80 }
81 if(p.state == PCB_STATE_TERMINATED) {
82 return {pid: p.PID, tsb: p.tsb};
83 }
84 }
85 return {pid: -1, tsb: {}};
86 }
87
88 /*
89 * Swaps an entire process by "rolling out" or transfering
90 * a process to swap files in the disk drive.
91 */
92 this.rollOut = function(tsb, pid) {
93 var pid = TOTAL_PAGES-1 != pid ? TOTAL_PAGES-1 : TOTAL_PAGES; //TODO fixed
94 var process = this.processes[pid];
95 process.tsb = tsb;
96
97 var swap = new Swap(tsb);
98 var data = _Memory.deallocateBytes(process.base, process.limit);
99 var hex = this.dec2Hex(data);
100
101 swap.write(swap.data().slice(0, swap.HEADER_SIZE).concat(hex), true);
102 }
103
104 /*
105 * Swaps an entire process by "rolling in" or transfering
106 * a process to memory from swap files in the disk drive.
107 */
108 this.rollIn = function(process) {
109 var swap = new Swap(process.tsb);
110 var data = swap.payload();
111
112 this.rollOut(process.tsb, process.PID);
113 process.tsb = undefined;
114
115 var bytes = this.hex2Dec(data);
116 _Memory.allocateBytes(bytes, process.base);
117 }
118
119 /*
120 * Converts an array of hexadecimals to an array of decimals.
121 */
122 this.hex2Dec = function(hex) {
123 for(var i=0; i<hex.length; i++)
124 hex[i] = parseInt(hex[i], 16);
125 return hex;
126 }
127
128 /*
129 * Converts an array of decimals to an array of hexadecimals.
130 */
131 this.dec2Hex = function(hex) {
132 for(var i=0; i<hex.length; i++) {
133 if(hex[i] != undefined)
134 hex[i] = hex[i].toString(16);
135 }
136 return hex;
137 }
138
139 /*
140 * Outputs pcb attributes of each process in control of this
141 * OS's memory manager to the interface.
142 */
143 this.output = function() {
144 var div = document.getElementById("processesTable");
145 var html =
146 '<tr><th>pid</th><th>state</th><th>base</th>' +
147 '<th>limit</th><th>PC</th><th>ACC</th><th>X</th>' +
148 '<th>Y</th><th>Z</th><th>P</th></tr>';
149
150 for(var i=0; i<this.processes.length; i++) {
151 var p = this.processes[i];
152 var base=p.base-((p.PID%TOTAL_PAGES)*MAX_MEMORY_PROGRAM);
153 var limit=p.limit-((p.PID%TOTAL_PAGES)*MAX_MEMORY_PROGRAM);
154 var pc=p.PC-((p.PID%TOTAL_PAGES)*MAX_MEMORY_PROGRAM);
155
156 if(p.PID >= TOTAL_PAGES) {
157 base=p.base-((p.PID-(((p.PID - TOTAL_PAGES) % (SWAPPABLE + 1)) + 1))*MAX_MEMORY_PROGRAM);
158 limit=p.limit-((p.PID-(((p.PID - TOTAL_PAGES) % (SWAPPABLE + 1)) + 1))*MAX_MEMORY_PROGRAM);
159 pc=p.PC-((p.PID-(((p.PID - TOTAL_PAGES) % (SWAPPABLE + 1)) + 1))*MAX_MEMORY_PROGRAM);
160 }
161
162 html += '<tr>';
163 html += '<td>'+p.PID+'</td>';
164 html += '<td>'+p.state+'</td>';
165 html += '<td>'+pad((base).toString(16),4).toUpperCase()+'</td>';
166 html += '<td>'+pad((limit).toString(16),4).toUpperCase()+'</td>';
167 html += '<td>'+pad((pc).toString(16),4).toUpperCase()+'</td>';
168 html += '<td>'+pad(p.ACC.toString(16),2).toUpperCase()+'</td>';
169 html += '<td>'+pad(p.X.toString(16),2).toUpperCase()+'</td>';
170 html += '<td>'+pad(p.Y.toString(16),2).toUpperCase()+'</td>';
171 html += '<td>'+p.Z.toString(16)+'</td>';
172 html += '<td>'+p.priority.toString(16)+'</td>';
173 html += '</tr>';
174 }
175 div.innerHTML = html;
176 }
177 }