Ragazzi sapete dirmi qual'è l'errore? Non riesco a trovarlo..
/* Programma che simula la Gestione della Memoria virtuale con la rilocazione paginata
* generando PageFault e conseguenti chiamate all'algoritmo LRU.
*
* I passi che segue il programma sono molto semplici. Come prima cosa chiede i dati relativi
* a PC, RAM e PAGINA, dopo di che genera la Tabella delle Pagine e chiede un indirizzo da
* rilocare. Poi effettua in successione questi tre controlli:
* - controlla la validità dell'indirizzo da rilocare.
* - controlla se l'indirizzo non sia stato già rilocato.
* - controlla se viene gerenato PageFault con chiamata all'LRU.
*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <conio.h>
#define uint unsigned int
/*
Effettua il logaritmo con una base scelta.
*/
uint loga(uint x, uint base){
return (uint)(log(x) / log(base));
}
/*
Riloca un indirizzo logico in un indirizzo fisico.
*/
void riloca(uint **tabpag, uint npf, uint *pagfisica, uint offset, uint ind, uint* it){
unsigned int indf;
indf = (ind << (32-offset) >> 32-offset) + (*pagfisica << offset); // ricavo l'indirizzo fisico
tabpag[ind>>offset][1]=1; // shifta a destra i bit dell'indirizzoo logico di una posizione pari all'offset, assegna 1
tabpag[ind>>offset][2]=*pagfisica; // al bit di presenza ed imposta la pagina fisica
printf("L'indirizzo logico %u e' stato rilocato nell'indirizzo fisico %un",ind,indf);
printf("Ovvero la pagina logica %u nella pagina fisica %un",ind>>offset,*pagfisica);
++*pagfisica; // incrementa la pagina fisica
if(*pagfisica >= npf) // se l'incremento supera il numero delle pagine disponbili
*pagfisica = 0; // azzera la pagina al quale rilocare l'indirizzo
tabpag[ind>>offset][3]=*it; // scrive in tabella l'istante di tempo
++*it; // incrementa l'istante di tempo
}
/*
Utilizza l'LRU per rilocare un indirizzo.
*/
void LRU(uint **tabpag, uint npl, uint offset, uint ind, uint* it){
uint i, min=0; // min è l'indice al quale c'è l'elemento con un instante di tempo più piccolo
unsigned int indf;
for(i=1; i<npl; i++){
if(tabpag[0][3] > tabpag[i][3] && tabpag[i][3] != 0)
if(tabpag[min][3] > tabpag[i][3] && tabpag[i][3] != 0)
min=i;
}
tabpag[min][1]=0; // imposta a 0 il bit di presenza dell'elemento con l'istante di tempo più piccol
tabpag[ind>>offset][1]=1; // imposta ad 1 il bit di presenza del nuovo indirizzo rilocato
tabpag[ind>>offset][3]=*it; // aggiorno l'istante di tempo
++*it; // incremento l'istante di tempo
indf = (ind << (32-offset) >> 32-offset) + (tabpag[ind>>offset][1] << offset); // calcolo l'indirizzo fisico
printf("L'indirizzo logico %d e' stato rilocato nell'indirizzo fisico %dn",ind,indf);
}
/*
Controlla e gestisce il rilocamento.
*/
void controlla(uint **tabpag, uint npl, uint npf, uint *pagfisica, uint offset, uint ind, uint* it){
uint i;
uint cout_npf=0; // tiene conto delle pagine fisiche
if(tabpag[ind>>offset][1] == 1){ // se il bit di presenza è ipostato ad 1 vuol dire che è stato già rilocato
printf("L'indirizzo logico %d e' gia' stato rilocato nell'indirizzo fisico %dn",ind,tabpag[ind>>offset][2]);
} else {
for(i=0; i<npl; i++){
if(tabpag[i][1] == 1) // conta il numero degli 1 nella colonna bit di presenza
cout_npf++;
}
if(cout_npf >= npf){ // se il numero di 1 nella colonna bit di presenza è maggiore o uguale al numero delle pagine fisiche
printf("L'indirizzo logico %d puo' essere rilocato in %d indirizzi fisici.n",ind,npf-*pagfisica);
printf("n-> E' stato generato PAGEFAULT con conseguente chiamata dell'LRU.nn");
LRU(tabpag,npl,offset,ind,it); // allora si chiama l'LRU
}
else{ // altrimenti si riloca semplicemente l'indirizzo
printf("n-> E' stato generato PAGEFAULT.nn");
riloca(tabpag,npf,pagfisica,offset,ind,it);
}
}
}
/*
Visualizza la Tabella delle Pagine.
*/
void visualizza(uint **tabpag, uint npl){
uint i;
printf("n -- TABELLA DELLE PAGINE -- nn");
printf("|tIPLt|tBPt|tIPFt|tITt|n");
for(i=0; i<npl; i++){
printf("|t%dt|t%dt|t%dt|t%dt|n",tabpag[i][0],tabpag[i][1],tabpag[i][2],tabpag[i][3]);
}
printf("n -- FINE TABELLA -- n");
}
int main(){
uint pc, ram, pagina; // PC, RAM e PAGINA
uint npl, npf, offset; // Numero Pagina Logica, Numero Pagina Fisica, Offset
uint indl; // Indirizzo logico
uint it=1; // Istante temporale
uint **tabpag; // Tabella delle pagine
uint i; // Contatore
uint pagfisica=0; // Pagina fisica al quale rilocare l'indirizzo logico
char scelta1, scelta2;
do{
printf("Programma che simula la gestione della memoria virtuale.n");
printf("A quanti bit e' il processore? : ");
scanf("%d",&pc);
printf("Quanto e' grande la tua ram? (in byte) : ");
scanf("%d",&ram);
printf("Quanto e' grande la pagina? (in byte) : ");
scanf("%d",&pagina);
if(pagina > ram || pagina > pow(2,pc) || ram > pow(2,pc) || ram <=0 || pagina <=0 || pc <= 0)
printf("I dati inseriti non sono corretti. Riprovare.n");
}
while(pagina > ram || pagina > pow(2,pc) || ram > pow(2,pc) || ram <=0 || pagina <=0 || pc <= 0);
npl=(uint)(pow(2,pc)/pagina);
npf=(uint)(ram/pagina);
offset=loga(pagina,2);
printf("nRiepilogo:n");
printf("-----------------------------n");
printf("SILt%.0f bytet(2^%u)n",pow(2,pc),pc);
printf("SIFt%u bytet(2^%u)n",ram,loga(ram,2));
printf("PAGINAt%u bytet(2^%u)n",pagina,loga(pagina,2));
printf("-----------------------------n");
printf("Numero pagine logiche:t%un",npl);
printf("Numero pagine fisiche:t%un",npf);
printf("Offset:ttt%un",offset);
printf("-----------------------------n");
printf("Creazione della tabella delle pagine in corso...n");
tabpag=(uint**)malloc(npl*sizeof(uint*));
for(i=0; i<npl; i++){
tabpag[i]=(uint*)malloc(4*sizeof(uint));
tabpag[i][0]=i;
tabpag[i][1]=0;
tabpag[i][2]=0;
tabpag[i][3]=0;
}
printf("Tabella creata.n");
printf("Vuoi visualizzare la Tabella delle pagine? (s/n) : ");
scelta1 = getch();
if(scelta1 == 's' || scelta1 == 'S')
visualizza(tabpag,npl);
do{
do{
printf("nQuale indirizzo logico vuoi rilocare? : ");
scanf("%d",&indl);
if(indl < 0 || indl > pow(2,pc))
printf("I dati inseriti non sono corretti. Riprovare.n");
}
while(indl < 0 || indl > pow(2,pc)-1);
controlla(tabpag,npl,npf,&pagfisica,offset,indl,&it);
printf("Vuoi visualizzare la Tabella delle pagine? (s/n) : ");
scelta1 = getch();
if(scelta1 == 's' || scelta1 == 'S')
visualizza(tabpag,npl);
printf("nnRilocare un altro indirizzo? (s/n) : ");
scelta2 = getch();
if(scelta2== 'N'|| scelta2== 'n')
break;
}
while(scelta2 != 'n' || scelta2 != 'N');
for(i=0; i<npl; i++)
free(tabpag[i]);
free(tabpag);
exit(0);
}