/** * The Simulator class allows the user to input a file containing a list of * processes and to choose a type of Scheduler and a length of time for which * to run. It then simulates that scheduler's actions on the processes, * and reports the results back to the user. */ import java.io.*; import java.util.*; class Simulator { protected static Process[] _processes; protected static Scheduler _scheduler; public static void main ( String[] args) throws IOException{ BufferedReader reader = new BufferedReader( new InputStreamReader( System.in ) ); String input, filename; File file = new File( "default.txt" ); Integer runTime = -1; boolean quit = false, validFile = false; // Prompts the user for a valid filename from which to read // descriptions of the processes while ( !quit && !validFile ) { System.out.print ( "Enter a filename containing the processes: "); filename = reader.readLine(); file = new File( filename ); if ( file.exists() ) { validFile = true; } else { System.out.print ( "Invalid filename. Quit? (y/n) "); input = reader.readLine(); if ( input.equalsIgnoreCase("y") ) quit = true; } } if (!quit) { // Initialize the Processes and Scheduler. _processes = initProcesses( file ); _scheduler = initScheduler( _processes, reader ); } // Until either the user decides to quit or all processes are // finished, ask the user for an amount of time, run the scheduler // for that amount of time, report back results, and repeat. while ( !quit && !_scheduler.finished() ) { System.out.print ( "Enter an amount of time for the scheduler to run " + "(enter -1 to run until processes complete): "); input = reader.readLine(); runTime = new Integer(input); if (runTime == -1) _scheduler.runAndReport(); else _scheduler.runAndReport( runTime ); if ( !_scheduler.finished() ) { System.out.print( "Update processes and continue to run? (y/n) "); input = reader.readLine(); if ( input.equalsIgnoreCase("n") ) quit = true; } if ( quit || _scheduler.finished() ) { _scheduler.finalReport(); } if ( !quit && !_scheduler.finished() ) { // Report on the current processes, then prompt the user // to enter updated data for them System.out.println("--- Current Processes ---"); printProcesses( ); updateProcesses( _scheduler, reader ); } } // end while loop } // end main // Prompts the user to update the scheduler's processes. The user may // change processes' working set sizes, add processes, or drop them. This // simulates the actions of actual processes. // // NOTE: This method is not yet supported or complete. // Things to change or add: // -- Make the input system more friendly // -- Allow for adding and dropping processes // -- Decide what actions should be taken if the processes change // mid-schedule; this may make the current schedule impossible // to run protected static void updateProcesses( Scheduler s, BufferedReader reader ) throws IOException { System.out.print("Enter IDs of processes with new working sets " + "(ex. 2 5 13 21): "); String line = reader.readLine(); String[] ids = line.split("\\s"); int newVal = 0; int check = 0; for (int loop = 0; loop < ids.length; loop++) { System.out.print( "Enter new working set for process " + ids[loop] + ": " ); newVal = new Integer( reader.readLine() ); check = s.editProcWS( new Integer( ids[loop] ), newVal ); System.out.println(); if (check == -1) System.out.println("Error: " + ids[loop] + " is not a valid ID."); else System.out.println("Process updated."); } } // Prints a list of processes and their attributes protected static void printProcesses( ) { System.out.println("Process - Working Set - Share - Run Time"); for ( int loop=0; loop < _processes.length; loop++) { System.out.println(" " + _processes[loop].getID() + " - " + _processes[loop].getWorkingSet() + " - " + _processes[loop].getGoalShare() + " - " + _processes[loop].getRunTime() ); } } // Reads information from the file and initializes the processes // accordingly protected static Process[] initProcesses( File file ) throws IOException { BufferedReader inFile = new BufferedReader( new FileReader( file ) ); String line = inFile.readLine(); if (line == null) throw new EOFException(); Process[] processes = new Process[new Integer(line)]; int pCount = 0; String[] tokens; // Read through the file and initialize each Process line = inFile.readLine(); while (line != null) { tokens = line.split("\\s"); if (tokens.length != 4 || pCount >= processes.length) throw new FileFormatException( "The file's format is incorrect." ); processes[pCount] = new Process( new Integer(tokens[0]), new Integer(tokens[1]), new Integer(tokens[2]), new Integer(tokens[3]) ); pCount++; line = inFile.readLine(); } return processes; } // Chooses a scheduler type and initializes it protected static Scheduler initScheduler( Process[] processes, BufferedReader reader ) throws IOException { Scheduler s = null; boolean valid = true; do { System.out.println("What kind of scheduler would you " + "like to use?"); System.out.println("1. Simple Linear"); System.out.println("2. Start-End"); System.out.println("3. In Order"); System.out.println("4. Two Heap"); int sType = new Integer(reader.readLine()); System.out.print("How much free memory does the scheduler have access to? "); int availMem = new Integer(reader.readLine()); switch( sType ) { case 1: s = new SimpleLinearScheduler( processes, availMem ); valid = true; break; case 2: s = new StartEndScheduler( processes, availMem ); valid = true; break; case 3: s = new InOrderScheduler( processes, availMem ); valid = true; break; case 4: s = new TwoHeapScheduler( processes, availMem ); valid = true; break; default: System.out.println("Invalid scheduler choice."); valid = false; break; } } while( valid == false); return s; } }