/** * The PreCompScheduler class encompasses all Schedulers that pre-compute * their schedules. Examples include the SimpleLinearScheduler and the * StartEndScheduler. Its sibling, the other extension of Scheduler, is the * HeuristicScheduler. */ import java.io.*; abstract class PreCompScheduler extends Scheduler { // Public ------------------------ // Constructor public PreCompScheduler( Process[] processes, int availMem ) { super( processes, availMem ); _schedClock = 0; } // Run the Scheduler until all processes have completed public void run( ) throws IOException { makeSchedule( false ); runSchedule(); } // Run the Scheduler for the given amount of time public void run ( int time ) { makeSchedule( false ); _stepClock = 0; runSchedule( time ); } // Run the Scheduler silently and write the results to files // Procfile should be of the form name.proc public void makeFiles( String procfile ) throws IOException { if ( !procfile.endsWith(".proc") ) { System.out.println("File must be a process file ending with " + ".proc"); System.exit(1); } String name = procfile.substring ( procfile.lastIndexOf("/") + 1, procfile.lastIndexOf(".") ); makeSchedule( false ); runSchedule( name ); } // Private ------------------------ // Compute a schedule for the current set of processes. protected abstract void makeSchedule( boolean verbose ); // A 3xN matrix representing the computed schedule. // The first row lists processes receiving a quantum of CPU time, // the second row processes rolling in for a quantum, // and the third row processes rolling out for a quantum. protected int[][] _schedule; // What slot of the schedule we're currently running protected int _schedClock; // Use the schedule we've computed to simulate the processes running and // rolling in and out, until all processes are finished protected void runSchedule( ) throws IOException { while( !finished( ) ) { for( int loop = 0; loop < _schedule[0].length; loop++) { if( _schedule[0][loop] != -1 ) { _processes[ _schedule[0][loop] ].giveQuanta(); _cpuCount++; } if( _schedule[1][loop] != -1 ) { _processes[ _schedule[1][loop] ].rollIn(); } if( _schedule[2][loop] != -1 ) { _processes[ _schedule[2][loop] ].rollOut(); } _clock++; } } } // Use the schedule we've computed to simulate the processes running and // rolling in and out, until all processes are finished // Also output the results to files protected void runSchedule( String name ) throws IOException { String cpuName, shareName, integralName; StringBuffer buffer = new StringBuffer(); buffer.append( "../data/" ).append( name ) .append( "-" ).append( getType() ).append( "cpu.dat" ); cpuName = buffer.toString(); buffer = buffer.delete( cpuName.lastIndexOf("c"), buffer.length() ); buffer.append( "share.dat" ); shareName = buffer.toString(); buffer = buffer.delete( shareName.lastIndexOf("s"), buffer.length() ); buffer.append( "integral.dat" ); integralName = buffer.toString(); PrintStream cpuOut = new PrintStream ( new BufferedOutputStream ( new FileOutputStream ( cpuName ))); PrintStream shareOut = new PrintStream ( new BufferedOutputStream ( new FileOutputStream ( shareName ))); PrintStream integralOut = new PrintStream ( new BufferedOutputStream ( new FileOutputStream ( integralName ))); // Print the chosen permutation to the share .dat file, so it can // be added to the plot shareOut.println( getPerm() ); // Print the schedule length to the share .dat file, so it too can be // added to the plot shareOut.println( getSchedLength() ); while( !finished( ) ) { for( int loop = 0; loop < _schedule[0].length; loop++) { if( _schedule[0][loop] != -1 ) { _processes[ _schedule[0][loop] ].giveQuanta(); _cpuCount++; // Update processes' exponentially averaged shares for( int ploop = 0; ploop < _pCount; ploop++ ){ if( ploop == _schedule[0][loop] ){ _processes[ploop].updateShare( true ); } else { _processes[ploop].updateShare( false ); } } } else { _idleTime++; } if( _schedule[1][loop] != -1 ) { _processes[ _schedule[1][loop] ].rollIn(); } if( _schedule[2][loop] != -1 ) { _processes[ _schedule[2][loop] ].rollOut(); } cpusToFile( cpuOut ); sharesToFile( shareOut, integralOut ); _clock++; } } // Print the total running and idle times to the share .dat file, // so they can be added to the plot shareOut.println( _clock ); shareOut.println( _idleTime ); cpuOut.close(); shareOut.close(); integralOut.close(); } // Each process prints its current CPU total to file protected void cpusToFile( PrintStream out ) throws IOException { for( int loop = 0; loop < _processes.length; loop++ ) { out.print( _processes[loop].getQuanta() + " "); } out.println(); } // Each process prints its current received share to file protected void sharesToFile( PrintStream shareOut, PrintStream integralOut ) throws IOException { double actualShare; for( int loop = 0; loop < _processes.length; loop++ ) { /* if( _cpuCount != 0 ) { actualShare = (double)_processes[loop].getQuanta() / _cpuCount; } else { actualShare = 0; } */ actualShare = _processes[loop].averagedShare(); shareOut.print( actualShare + " "); integralOut.print( actualShare - _processes[loop].getShareFrom1() + " "); } shareOut.println(); integralOut.println(); } // Use the schedule we've computed to simulate the processes running and // rolling in and out, for the given amount of time protected void runSchedule( int time ) { while ( _stepClock < time ) { for( int loop = 0; loop < _schedule[0].length; loop++) { if( _schedule[0][loop] != -1 ) { _processes[ _schedule[0][loop] ].giveQuanta(); _cpuCount++; } if( _schedule[1][loop] != -1 ) { _processes[ _schedule[1][loop] ].rollIn(); } if( _schedule[2][loop] != -1 ) { _processes[ _schedule[2][loop] ].rollOut(); } _clock++; _stepClock++; } } } protected void printSchedule( ) { for( int loop = 0; loop < _schedule[0].length; loop++) { System.out.println( schedProc( _schedule[1][loop] ) + " " + schedProc( _schedule[0][loop] ) + " " + schedProc( _schedule[2][loop] ) ); } } public abstract String getPerm( ); public abstract int getSchedLength(); protected String schedProc( int i ) { if ( i == -1 ) return "-"; else return new Integer(i).toString(); } }