Prima versione funzionante dello scheduler

This commit is contained in:
Claudio Maggioni 2016-05-10 21:35:43 +02:00
parent 3da3418b99
commit 523f0dc354

View file

@ -4,152 +4,195 @@
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="author" content="Claudio Maggioni, Fabio Brambilla, Pamela Dardano, Federico Mainetti, Ionel Mihali"/> <meta name="author" content="Claudio Maggioni, Fabio Brambilla, Pamela Dardano, Federico Mainetti, Ionel Mihali"/>
<meta name="description" content="Simulazione di uno scheduler in HTML, Javascript e (purtroppo) CSS."/> <meta name="description" content="Simulazione di uno scheduler in HTML, Javascript e (purtroppo) CSS."/>
</head> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.2/jquery.min.js"></script>
<script> <script>
var lungIstante=2000 //in millis var lunghezzaExec=300 //in millis
var risorse = { var risorse = {
file: new Array(5), file: new Array(5),
stampante: 0, stampante: 0,
io: new Array(6), io: new Array(6),
mem: new Array(100) //vettore contenente 100 cloni di memoria mem: new Array(100) //vettore contenente 100 cloni di memoria
} }
var memoria = {
pid: 0, function Memoria(){
istanteAllocazione: -1, this.pid = 0;
numeroPagina: -1 this.istanteAllocazione = 0;
} this.numeroPagina = -1;
var processi = new Array();
var processiTerminati = new Array();
function Processo(){
var pidNuovo=1;
processi.push(this);
this.pid=pidNuovo;
this.pagine=new Array(Math.floor(Math.random()*10)+3); //vettore contenente gli indirizzi di tutte le pagine in ordine
for(var i=0; i<this.pagine.length; i++){
this.pagine[i]=-1;
} }
this.percorsoAllocazione=new Array(Math.floor(Math.random()*10)+this.pagine.length);
for(var i=0; i<this.percorsoAllocazione.length; i++){ //avvio del programma
this.percorsoAllocazione[i]=Math.floor(Math.random()*this.pagine.length); for(var i=0; i<100; i++){
risorse.mem[i]= new Memoria();
} }
for(var i=0; i<this.pagine.length; i++){
if(this.percorsoAllocazione.indexOf(i)==-1){ var pidNuovo = 1;
this.percorsoAllocazione.push(i); function Processo(){
processiPronti.push(this);
this.pid=pidNuovo;
this.logProcesso="";
this.pagine=new Array(Math.floor(Math.random()*10)+3); //vettore contenente gli indirizzi di tutte le pagine in ordine
for(var i=0; i<this.pagine.length; i++){
this.pagine[i]=-1;
} }
} this.percorsoAllocazione=new Array(Math.floor(Math.random()*10)+this.pagine.length);
this.stato="disponibile"; for(var i=0; i<this.percorsoAllocazione.length; i++){
this.contatorePercorso=0; this.percorsoAllocazione[i]=Math.floor(Math.random()*this.pagine.length);
scriviLog("Nuovo processo: pid="+this.pid+" pagine="+this.pagine.length+" lunghezzaPercorso="+this.percorsoAllocazione.length); }
pidNuovo++; for(var i=0; i<this.pagine.length; i++){
} if(this.percorsoAllocazione.indexOf(i)==-1){
Processo.prototype.cambiaStato = function (str) { this.percorsoAllocazione.push(i);
this.stato=str; }
scriviLog("Processo "+this.pid+": "+this.stato); }
}; this.stato="disponibile";
Processo.prototype.termina = function (){ this.contatorePercorso=0;
this.cambiaStato("terminazione"); scriviLog("<span style=\"color: white\">Nuovo processo: pid="+this.pid+" pagine="+
(this.pagine).forEach(function(item, index){ this.pagine.length+" lunghezzaPercorso="+this.percorsoAllocazione.length+"</span>");
resettaPagina(item); pidNuovo++;
}); }
this.cambiaStato("terminato"); Processo.prototype.log = function(str){
var i = processi.indexOf(this); var tmp = str.replace(/ *\<[^>]*\> */g, "");
processiTerminati.push(processi.splice(i, 1)[0]); scriviLog("<span style=\"color: lightblue\">Processo "+this.pid+": </span>"+str+"\n");
}; this.logProcesso+="Processo "+this.pid+": "+tmp+"\n";
Processo.prototype.esecuzioneCicloSingolo = function(){ };
if(this.contatorePercorso>=this.percorsoAllocazione.length){ Processo.prototype.cambiaStato = function (str) {
this.termina(); this.stato=str;
this.log("<span style=\"color: violet\">"+this.stato+"</span>");
};
Processo.prototype.termina = function (){
this.cambiaStato("terminazione");
(this.pagine).forEach(function(item, index){
if(item>=0) resettaPagina(item);
});
this.cambiaStato("terminato");
var i = processiPronti.indexOf(this);
processiTerminati.push(processiPronti.splice(i, 1)[0]);
};
Processo.prototype.esecuzioneCicloSingolo = function(){
if(this.contatorePercorso>=this.percorsoAllocazione.length){
this.termina();
return false;
}
this.stato="esecuzione";
this.log("<span style=\"color: violet\">esecuzione</span> pagina <span style=\"color: orange\">" +
this.percorsoAllocazione[this.contatorePercorso]+"</span>");
if(paginaDaCaricareGiaAllocata(this)){
this.contatorePercorso++;
return true;
}
else {
return allocaSegmento(this);
}
this.stato="pronto";
};
var processiPronti = new Array();
var processiTerminati = new Array();
function allocaSegmento(proc){
//ricerca memoria libera tramite first-fit
for(var i=0; i<100; i++){
if(risorse.mem[i].pid==0) break;
}
if(i==100){
//allocazione fallita
proc.log("<span style=\"color: orange\">Allocazione fallita. Gestione della memoria piena...</span>");
//si applica least recently used
var min=0;
for(i=1; i<100; i++){
if(risorse.mem[min].istanteAllocazione > risorse.mem[i].istanteAllocazione)
min = i;
}
if(!resettaPagina(min)){
proc.log("<span style=\"color: red\">gestione della memoria piena fallita.</span>");
return false;
};
i=min;
}
risorse.mem[i].pid=proc.pid;
risorse.mem[i].numeroPagina=proc.percorsoAllocazione[proc.contatorePercorso];
risorse.mem[i].istanteAllocazione=Date.now();
proc.pagine[proc.percorsoAllocazione[proc.contatorePercorso]]=i;
proc.log("<span style=\"color: grey\">allocata pagina <span style=\"color: orange\">"+proc.percorsoAllocazione[proc.contatorePercorso]+
"</span> in locazione di memoria <span style=\"color: orange\">"+i+"</span></span>");
proc.contatorePercorso++;
return true;
}
function paginaDaCaricareGiaAllocata(proc){
if(proc.contatorePercorso>=proc.percorsoAllocazione.length) return false;
if(proc.pagine[proc.percorsoAllocazione[proc.contatorePercorso]]!=-1) return true;
return false; return false;
} }
scriviLog("Processo "+this.pid+": esecuzione pagina " + this.percorsoAllocazione[this.contatorePercorso]); function resettaPagina(pagina){
if(paginaDaCaricareGiaAllocata(this)){ scriviLog("<span style=\"color: grey\">Libero locazione di memoria <span style=\"color: orange\">"+pagina+"</span></span>");
this.contatorePercorso++; for(var i=0; i<processiPronti.length; i++){
if(processiPronti[i].pid==risorse.mem[pagina].pid){
var a = processiPronti[i].pagine.indexOf(pagina);
if(a<0){
scriviLog("<span style=\"color: red\">Pagina non registrata nel processo.</span>");
return false;
}
processiPronti[i].pagine[a]=-1;
break;
}
}
if(i==processiPronti.length){
scriviLog("<span style=\"color: red\">Pid non trovato. Questa locazione potrebbe essere già libera</span>");
return false;
}
risorse.mem[pagina].pid=0;
risorse.mem[pagina].numeroPagina=-1;
risorse.mem[pagina].istanteAllocazione=-1;
return true; return true;
} }
else { function scriviLog(str){
return allocaSegmento(this); var $cont = $('.logger');
$cont.append('<p>' + str + '</p>');
$cont[0].scrollTop = $cont[0].scrollHeight;
} }
};
function allocaSegmento(proc){ var pidAttuale = 0;
//ricerca memoria libera tramite first-fit var vuoto=false;
for(var i=0; i<100; i++){ function loopProcessiPronti(){
if(risorse.mem[i].pid==0) break; if(processiPronti.length>0){
} if(pidAttuale >= processiPronti.length) pidAttuale=0;
processiPronti[pidAttuale].esecuzioneCicloSingolo();
if(i==100){ pidAttuale++;
//allocazione fallita vuoto=false;
scriviLog("Allocazione fallita. Gestione della memoria piena...");
//si applica least recently used
var min=0;
for(i=1; i<100; i++){
if(risorse.mem[min].istanteAllocazione > risorse.mem[i].istanteAllocazione)
min = i;
} }
if(!resettaPagina(min)){ else if(!vuoto){
scriviLog("Gestione della memoria piena fallita."); scriviLog("<span style=\"color: white\">Coda dei processi pronti vuota.<span>");
return false; vuoto=true;
};
i=min;
}
risorse.mem[i].pid=proc.pid;
risorse.mem[i].numeroPagina=proc.percorsoAllocazione[proc.contatorePercorso];
risorse.mem[i].istanteAllocazione=Date.now();
proc.pagine[proc.percorsoAllocazione[proc.contatorePercorso]]=i;
scriviLog("Allocata pagina "+proc.percorsoAllocazione[proc.contatorePercorso]+" in locazione di memoria "+i);
proc.contatorePercorso++;
return true;
}
function paginaDaCaricareGiaAllocata(proc){
if(proc.contatorePercorso>=proc.percorsoAllocazione.length) return false;
if(proc.pagine[proc.percorsoAllocazione[proc.contatorePercorso]]!=-1) return true;
return false;
}
function resettaPagina(pagina){
scriviLog("Libero locazione di memoria "+pagina);
for(var i=0; i<processi.length; i++){
if(processi[i].pid==risorse.mem[pagina].pid){
var a = processi[i].pagine.indexOf(pagina);
if(a<0){
scriviLog("Pagina non registrata nel processo.");
return false;
}
processi[i].pagine[a]=-1;
break;
} }
window.setTimeout(function(){
loopProcessiPronti();
},lunghezzaExec);
} }
if(i==processi.length){
scriviLog("Pid non trovato. Questa locazione potrebbe essere già libera"); function testaProcessiPronti(){
return false; for(var j=0; j<10; j++){
new Processo();
}
loopProcessiPronti();
} }
risorse.mem[pagina].pid=0; </script>
risorse.mem[pagina].numeroPagina=-1; <style type="text/css">
risorse.mem[pagina].istanteAllocazione=-1; .logger{
return true; overflow-y: scroll;
} height: 50vh;
function scriviLog(str){ background-color: black;
console.log(str); }
//log nella div .logger > p{
} margin-top: 0;
function clone(obj){ margin-bottom: 0;
return JSON.parse(JSON.stringify(obj)); font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace;
} font-size: 1em;
font-weight: bolder;
//avvio del programma color: lightgreen;
for(var i=0; i<100; i++){ }
risorse.mem[i]=clone(memoria); </style>
} </head>
function testAllocazione(){
//test di allocazione
var provaProc = new Processo();
while(provaProc.esecuzioneCicloSingolo());
}
testAllocazione();
</script>
<style type="text/css">
</style>
<body> <body>
<div style="background-color:yellow; color:black; padding:20px;"> <div style="background-color:yellow; color:black; padding:20px;">
<h2>Scheduler</h2> <h2>Scheduler</h2>
@ -159,13 +202,11 @@
temporale per l'esecuzione di tali richieste, privilegiando quelle che rispettano determinati parametri secondo una certa politica temporale per l'esecuzione di tali richieste, privilegiando quelle che rispettano determinati parametri secondo una certa politica
di scheduling, in modo da ottimizzare l'accesso a tale risorsa e consentire così l'espletamento del servizio/istruzione o processo desiderato.</p> di scheduling, in modo da ottimizzare l'accesso a tale risorsa e consentire così l'espletamento del servizio/istruzione o processo desiderato.</p>
</div> </div>
<div> <div class="logger">
<ul>
<li>Processo 1</li>
<li>Processo 2</li>
<li>Processo 3</li>
</ul>
</div> </div>
<h1>Prima modifica</h1> <button type="button" name="aggiungiProcesso" onclick="new Processo()">Aggiungi processo</button>
<script>
testaProcessiPronti()
</script>
</body> </body>
</html> </html>