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 }