This repository has been archived on 2021-01-15. You can view files and clone it, but cannot push or open issues or pull requests.
html-scheduler/index.html

315 lines
13 KiB
HTML

<!DOCTYPE HTML>
<html lang="it">
<head>
<meta charset="utf-8">
<meta name="author" content="Claudio Maggioni, Fabio Brambilla, Pamela Dardano, Federico Mainetti"/>
<meta name="description" content="Simulazione di uno scheduler in HTML, Javascript e (purtroppo) CSS."/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.2/jquery.min.js"></script>
<link href='https://fonts.googleapis.com/css?family=Hammersmith+One' rel='stylesheet' type='text/css'>
<script>
var lunghezzaExec=1 //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;
}
//avvio del programma
for(var i=0; i<100; i++){
risorse.mem[i]= new Memoria();
}
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.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;
}
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;
}
function scriviLog(str){
var $cont = $('.logger');
$cont.append('<p>' + str + '</p>');
$cont[0].scrollTop = $cont[0].scrollHeight;
}
var pidAttuale = 0;
var vuoto=false;
var interrompi=false;
function loopProcessiPronti(){
if(processiPronti.length>0){
if(pidAttuale >= processiPronti.length) pidAttuale=0;
processiPronti[pidAttuale].esecuzioneCicloSingolo();
pidAttuale++;
vuoto=false;
}
else if(!vuoto){
scriviLog("<span style=\"color: white\">Coda dei processi pronti vuota.<span>");
vuoto=true;
}
if(interrompi) return;
window.setTimeout(function(){
loopProcessiPronti();
},lunghezzaExec);
}
function toggleProcessiPronti(){
interrompi= !interrompi;
if(!interrompi) loopProcessiPronti();
}
function testaProcessiPronti(){
for(var j=0; j<100; j++){
new Processo();
}
loopProcessiPronti();
}
function cambiaVel(e,elem){
if(e.keyCode!=13) return;
var tmp = parseInt(elem.value);
if(isNaN(tmp)||tmp<1){
alert("Inserimento non valido.");
return;
}
lunghezzaExec=tmp;
}
</script>
<style type="text/css">
body{
margin: 0;
overflow-x: hidden;
}
.logger{
overflow-y: scroll;
height: 60vh;
background-color: black;
width: calc(100vw - 13rem);
float: left;
}
.logger > p{
margin-top: 0;
margin-bottom: 0;
font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace;
font-size: 1em;
font-weight: bolder;
color: lightgreen;
background: black;
}
.header {
background-color: orange;
height: 3em;
text-align: center;
display: table;
z-index: 1;
width: 100vw;
box-shadow: 0 1px 3px rgba(0,0,0,.12),0 1px 2px rgba(0,0,0,.24);
margin-bottom: 1rem;
font-family: 'Hammersmith One', sans-serif;
}
.header > h1{
font-size: 2em;
color: white;
margin: 0;
display: table-cell;
vertical-align: middle;
font-weight: lighter;
}
.card {
background: #fff;
display: block;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.16), 0 1px 3px rgba(0, 0, 0, 0.23);
}
.nav {
width: 8rem;
padding: .5rem;
font-family: 'Hammersmith One', sans-serif;
margin-left: .5rem;
float: left;
font-weight: lighter;
}
.nav > p, .section.teoria > p{
margin: 0;
}
.nav > p > a{
color: black;
text-transform: uppercase;
text-decoration: none;
}
.sections{
float: right;
width: calc(100vw - 11rem);
margin-bottom: 2rem;
}
.section {
width: calc(100vw - 13rem);
padding: .5rem;
margin: .5rem;
margin-top: 0;
}
div.sections div.section:last-child{
margin-bottom: 0;
}
.footer {
background-color: orange;
color: white;
clear: both;
text-align:center;
position: fixed;
font-size: 0.8em;
width: 100vw;
bottom: 0;
left: 0;
right: 0;
font-family: 'Hammersmith One', sans-serif;
font-weight: lighter;
}
.section.teoria{
font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace;
background: black;
color: white;
}
</style>
</head>
<body>
<div class="header">
<h1>Scheduler</h1>
</div>
<div class="nav card">
<p><a href="javascript:void(0)">HOME</a></p>
<p><a href="javascript:void(0)">GRAFICO</a></p>
<p><a href="javascript:void(0)">TEORIA</a></p>
</div>
<div class="sections">
<div class="section card teoria">
<p>In informatica lo scheduler (da to schedule letteralmente "mettere in lista", ovvero "pianificare") è un componente
di un sistema operativo ovvero un programma che implementa un algoritmo di scheduling il quale, dato un insieme di richieste
di accesso ad una risorsa (tipicamente l'accesso al processore da parte di un processo da eseguire), stabilisce un ordinamento
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 class="section card">
<div class="logger">
</div>
<button type="button" name="aggiungiProcesso" onclick="new Processo()">Aggiungi processo</button>
<button type="button" name="toggleProcessi" onclick="toggleProcessiPronti()">Ferma/riprendi</button>
<label>Velocità (in millisecondi):<input class="inputVel" type="number" onkeypress="cambiaVel(event,this)" value="500"/></label>
</div>
</div>
<div class="footer">
Creato da Claudio Maggioni, Federico Mainetti, Pamela Dardano, Fabio Brambilla
</div>
<script>
testaProcessiPronti()
</script>
</body>
</html>