//------------------------------------------------------------------- // clockalg.cpp // // Simulations comparing the clock page-replacement algorithm // with the optimal and the FIFO page-replacement algorithms. // // programmer: ALLAN CRUSE // date begun: 23 NOV 2004 //------------------------------------------------------------------- #include // for printf() #include // for random() #define NR_VIRT_PAGES 5 #define NR_PHYS_PAGES 3 #define NR_REFERENCES 24 int pagestream[ NR_REFERENCES ]; int page_cache[ NR_PHYS_PAGES ]; int main( int argc, char **argv ) { //-------------------------------------- // initialize the page-reference stream //-------------------------------------- for (int i = 0; i < NR_REFERENCES; i++) pagestream[ i ] = 1 + random() % NR_VIRT_PAGES; //----------------------------------- // display the page-reference stream //----------------------------------- printf( "\nThe stream of page-references: \n\n" ); for (int i = 0; i < NR_REFERENCES; i++) printf( "%2d ", pagestream[ i ] ); printf( "\n\n" ); //------------------------------------- // perform page-replacement siulations //------------------------------------- int optimal_algorithm( void ); printf( "\noptimal algorithm: %d faults \n\n", optimal_algorithm() ); int clock_algorithm( void ); printf( "\nclock algorithm: %d faults \n\n", clock_algorithm() ); int fifo_algorithm( void ); printf( "\nfifo algorithm: %d faults \n\n", fifo_algorithm() ); } void show_page_cache( void ) { for (int i = 0; i < NR_PHYS_PAGES; i++) printf( "%2d ", page_cache[ i ] ); printf( "\n" ); } int fill_up_pagecache( void ) { int r = 0; // reference-index int u = 0; // unused cache-entry index int p, i; do { p = pagestream[ r ]; // see if p is in page_cache for (i = 0; i < u; i++) if ( p == page_cache[ i ] ) break; if ( i < u ) continue; // page already in cache page_cache[ u++ ] = p; // add to cache } while (( ++r < NR_REFERENCES )&&( u < NR_PHYS_PAGES )); return r; } int fifo_algorithm( void ) { //----------------------- // count the page-faults //----------------------- int faults = 0; int r = fill_up_pagecache(); printf( "pagestream[%d]=%d \t", r, pagestream[ r ] ); show_page_cache(); int next = 0, page_accessed[ NR_PHYS_PAGES ] = {0}; while ( r < NR_REFERENCES ) { int p = pagestream[ r++ ]; // see if page is in cache int i; for (i = 0; i < NR_PHYS_PAGES; i++) if ( p == page_cache[ i ] ) break; if ( i == NR_PHYS_PAGES ) // not in cache { ++faults; page_cache[ next ] = p; next = ( 1 + next ) % NR_PHYS_PAGES; } printf( "pagestream[%d]=%d \t", r, pagestream[ r ] ); show_page_cache(); } return faults; } int optimal_algorithm( void ) { //----------------------- // count the page-faults //----------------------- int faults = 0; int r = fill_up_pagecache(); printf( "pagestream[%d]=%d \t", r, pagestream[ r ] ); show_page_cache(); while ( r < NR_REFERENCES ) { int next_refer[ NR_PHYS_PAGES ]; for (int i = 0; i < NR_PHYS_PAGES; i++) { int j; next_refer[ i ] = NR_REFERENCES; for (j = 1; r+j < NR_REFERENCES; j++) if ( pagestream[ r+j ] == page_cache[ i ] ) break; if ( r+j < NR_REFERENCES ) next_refer[ i ] = j; } int p = pagestream[ r++ ]; int i; for (i = 0; i < NR_PHYS_PAGES; i++) if ( p == page_cache[ i ] ) break; if ( i == NR_PHYS_PAGES ) // not in cache { int max = 0, u; for (i = 0; i < NR_PHYS_PAGES; i++) if ( max < next_refer[ i ] ) { u = i; max = next_refer[ u ]; } page_cache[ u ] = p; ++faults; } printf( "pagestream[%d]=%d \t", r, pagestream[ r ] ); show_page_cache(); } return faults; } int clock_algorithm( void ) { //----------------------- // count the page-faults //----------------------- int faults = 0; int r = fill_up_pagecache(); printf( "pagestream[%d]=%d \t", r, pagestream[ r ] ); show_page_cache(); int next = 0, page_accessed[ NR_PHYS_PAGES ] = {0}; while ( r < NR_REFERENCES ) { int p = pagestream[ r++ ]; // see if page is in cache int i; for (i = 0; i < NR_PHYS_PAGES; i++) if ( p == page_cache[ i ] ) break; if ( i < NR_PHYS_PAGES ) page_accessed[ i ] = 1; else { // not in cache for (i = 0; i < NR_PHYS_PAGES; i++) { if ( page_accessed[ next ] ) { page_accessed[ next ] = 0; next = ( 1 + next ) % NR_PHYS_PAGES; } else break; } ++faults; page_cache[ next ] = p; next = ( 1 + next ) % NR_PHYS_PAGES; } printf( "pagestream[%d]=%d \t", r, pagestream[ r ] ); show_page_cache(); } return faults; }