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

539 lines
22 KiB
HTML
Raw Normal View History

<!DOCTYPE HTML>
<html lang="it">
<head>
<meta charset="utf-8">
<title>Scheduler</title>
2016-05-11 07:01:11 +00:00
<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."/>
2016-05-13 14:43:15 +00:00
<script src="jquery.min.js"></script>
2016-05-11 11:42:40 +00:00
<link href='https://fonts.googleapis.com/css?family=Hammersmith+One' rel='stylesheet' type='text/css'>
<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;
}
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){
2016-05-11 11:42:40 +00:00
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 (){
2016-05-13 14:43:15 +00:00
if(this.terminazioneCont===undefined){
this.terminazioneCont=0;
this.cambiaStato("terminazione");
}
if(this.pagine[this.terminazioneCont+1]===undefined){
if(this.pagine[this.terminazioneCont]!=-1){
aggiornaMemoria(this.pagine[this.terminazioneCont],"#FF6666");
resettaPagina(this.pagine[this.terminazioneCont]);
this.pagine[this.terminazioneCont]=-1;
}
this.cambiaStato("terminato");
this.terminazioneCont=undefined;
var i = processiPronti.indexOf(this);
processiTerminati.push(processiPronti.splice(i, 1)[0]);
return "TERM";
}
else if(this.pagine[this.terminazioneCont]==-1){
this.terminazioneCont++;
return this.termina();
}
else{
aggiornaMemoria(this.pagine[this.terminazioneCont],"#FF6666");
resettaPagina(this.pagine[this.terminazioneCont]);
this.pagine[this.terminazioneCont]=-1;
this.terminazioneCont++;
return true;
}
};
2016-05-13 14:43:15 +00:00
Processo.prototype.numeroPagineAllocate = function(){
var tmp=0;
for(var i=0; i<this.pagine.length; i++){
if(this.pagine[i]>=0) tmp++;
}
return tmp;
}
Processo.prototype.esecuzioneCicloSingolo = function(){ //false: non terminato, true: terminato
if(this.contatorePercorso>=this.percorsoAllocazione.length){
2016-05-13 14:43:15 +00:00
return this.termina();
}
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++;
2016-05-13 14:43:15 +00:00
this.stato="pronto";
return false;
}
else {
if(allocaSegmento(this)==="DEALLOC") return true;
2016-05-13 14:43:15 +00:00
this.stato="pronto";
return false;
}
};
var processiPronti = new Array();
var processiTerminati = new Array();
function allocaSegmento(proc){
var min=0;
//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
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;
};
aggiornaMemoria(min, "#FF6666");
return "DEALLOC";
}
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;
2016-05-11 11:42:40 +00:00
var interrompi=false;
function loopProcessiPronti(){
if(processiPronti.length>0){
if(pidAttuale >= processiPronti.length) pidAttuale=0;
2016-05-13 14:43:15 +00:00
var tmp;
if((tmp = processiPronti[pidAttuale].esecuzioneCicloSingolo())===true) pidAttuale--;
else if(tmp==="TERM"){
window.setTimeout(aggiornaMemoria, lunghezzaExec);
}
else{
aggiornaMemoria(processiPronti[pidAttuale].pagine[processiPronti[pidAttuale]
.percorsoAllocazione[processiPronti[pidAttuale].contatorePercorso-1]],"#CCFF66");
}
pidAttuale++;
vuoto=false;
}
else if(!vuoto){
scriviLog("<span style=\"color: white\">Coda dei processi pronti vuota.<span>");
vuoto=true;
}
if(interrompi){
if(interrompi===true){
scriviLog("<span style=\"color: white\">In pausa.</span>");
interrompi=2;
}
return;
}
window.setTimeout(function(){
loopProcessiPronti();
},lunghezzaExec);
}
2016-05-11 11:42:40 +00:00
function toggleProcessiPronti(){
if(processiPronti.length==0) return;
2016-05-11 11:42:40 +00:00
interrompi= !interrompi;
if(!interrompi) {
scriviLog("<span style=\"color: white\">Continuo...</span>");
loopProcessiPronti();
}
2016-05-11 11:42:40 +00:00
}
function avvio(){
document.getElementsByName("wiki")[0].href=wikiScheduler;
for(var i=0; i<100; i++){
risorse.mem[i]= new Memoria();
}
2016-05-13 14:43:15 +00:00
for(var j=0; j<10; j++){
new Processo();
}
loopProcessiPronti();
}
2016-05-11 11:42:40 +00:00
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;
}
2016-05-13 14:43:15 +00:00
function aggiornaMemoria(eseguita, colore){
for(var i=0; i<100; i++){
var cella = document.getElementById("memoria"+Math.floor(i/10)+i%10);
if(eseguita==i) cella.style.background=colore;
else if(processiPronti[pidAttuale]!==undefined&&risorse.mem[i].pid==(processiPronti[pidAttuale].pid)) cella.style.background="lightblue";
else if(risorse.mem[i].pid!=0) cella.style.background="orange";
else cella.style.background="white";
cella.innerHTML= risorse.mem[i].pid!=0 ? risorse.mem[i].pid : "";
}
}
function trovaProcessoPronto(pid){
return $.grep(processiPronti, function(e){ return e.pid == pid; });
}
function comandiDaTastiera(e){
switch(e.keyCode){
case 84:
case 116:
//lettera T: nuovo processo
new Processo();
break;
case 69:
case 101:
//lettera E: pausa/riprendi processi
toggleProcessiPronti();
break;
case 67:
case 99:
//lettera C: avanza di un esecuzioneCicloSingolo se è in pausa
if(interrompi) loopProcessiPronti();
break;
case 82:
case 114:
//lettera R: apri wiki dello scheduler
window.open(window.wikiScheduler,"","width=600,height=450");
break;
};
}
</script>
<style type="text/css">
2016-05-11 11:42:40 +00:00
body{
margin: 0;
overflow-x: hidden;
}
h1,h2,h3,h4,h5,h6{
margin: 0;
margin-bottom: .5rem;
text-align: center;
width: 100%;
}
.section.card.loggerSection{
background: lightblue;
}
.logger{
overflow-y: scroll;
2016-05-11 11:42:40 +00:00
height: 60vh;
background-color: black;
2016-05-11 11:42:40 +00:00
width: calc(100vw - 13rem);
float: left;
margin-bottom: .5rem;
}
.logger > p{
margin-top: 0;
margin-bottom: 0;
font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace;
font-size: 1em;
font-weight: bolder;
color: lightgreen;
2016-05-11 11:42:40 +00:00
background: black;
}
2016-05-11 11:42:40 +00:00
.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;
}
.nav {
width: 8rem;
padding: .5rem;
font-family: 'Hammersmith One', sans-serif;
margin-left: .5rem;
background: #cccccc;
2016-05-11 11:42:40 +00:00
float: left;
font-weight: lighter;
position: fixed;
2016-05-11 07:40:11 +00:00
}
2016-05-11 11:42:40 +00:00
.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;
}
.sections > .section{
2016-05-11 11:42:40 +00:00
width: calc(100vw - 13rem);
padding: .5rem;
margin-bottom: .5em;
2016-05-11 07:40:11 +00:00
}
.card{
display: block;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.16), 0 1px 3px rgba(0, 0, 0, 0.23);
}
2016-05-11 11:42:40 +00:00
div.sections div.section:last-child{
margin-bottom: 0;
}
.footer {
background-color: orange;
color: white;
clear: both;
2016-05-11 07:40:11 +00:00
text-align:center;
2016-05-11 11:42:40 +00:00
position: fixed;
font-size: 0.8em;
width: 100vw;
bottom: 0;
left: 0;
right: 0;
2016-05-11 07:40:11 +00:00
}
.btn {
position: relative;
display: block;
margin-left: .5rem;
padding: .5rem;
overflow: hidden;
border-width: 0;
color: white;
float: left;
outline: none;
box-shadow: 0 1px 4px rgba(0, 0, 0, .6);
background-color: #2ecc71;
transition: background-color .3s;
font-size: 1em;
}
.btn:hover, .btn:focus {
background-color: #27ae60;
}
.btn > * {
position: relative;
}
.btn span {
display: block;
padding: 12px 24px;
}
.btn:before {
content: "";
position: absolute;
top: 50%;
left: 50%;
display: block;
width: 0;
padding-top: 0;
border-radius: 100%;
background-color: rgba(236, 240, 241, .3);
-webkit-transform: translate(-50%, -50%);
-moz-transform: translate(-50%, -50%);
-ms-transform: translate(-50%, -50%);
-o-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
}
.btn:active:before {
width: 120%;
padding-top: 120%;
transition: width .2s ease-out, padding-top .2s ease-out;
}
.buttons{
display: inline-block;
margin-bottom: .5rem;
width: 100%;
}
div.buttons button:first-child{
margin-left: 0px;
}
div.buttons button:last-child{
margin-right: 0px;
}
2016-05-11 11:42:40 +00:00
.section.teoria{
font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace;
background: black;
color: white;
}
label,input,button,.footer,table,h1,h2,h3,h4,h5,h6{
font-family: 'Hammersmith One', sans-serif;
font-weight: lighter;
}
input{
border: 0;
border-bottom: 1px solid #2ecc71;
margin-left: .5rem;
background: rgba(0,0,0,0);
}
td.memCell{
width: 3em;
height: 3em;
background: white;
text-align: center;
vertical-align: middle;
}
.memTable{
display: inline-block;
}
.section.card.memory{
text-align: center;
background: lightgreen;
2016-05-11 11:42:40 +00:00
}
2016-05-12 10:51:02 +00:00
@media screen and (max-width: 600px) {
.nav{
width: calc(100vw - 3rem);
margin-bottom: .5rem;
float: none;
position: static;
2016-05-12 10:51:02 +00:00
}
.sections{
float: none;
margin-left: .5rem;
2016-05-12 10:51:02 +00:00
width: calc(100vw - 1rem);
margin-bottom: .5rem;
2016-05-12 10:51:02 +00:00
}
.sections > .section{
2016-05-12 10:51:02 +00:00
width: calc(100vw - 3rem);
}
.footer{
display: none;
}
.sections > .section > .logger{
width: 100%;
}
2016-05-12 10:51:02 +00:00
}
</style>
</head>
<body onkeypress="comandiDaTastiera(event)">
2016-05-11 11:42:40 +00:00
<div class="header">
<h1>Scheduler</h1>
2016-05-11 07:01:11 +00:00
</div>
2016-05-11 11:42:40 +00:00
<div class="nav card">
<p><a href="#teoria">TEORIA</a></p>
<p><a href="#log">LOG</a></p>
<p><a href="#memoria">MEMORIA</a></p>
<p><a name="wiki">WIKI</a></p>
</div>
2016-05-11 11:42:40 +00:00
<div class="sections">
<div class="section card teoria">
<a name="teoria"><h2>Teoria</h2></a>
2016-05-11 11:42:40 +00:00
<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 loggerSection">
<a name="log"><h2>Log dello scheduler</h2></a>
2016-05-11 11:42:40 +00:00
<div class="logger">
</div>
2016-05-12 10:51:02 +00:00
<div class="controls">
<div class="buttons">
<button type="button" class="btn" name="aggiungiProcesso" onclick="new Processo()">Aggiungi processo</button>
<button type="button" class="btn" name="toggleProcessi" onclick="toggleProcessiPronti()">Ferma o riprendi</button>
2016-05-18 09:21:56 +00:00
<button type="button" class="btn" name="vaiAvanti" onclick="if(interrompi) loopProcessiPronti()">Procedi di un ciclo</button>
</div>
<label>Tempo tra i cambi di contesto (in millisecondi):<input class="inputVel" type="number" onkeypress="cambiaVel(event,this)" value="300"/></label>
2016-05-12 10:51:02 +00:00
</div>
</div>
<div class="section card memory">
<a name="memoria"><h2>Memoria</h2></a>
<table class="memTable">
<tbody>
<script>
for(var i=0; i<10; i++){
document.write("<tr>")
for(var j=0; j<10; j++){
2016-05-13 14:43:15 +00:00
document.write("<td class=\"card memCell\" style=\"display: table-cell\" id=\"memoria"+i+j+"\"></td>");
}
document.write("</tr>")
}
</script>
</tbody>
</table>
</div>
2016-05-11 07:01:11 +00:00
</div>
2016-05-11 11:42:40 +00:00
<div class="footer">
Creato da Claudio Maggioni, Federico Mainetti, Pamela Dardano, Fabio Brambilla
</div>
<script>
avvio();
</script>
</body>
</html>