Memoria virtuale-programma sulla rilocazione paginata

di il
1 risposte

Memoria virtuale-programma sulla rilocazione paginata

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);
}

1 Risposte

Devi accedere o registrarti per scrivere nel forum
1 risposte