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 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."/>
</head>
<script>
var lungIstante=2000 //in millis
var risorse = {
file: new Array(5),
stampante: 0,
io: new Array(6),
mem: new Array(100) //vettore contenente 100 cloni di memoria
}
var memoria = {
pid: 0,
istanteAllocazione: -1,
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;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.2/jquery.min.js"></script>
<script>
var lunghezzaExec=300 //in millis
var risorse = {
file: new Array(5),
stampante: 0,
io: new Array(6),
mem: new Array(100) //vettore contenente 100 cloni di memoria
}
function Memoria(){
this.pid = 0;
this.istanteAllocazione = 0;
this.numeroPagina = -1;
}
this.percorsoAllocazione=new Array(Math.floor(Math.random()*10)+this.pagine.length);
for(var i=0; i<this.percorsoAllocazione.length; i++){
this.percorsoAllocazione[i]=Math.floor(Math.random()*this.pagine.length);
//avvio del programma
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){
this.percorsoAllocazione.push(i);
var pidNuovo = 1;
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.stato="disponibile";
this.contatorePercorso=0;
scriviLog("Nuovo processo: pid="+this.pid+" pagine="+this.pagine.length+" lunghezzaPercorso="+this.percorsoAllocazione.length);
pidNuovo++;
}
Processo.prototype.cambiaStato = function (str) {
this.stato=str;
scriviLog("Processo "+this.pid+": "+this.stato);
};
Processo.prototype.termina = function (){
this.cambiaStato("terminazione");
(this.pagine).forEach(function(item, index){
resettaPagina(item);
});
this.cambiaStato("terminato");
var i = processi.indexOf(this);
processiTerminati.push(processi.splice(i, 1)[0]);
};
Processo.prototype.esecuzioneCicloSingolo = function(){
if(this.contatorePercorso>=this.percorsoAllocazione.length){
this.termina();
this.percorsoAllocazione=new Array(Math.floor(Math.random()*10)+this.pagine.length);
for(var i=0; i<this.percorsoAllocazione.length; i++){
this.percorsoAllocazione[i]=Math.floor(Math.random()*this.pagine.length);
}
for(var i=0; i<this.pagine.length; i++){
if(this.percorsoAllocazione.indexOf(i)==-1){
this.percorsoAllocazione.push(i);
}
}
this.stato="disponibile";
this.contatorePercorso=0;
scriviLog("<span style=\"color: white\">Nuovo processo: pid="+this.pid+" pagine="+
this.pagine.length+" lunghezzaPercorso="+this.percorsoAllocazione.length+"</span>");
pidNuovo++;
}
Processo.prototype.log = function(str){
var tmp = str.replace(/ *\<[^>]*\> */g, "");
scriviLog("<span style=\"color: lightblue\">Processo "+this.pid+": </span>"+str+"\n");
this.logProcesso+="Processo "+this.pid+": "+tmp+"\n";
};
Processo.prototype.cambiaStato = function (str) {
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;
}
scriviLog("Processo "+this.pid+": esecuzione pagina " + this.percorsoAllocazione[this.contatorePercorso]);
if(paginaDaCaricareGiaAllocata(this)){
this.contatorePercorso++;
function resettaPagina(pagina){
scriviLog("<span style=\"color: grey\">Libero locazione di memoria <span style=\"color: orange\">"+pagina+"</span></span>");
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;
}
else {
return allocaSegmento(this);
function scriviLog(str){
var $cont = $('.logger');
$cont.append('<p>' + str + '</p>');
$cont[0].scrollTop = $cont[0].scrollHeight;
}
};
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
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;
var pidAttuale = 0;
var vuoto=false;
function loopProcessiPronti(){
if(processiPronti.length>0){
if(pidAttuale >= processiPronti.length) pidAttuale=0;
processiPronti[pidAttuale].esecuzioneCicloSingolo();
pidAttuale++;
vuoto=false;
}
if(!resettaPagina(min)){
scriviLog("Gestione della memoria piena fallita.");
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;
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;
else if(!vuoto){
scriviLog("<span style=\"color: white\">Coda dei processi pronti vuota.<span>");
vuoto=true;
}
window.setTimeout(function(){
loopProcessiPronti();
},lunghezzaExec);
}
if(i==processi.length){
scriviLog("Pid non trovato. Questa locazione potrebbe essere già libera");
return false;
function testaProcessiPronti(){
for(var j=0; j<10; j++){
new Processo();
}
loopProcessiPronti();
}
risorse.mem[pagina].pid=0;
risorse.mem[pagina].numeroPagina=-1;
risorse.mem[pagina].istanteAllocazione=-1;
return true;
}
function scriviLog(str){
console.log(str);
//log nella div
}
function clone(obj){
return JSON.parse(JSON.stringify(obj));
}
//avvio del programma
for(var i=0; i<100; i++){
risorse.mem[i]=clone(memoria);
}
function testAllocazione(){
//test di allocazione
var provaProc = new Processo();
while(provaProc.esecuzioneCicloSingolo());
}
testAllocazione();
</script>
<style type="text/css">
</style>
</script>
<style type="text/css">
.logger{
overflow-y: scroll;
height: 50vh;
background-color: black;
}
.logger > p{
margin-top: 0;
margin-bottom: 0;
font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace;
font-size: 1em;
font-weight: bolder;
color: lightgreen;
}
</style>
</head>
<body>
<div style="background-color:yellow; color:black; padding:20px;">
<h2>Scheduler</h2>
@ -159,13 +202,11 @@
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>
</div>
<div>
<ul>
<li>Processo 1</li>
<li>Processo 2</li>
<li>Processo 3</li>
</ul>
<div class="logger">
</div>
<h1>Prima modifica</h1>
<button type="button" name="aggiungiProcesso" onclick="new Processo()">Aggiungi processo</button>
<script>
testaProcessiPronti()
</script>
</body>
</html>