import java.awt.*; import java.applet.*; import java.lang.Float; // // gui_aux class // // Is responsible for painting and updating the animation. // class gui_aux extends Panel implements Runnable { final int MaxProcesses = 10, // Max number of processes at the same moment MaxServiceTime = 10; // Max service time for each process double xfactor, yfactor; // Applet dimensions multiplicative factors Simple graph; Thread sim = null; // simulation thread public boolean drawgraph = false; Queue Q = new Queue(MaxProcesses); private boolean just_restarted = false; gui_aux(Simple graph) { this.graph=graph; } float last_time = -1; public void update(Graphics g) { float time; if(drawgraph || just_restarted) { drawQueue(g, Q); just_restarted = false; time = (float)((int) Clock.getTime()); drawClock(g, time); if(time != last_time) // update the graph once each second { last_time = time; drawQueueLength(g, (int) Q.length()); drawMeanCompletionTime(g, (int) CPU.getCompletion()); } } } public void start() { sim = new Thread(this); sim.start(); // starts debugging thread } public void stop() { sim.stop(); } public void run() { /* Used for debugging purposes while(sim!=null) { try {Thread.sleep(5000);} catch (InterruptedException e){} repaint(); } */ } /* paint() is the basic display method; most applets implement this method to draw the applet's representation within a browser page */ public void paint(Graphics g) { /* compute multiplicative factors */ xfactor = 0.95 * size().width / 100.0; // leave right 5% to other panels yfactor = 0.95 * size().height / 100.0; // leave botton 5% to other panels /* draw background */ g.setColor(Color.blue.brighter().brighter().brighter()); g.fill3DRect(0, 0, (int)(100*xfactor -1), (int)(100*yfactor -1),true); /* draw animation box*/ g.setColor(Color.cyan.brighter()); g.fillRect(0,0, (int)(47.5*xfactor), (int)(90*yfactor)); /* draw CPU */ g.setColor(Color.yellow); g.fillRect((int)(2.5*xfactor), (int)(75*yfactor), (int)(40*xfactor), (int)(12.5*yfactor)); g.setColor(Color.black); g.setFont(new Font("TimesRoman", Font.BOLD, 20)); g.drawString("CPU", (int)(18*xfactor), (int)(85*yfactor)); /* draw queue length graph */ g.setColor(Color.black); g.drawString("Queue Length", (int)(58*xfactor), (int)(4*yfactor)); g.setColor(Color.green.brighter()); g.fillRect((int)(55*xfactor), (int)(5*yfactor), (int)(30*xfactor), (int)(10*yfactor)); g.setFont(new Font("TimesRoman", Font.PLAIN, 12)); g.setColor(Color.black); g.drawString("0", (int)(54*xfactor), (int)(17*yfactor)); g.drawString(""+MaxProcesses, (int)(52.5*xfactor), (int)(6*yfactor)); g.drawString("60", (int)(83*xfactor), (int)(17*yfactor)); /* draw mean completion time graph */ g.setFont(new Font("TimesRoman", Font.BOLD, 20)); g.setColor(Color.black); g.drawString("Mean Completion Time", (int)(51*xfactor), (int)(30*yfactor)); g.setColor(Color.green.brighter()); g.fillRect((int)(55*xfactor), (int)(32*yfactor), (int)(30*xfactor), (int)(10*yfactor)); g.setFont(new Font("TimesRoman", Font.PLAIN, 12)); g.setColor(Color.black); g.drawString("0", (int)(54*xfactor), (int)(44*yfactor)); g.drawString(""+MaxMeanCT, (int)(52.5*xfactor), (int)(33*yfactor)); g.drawString("60", (int)(83*xfactor), (int)(44*yfactor)); /* draw clock */ g.setFont(new Font("TimesRoman", Font.BOLD, 20)); g.setColor(Color.black); g.drawString("TIME", (int)(68*xfactor), (int)(88*yfactor)); g.setColor(Color.pink); g.fillRect((int)(58*xfactor), (int)(90*yfactor), (int)(30*xfactor), (int)(10*yfactor)); g.setColor(Color.black); g.setFont(new Font("TimesRoman", Font.BOLD, 40)); g.drawString("0", (int)(68*xfactor), (int)(97*yfactor)); }// end of paint() public void drawClock(Graphics g, float time) { g.setColor(Color.pink); g.fillRect((int)(58*xfactor), (int)(90*yfactor), (int)(30*xfactor), (int)(10*yfactor)); g.setColor(Color.black); g.setFont(new Font("TimesRoman", Font.BOLD, 40)); g.drawString(""+time, (int)(68*xfactor), (int)(97*yfactor)); } public void drawProcessArrived(Graphics g, int pid, float time){ // delete previous messages g.setColor(Color.blue.brighter().brighter().brighter()); g.fillRect((int)(50*xfactor),(int)(45*yfactor), (int)(49.4*xfactor), (int)(30*yfactor)); g.setColor(Color.black); g.setFont(new Font("TimesRoman", Font.BOLD, 20)); g.drawString(" Process " + pid, (int)(56*xfactor), (int)(48*yfactor)); g.drawString("arrived at time " + time, (int)(56*xfactor), (int)(53*yfactor)); } public void drawProcessCompleted(Graphics g, int pid, float time){ // old message was already deleted by drawProcessArrived() // g.setColor(Color.black); g.setFont(new Font("TimesRoman", Font.BOLD, 18)); g.drawString(" Process " + pid, (int)(50*xfactor), (int)(65*yfactor)); g.drawString("completed execution at time " + time,(int)(49*xfactor), (int)(70*yfactor)); } public void drawQueue(Graphics g, Queue Q) { int i; float fraction; // first draw (inside the CPU) the process which is being served // delete previously served process g.setFont(new Font("TimesRoman", Font.BOLD, 12)); g.setColor(Color.yellow); g.fillRect((int)(2.75*xfactor), (int)(77*yfactor), (int)(39.5*xfactor), (int)(5*yfactor)); if(Q.length() == 0) return; // no processes on the system // compute the relative size of the process being served fraction = (float)Q.getTime(0)/MaxServiceTime; if(fraction >1.0) fraction = (float)1.0; else if(fraction <.01) fraction = (float).01; // draw process being served g.setColor(Color.black); g.drawString(Q.getName(0), (int)(2.75*xfactor), (int)(80*yfactor)); g.setColor(Color.red); g.fillRect((int)(7*xfactor), (int)(77*yfactor), (int)(35*fraction*xfactor), (int)(5*yfactor)); // delete previous processes g.setColor(Color.cyan.brighter()); g.fillRect((int)(2.75*xfactor), (int)((2.75*yfactor)), (int)(41*xfactor), (int)(72.5*yfactor)); // now, draw the processes really waiting on the queue for(i = 1; i < Q.length() && i < MaxProcesses; i++) { // compute the relative size of process i fraction = (float)Q.getTime(i)/MaxServiceTime; if(fraction >1.0) fraction = (float)1.0; else if(fraction <.01) fraction = (float).01; g.setColor(Color.red); g.fillRect((int)(7*xfactor), (int)((75-7.5*i)*yfactor), (int)(35*fraction*xfactor), (int)(5*yfactor)); g.setColor(Color.black); g.drawString(Q.getName(i), (int)(2.75*xfactor), (int)((78-7.5*i)*yfactor)); } if(i < MaxProcesses) { // delete old process g.setColor(Color.cyan.brighter()); g.fillRect((int)(2.75*xfactor), (int)0, (int)(41*xfactor), (int)((80-7.5*i)*yfactor)); } }// end of drawQueue final int MaxQL = 60; int QL[] = new int[MaxQL+1]; int QLsize = 0; public final void drawQueueLength(Graphics g, int CurrentLength) { int i; if(QLsize < MaxQL - 1) QLsize++; else for(i=0; i < QLsize - 1; i++) QL[i] = QL[i+1]; QL[QLsize-1] = (CurrentLength > MaxProcesses)? MaxProcesses:CurrentLength; // delete previous graph g.setColor(Color.green.brighter()); g.fillRect((int)(55*xfactor), (int)(5*yfactor), (int)(30*xfactor), (int)(10*yfactor)); g.setColor(Color.black); for(i=1; i < QLsize; i++) g.drawLine((int)((55.0 + 30.0*(i-1)/(MaxQL))*xfactor), (int)((14.8 - 9.8*QL[i-1]/MaxProcesses)*yfactor), (int)((55.0 + 30.0*(i)/(MaxQL))*xfactor), (int)((14.8 - 9.8*QL[i]/MaxProcesses)*yfactor)); }// end of drawQueueLength() final int MaxQM = 60, MaxMeanCT = 80; int QM[] = new int[MaxQM+1]; int QMsize = 0; public final void drawMeanCompletionTime(Graphics g, int CurrentMean) { int i; if(QMsize < MaxQM - 1) QMsize++; else for(i=0; i < QMsize - 1; i++) QM[i] = QM[i+1]; QM[QMsize-1] = (CurrentMean > MaxMeanCT)? MaxMeanCT:CurrentMean; // delete previous graph g.setColor(Color.green.brighter()); g.fillRect((int)(55*xfactor), (int)(32*yfactor), (int)(30*xfactor), (int)(10*yfactor)); g.setColor(Color.black); for(i=1; i < QMsize; i++) g.drawLine((int)((55.0 + 30.0*(i-1)/(MaxQM))*xfactor), (int)((41.6 - 9.8*QM[i-1]/MaxMeanCT)*yfactor), (int)((55.0 + 30.0*(i)/(MaxQM))*xfactor), (int)((41.6 - 9.8*QM[i]/MaxMeanCT)*yfactor)); }// end of drawMeanCompletionTime() public void restart() { QM = new int[MaxQM+1]; QMsize = 0; QL = new int[MaxQL+1]; QLsize = 0; just_restarted = true; Q = new Queue(MaxProcesses); } }// end of class gui_aux // // Simple class // // Creates the applet and get the input data from the user // public class Simple extends java.applet.Applet { gui_aux panel; private boolean accept_play = true; // The following are GUI components which generate exceptions when the // user inputs some data or make a selection TextField Quantum, Cont_swi, Serv_time, Interarr_time; Choice ArrivalProcess, Serv_timeProcess; public void init() { setLayout(new BorderLayout()); panel = new gui_aux(this); add("Center",panel); Panel p = new Panel(); add("South",p); Panel q = new Panel(); q.setLayout(new BorderLayout(0,15)); add("East",q); ///////////////////// Add Buttons Button Play, Stop, Restart; p.setFont(new Font("Helvetica", Font.PLAIN, 14)); Play = new Button("Play"); p.add(Play); Stop = new Button("Pause / Resume"); p.add(Stop); Restart = new Button("Restart"); p.add(Restart); ///////////////////// Create SetQuantum Panel Panel SetQuantumPanel = new Panel(); SetQuantumPanel.setLayout(new BorderLayout()); Label SetQuantumLabel = new Label("Quantum (s)", Label.CENTER); SetQuantumLabel.setFont(new Font("Helvetica", Font.BOLD, 14)); SetQuantumPanel.add("North",SetQuantumLabel); Quantum = new TextField("3",4); SetQuantumPanel.add("Center",Quantum); p.add(SetQuantumPanel); ///////////////////// Create SetCont_swi Panel Panel SetCont_swiPanel = new Panel(); SetCont_swiPanel.setLayout(new BorderLayout()); Label SetCont_swiLabel = new Label("Context Switch Time (s)", Label.CENTER); SetCont_swiLabel.setFont(new Font("Helvetica", Font.BOLD, 14)); SetCont_swiPanel.add("North",SetCont_swiLabel); Cont_swi = new TextField("0.1",4); SetCont_swiPanel.add("Center",Cont_swi); p.add(SetCont_swiPanel); ///////////////////// Create Arrival Panel Panel ArrivalPanel = new Panel(); ArrivalPanel.setLayout(new BorderLayout()); Label ArrivalLabel = new Label("Interarrival Times (s)", Label.CENTER); ArrivalLabel.setFont(new Font("Helvetica", Font.BOLD, 14)); ArrivalPanel.add("North",ArrivalLabel); Interarr_time = new TextField("5.0",4); ArrivalPanel.add("Center",Interarr_time); ArrivalProcess = new Choice(); ArrivalProcess.addItem("Fixed"); ArrivalProcess.addItem("Poisson"); ArrivalPanel.add("South", ArrivalProcess); q.add("North", ArrivalPanel); ///////////////////// Create Service Time Panel Panel Serv_timePanel = new Panel(); Serv_timePanel.setLayout(new BorderLayout()); Label Serv_timeLabel = new Label("Service Times (s)", Label.CENTER); Serv_timeLabel.setFont(new Font("Helvetica", Font.BOLD, 14)); Serv_timePanel.add("North",Serv_timeLabel); Serv_time = new TextField("7",4); Serv_timePanel.add("Center",Serv_time); Serv_timeProcess = new Choice(); Serv_timeProcess.addItem("Fixed"); Serv_timeProcess.addItem("Poisson"); Serv_timePanel.add("South", Serv_timeProcess); q.add("South", Serv_timePanel); }// end of init() public void start() { panel.start(); } // Stops the simulation // This method is called when the user leaves the html page containing our applet. public void stop() { C.turnoff(); PowerPC.turnoff(); BigBen.turnoff(); panel.drawgraph = !panel.drawgraph; panel.repaint(); panel.stop(); } /******************** Event Handling ***********/ CPU PowerPC; Clock BigBen; Creator C; private void create_threads() { BigBen = new Clock(); BigBen.setGUI(panel); BigBen.setTime((float)0.0); new Thread(BigBen).start(); // starts clock thread C = new Creator(panel.Q); C.setGUI(panel); new Thread(C).start(); // starts process creator thread PowerPC = new CPU(panel.Q); PowerPC.setGUI(panel); new Thread(PowerPC).start(); // starts CPU thread panel.drawgraph = true; } // Handles the button event using the label. // Extracted from http://www.digitalfocus.com/digitalfocus/faq/GR.html public boolean action(Event evt, Object arg) { if("Play".equals(arg)) { if(accept_play) { accept_play = false; create_threads(); } return true; } if("Pause / Resume".equals(arg)) { C.pause(); PowerPC.pause(); BigBen.pause(); panel.drawgraph = !panel.drawgraph; panel.repaint(); return true; } if("Restart".equals(arg)) { C.stop(); C.turnoff(); PowerPC.stop(); PowerPC.turnoff(); BigBen.stop(); BigBen.turnoff(); panel.drawgraph = false; panel.restart(); create_threads(); panel.repaint(); return true; } if(evt.target instanceof TextField) { if(evt.target == Quantum) { CPU.setQuantum(Float.valueOf(arg.toString()).floatValue()); //Throws: NumberFormatException //If the String does not contain a parsable Float. } else if(evt.target == Cont_swi) { CPU.setOverhead(Float.valueOf(arg.toString()).floatValue()); } else if(evt.target == Interarr_time) { Creator.setArrivalTime(Float.valueOf(arg.toString()).floatValue()); } else if(evt.target == Serv_time) { Creator.setServiceTime(Float.valueOf(arg.toString()).floatValue()); } return true; } if(evt.target instanceof Choice) { if(evt.target == Serv_timeProcess) { if("Poisson".equals(arg)) Creator.setProcType(true); else Creator.setProcType(false); } else if(evt.target == ArrivalProcess) { if("Poisson".equals(arg)) Creator.setArrType(true); else Creator.setArrType(false); } return true; } return false; }// end of action() }//end of class Simple