// To run this program you need to enter command like this: // java Sim 4 < input1.txt // The 4 is the number of frames. input1.txt is where ref string is // We represent the collection of resident frames as an ArrayList // rather than an array, in order to make use of the built-in contains() // method and also to make it easier to print out. import java.util.ArrayList; import java.util.Scanner; public class Sim { public static void main(String [] args) { int numFrames = Integer.parseInt(args[0]); System.out.printf("There are %d frames.\n", numFrames); // Read input ArrayList refString = new ArrayList(); Scanner kbd = new Scanner(System.in); while(kbd.hasNextInt()) { int value = kbd.nextInt(); //System.out.printf("I see %d in input\n", value); refString.add("" + value); } // What's in refString? System.out.printf("Here is the ref string:\n%s\n", refString); ///////////////////////////////////////////////////////////////// // Clairvoyant - "Replace the page that will not be used for the // longest period of time in the future. ///////////////////////////////////////////////////////////////// int clairvoyantFaults = 0; ArrayList clairvoyant = new ArrayList(); for (int i = 0; i < refString.size(); ++i) { String nextPageStr = refString.get(i); System.out.printf("try %s: ", nextPageStr); if (clairvoyant.contains(nextPageStr)) { System.out.printf("hit\n"); continue; } // Page fault if (clairvoyant.size() < numFrames) { System.out.printf("Compulsory miss\n"); clairvoyant.add(nextPageStr); } // Need to replace somebody. Who will not be needed for the // longest period of time, looking into the future? // For each resident page, determine when it will next be needed! else { int [] forward = new int[clairvoyant.size()]; for (int j = 0; j < clairvoyant.size(); ++j) { String resident = clairvoyant.get(j); boolean found = false; for (int k = i+1; k < refString.size(); ++k) { if (refString.get(k).equals(resident)) { found = true; forward[j] = k; break; } } // If never used again, let's give a de-facto value of forward. if (found == false) forward[j] = refString.size(); } // At this point we know when every resident page will be used // again. Find the one with the furthest return time. int max = forward[0]; int maxIndex = 0; for (int j = 1; j < clairvoyant.size(); ++j) { if (forward[j] > max) { max = forward[j]; maxIndex = j; } } // Max at maxIndex is our victim. Replace it with nextPageStr. String victim = clairvoyant.get(maxIndex); clairvoyant.set(maxIndex, nextPageStr); System.out.printf("Had to replace %s. New clairvoyant frames: %s\n", victim, clairvoyant); } ++clairvoyantFaults; } System.out.printf("In all, I fouind %d clairvoyant faults.\n", clairvoyantFaults); ///////////////////////////////////////////////////////////////// // FIFO ///////////////////////////////////////////////////////////////// int fifoFaults = 0; ArrayList fifo = new ArrayList(); for (int i = 0; i < refString.size(); ++i) { String nextPageStr = refString.get(i); System.out.printf("try %s: ", nextPageStr); if (fifo.contains(nextPageStr)) { System.out.printf("hit\n"); continue; } // Page fault if (fifo.size() < numFrames) { System.out.printf("Compulsory miss\n"); fifo.add(nextPageStr); } else { // need to evict oldest, at index 0 String victim = fifo.get(0); fifo.remove(0); fifo.add(nextPageStr); System.out.printf("Had to evict %s. New fifo frames: %s\n", victim, fifo); } ++fifoFaults; } System.out.printf("In all, I found %d FIFO page faults.\n", fifoFaults); ///////////////////////////////////////////////////////////////// // Second chance FIFO // We need to maintain a pointer to keep track of the "clock hand" // and a reference bit for each frame. ///////////////////////////////////////////////////////////////// int secondChanceFaults = 0; ArrayList secondChance = new ArrayList(); int [] reference = new int [numFrames]; int pointer = 0; for (int i = 0; i < refString.size(); ++i) { String nextPageStr = refString.get(i); System.out.printf("try %s: ", nextPageStr); if (secondChance.contains(nextPageStr)) { System.out.printf("hit\n"); reference[secondChance.indexOf(nextPageStr)] = 1; continue; } // Page fault if (secondChance.size() < numFrames) { System.out.printf("Compulsory miss\n"); reference[secondChance.size()] = 1; secondChance.add(nextPageStr); } // We need to replace somebody! else { // Look for a victim: Continually increment the pointer. // Stop when the reference bit is zero. while (reference[pointer] == 1) { reference[pointer] = 0; pointer = (pointer + 1) % numFrames; } // The pointer is pointing at our victim. // When we replace with a new page in this frame, // set its corresponding reference bit and move the pointer // to the next position. String victim = secondChance.get(pointer); secondChance.set(pointer, nextPageStr); reference[pointer] = 1; pointer = (pointer + 1) % numFrames; System.out.printf("Had to evict %s. New second-chance frames: %s\n", victim, secondChance); } ++secondChanceFaults; } System.out.printf("In all, I found %d second-chance page faults.\n", secondChanceFaults); ///////////////////////////////////////////////////////////////// // LRU - Similar to clairvoyant, except we look backward in time. // When it's time to look for a victim, see when each resident // frame was most recently used. The frame with the oldest such // time is our victim. ///////////////////////////////////////////////////////////////// int LRUFaults = 0; /* implement LRU here */ System.out.printf("In all, I fouind %d LRU faults.\n", LRUFaults); } }