You can subscribe to this list here.
2007 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
(24) |
Sep
(14) |
Oct
(13) |
Nov
(5) |
Dec
(1) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2008 |
Jan
(2) |
Feb
(53) |
Mar
(29) |
Apr
(5) |
May
(11) |
Jun
(3) |
Jul
(7) |
Aug
(48) |
Sep
(10) |
Oct
(8) |
Nov
(1) |
Dec
|
2009 |
Jan
|
Feb
|
Mar
|
Apr
(1) |
May
(9) |
Jun
|
Jul
|
Aug
|
Sep
(5) |
Oct
(2) |
Nov
|
Dec
|
2012 |
Jan
|
Feb
|
Mar
(1) |
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2013 |
Jan
|
Feb
|
Mar
|
Apr
(1) |
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: <mar...@us...> - 2008-02-15 04:12:54
|
Revision: 103 http://gridsim.svn.sourceforge.net/gridsim/?rev=103&view=rev Author: marcos_dias Date: 2008-02-14 20:13:00 -0800 (Thu, 14 Feb 2008) Log Message: ----------- Stable version of the multiple queue aggressive backfilling policy. Modified Paths: -------------- branches/gridsim4.0-branch3/examples/examples/workload/parallel/TurboExampleMultiEBQueues01.java branches/gridsim4.0-branch3/examples/examples/workload/parallel/TurboExampleMultiEBQueues02.java branches/gridsim4.0-branch3/source/gridsim/gui/DefaultGridSimVisualizer.java branches/gridsim4.0-branch3/source/gridsim/turbo/CBParallelSpaceShared.java branches/gridsim4.0-branch3/source/gridsim/turbo/MultipleEasyBackfillingQueues.java branches/gridsim4.0-branch3/source/gridsim/turbo/SSGridlet.java branches/gridsim4.0-branch3/source/gridsim/turbo/TResourceCharacteristics.java Added Paths: ----------- branches/gridsim4.0-branch3/source/gridsim/turbo/QueuePartitionPredicate.java Removed Paths: ------------- branches/gridsim4.0-branch3/source/gridsim/turbo/QueuePredicate.java Modified: branches/gridsim4.0-branch3/examples/examples/workload/parallel/TurboExampleMultiEBQueues01.java =================================================================== --- branches/gridsim4.0-branch3/examples/examples/workload/parallel/TurboExampleMultiEBQueues01.java 2008-02-14 12:00:22 UTC (rev 102) +++ branches/gridsim4.0-branch3/examples/examples/workload/parallel/TurboExampleMultiEBQueues01.java 2008-02-15 04:13:00 UTC (rev 103) @@ -145,16 +145,9 @@ // this resource will use an aggressive backfilling policy (EASY) TResourceCharacteristics resConfig = new TResourceCharacteristics( - arch, os, mList, TResourceCharacteristics.EB_PARALLEL_SPACE_SHARED, + arch, os, mList, TResourceCharacteristics.MULTIPLE_EASY_BACKFILLING_QUEUES, time_zone, cost); - MultipleEasyBackfillingQueues policy = null; - try { - policy = new MultipleEasyBackfillingQueues(name, "Policy", 1); - } catch (Exception e1) { - e1.printStackTrace(); - } - ////////////////////////////////////////// // 6. Finally, we need to create a GridResource object. double baud_rate = 10000.0; // communication speed @@ -172,13 +165,10 @@ LinkedList holidays = new LinkedList(); GridResource gridRes = null; - ResourceCalendar resCalendar = new ResourceCalendar(time_zone, - peakLoad, offPeakLoad, holidayLoad, weekends, - holidays, seed); - try { - gridRes = new GridResource(name, baud_rate, resConfig, - resCalendar, policy); + gridRes = new GridResource(name, baud_rate, seed, + resConfig, peakLoad, offPeakLoad, holidayLoad, weekends, + holidays); } catch (Exception e) { e.printStackTrace(); Modified: branches/gridsim4.0-branch3/examples/examples/workload/parallel/TurboExampleMultiEBQueues02.java =================================================================== --- branches/gridsim4.0-branch3/examples/examples/workload/parallel/TurboExampleMultiEBQueues02.java 2008-02-14 12:00:22 UTC (rev 102) +++ branches/gridsim4.0-branch3/examples/examples/workload/parallel/TurboExampleMultiEBQueues02.java 2008-02-15 04:13:00 UTC (rev 103) @@ -7,7 +7,7 @@ import gridsim.MachineList; import gridsim.ResourceCalendar; import gridsim.turbo.MultipleEasyBackfillingQueues; -import gridsim.turbo.QueuePredicate; +import gridsim.turbo.QueuePartitionPredicate; import gridsim.turbo.SSGridlet; import gridsim.turbo.TResourceCharacteristics; import gridsim.util.Workload; @@ -145,7 +145,7 @@ // this resource will use an aggressive backfilling policy (EASY) TResourceCharacteristics resConfig = new TResourceCharacteristics( - arch, os, mList, TResourceCharacteristics.EB_PARALLEL_SPACE_SHARED, + arch, os, mList, TResourceCharacteristics.MULTIPLE_EASY_BACKFILLING_QUEUES, time_zone, cost); MultipleEasyBackfillingQueues policy = null; @@ -160,8 +160,8 @@ QueuePredicateExample pred1 = new QueuePredicateExample(0, 10000, peRating); QueuePredicateExample pred2 = new QueuePredicateExample(10000, Integer.MAX_VALUE, peRating); - policy.createQueue(0, resConfig.getNumPE() / 2, pred1); - policy.createQueue(1, resConfig.getNumPE() / 2, pred2); + policy.createPartition(0, resConfig.getNumPE() / 2, pred1); + policy.createPartition(1, resConfig.getNumPE() / 2, pred2); ////////////////////////////////////////// // 6. Finally, we need to create a GridResource object. @@ -197,7 +197,7 @@ } } // end class -class QueuePredicateExample implements QueuePredicate { +class QueuePredicateExample implements QueuePartitionPredicate { int minRuntime_; int maxRuntime_; int resRating_; Modified: branches/gridsim4.0-branch3/source/gridsim/gui/DefaultGridSimVisualizer.java =================================================================== --- branches/gridsim4.0-branch3/source/gridsim/gui/DefaultGridSimVisualizer.java 2008-02-14 12:00:22 UTC (rev 102) +++ branches/gridsim4.0-branch3/source/gridsim/gui/DefaultGridSimVisualizer.java 2008-02-15 04:13:00 UTC (rev 103) @@ -14,9 +14,12 @@ import gridsim.ResourceCharacteristics; import java.awt.BorderLayout; +import java.awt.FlowLayout; import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; @@ -76,6 +79,7 @@ private JButton btChangePause_; private JTextField tfRunUntil_; + private JLabel status_; private JList jlResource_; private JTextArea jlResourceInfo_; @@ -197,11 +201,38 @@ mainPanel.add(simulationPanel); mainPanel.add(resourceInfoPanel); + JPanel statusPanel = new JPanel(); + statusPanel.setLayout(new FlowLayout(FlowLayout.LEFT)); + status_ = new JLabel("Current simulation time is " + GridSim.clock() + " seconds."); + statusPanel.add(status_); + + /* to show simulation time when mouse cursor passing over buttons */ + MouseListener mouseListener = new MouseListener() { + + public void mouseEntered(MouseEvent e) { + status_.setText("Current simulation time is " + GridSim.clock() + " seconds."); + } + + public void mouseExited(MouseEvent e) { + status_.setText(" "); + } + + public void mouseClicked(MouseEvent e) { } + public void mousePressed(MouseEvent e) { } + public void mouseReleased(MouseEvent e) { } + }; + + btChangePause_.addMouseListener(mouseListener); + btRun_.addMouseListener(mouseListener); + btSlowMotion_.addMouseListener(mouseListener); + btStep_.addMouseListener(mouseListener); + createMenuBar(); firstClick_ = true; super.setLocation(0, 0); super.getContentPane().add(mainPanel, BorderLayout.CENTER); + super.getContentPane().add(statusPanel, BorderLayout.SOUTH); super.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // Creates a thread that will be responsible for starting the simulation @@ -248,7 +279,7 @@ /** * Handles the events generated by this frame */ - public void actionPerformed(ActionEvent e){ + public void actionPerformed(ActionEvent e) { String cmd = e.getActionCommand(); if(e.getSource() == btChangePause_) { @@ -313,7 +344,7 @@ * Informs all the listeners about the change in the * simulation time */ - private static void informListenersAboutTime() { + private void informListenersAboutTime() { settings_.setTimeSpan(GridSim.clock()); Iterator<AllocationListener> iterListener = listeners_.values().iterator(); while(iterListener.hasNext()) { @@ -322,6 +353,7 @@ new AllocationAction(AllocationAction.SIMULATION_TIME_CHANGED); listener.allocationActionPerformed(action); } + status_.setText("Current simulation time is " + GridSim.clock() + " seconds."); } /** Modified: branches/gridsim4.0-branch3/source/gridsim/turbo/CBParallelSpaceShared.java =================================================================== --- branches/gridsim4.0-branch3/source/gridsim/turbo/CBParallelSpaceShared.java 2008-02-14 12:00:22 UTC (rev 102) +++ branches/gridsim4.0-branch3/source/gridsim/turbo/CBParallelSpaceShared.java 2008-02-15 04:13:00 UTC (rev 103) @@ -279,7 +279,7 @@ * @pre userId > 0 * @post $none */ - public int gridletStatus(int gridletId,int userId){ + public int gridletStatus(int gridletId,int userId) { SSGridlet sgl = null; // Look for the Gridlet in the running queue Modified: branches/gridsim4.0-branch3/source/gridsim/turbo/MultipleEasyBackfillingQueues.java =================================================================== --- branches/gridsim4.0-branch3/source/gridsim/turbo/MultipleEasyBackfillingQueues.java 2008-02-14 12:00:22 UTC (rev 102) +++ branches/gridsim4.0-branch3/source/gridsim/turbo/MultipleEasyBackfillingQueues.java 2008-02-15 04:13:00 UTC (rev 103) @@ -23,15 +23,50 @@ import java.util.LinkedList; /** - * Under development... - * + * This class implements a non-FCFS policy to schedule parallel jobs. The + * policy is based on aggressive (EASY) backfilling. This policy can use + * multiple partitions or queues and the jobs can be directed to these partitions + * using a partition predicate ({@link QueuePartitionPredicate}. A partition + * can borrow resources from another when it requires and the resources are + * not being used by the other partition. The implementation of this policy is + * based on the following paper: + * <p> + * <ul> + * <li> Barry G. Lawson and Evgenia Smirni, Multiple-Queue Backfilling + * Scheduling with Priorities and Reservations for Parallel Systems, + * 2002 Workshop on Job Scheduling Strategies for Parallel + * Processing (JSSPP), pp. 72-87, 2002. + * </ul> + * <br> + * We use an availability profile to store the availability of processing + * elements. In order to represent the pivots (i.e. the first jobs in the + * partitions), we schedule them creating the entries in the availability + * profile. This way, we do not need to store the pivots' start times + * (or shadow times) and extra nodes in different variables. It also makes + * the search for available resources for a new pivot easier. + * <p> + * <b>LIMITATIONS:</b><br> + * <ul> + * <li> The list of machines comprising this resource must be + * homogeneous. + * <li> Local load is not considered. If you would like to simulate this, + * you have to model the local load as gridlets. It is more precise + * and faster. To do so, please check {@link Lublin99Workload}. + * <li> Gridlets cannot be paused nor migrated. This could be + * easily done, but due to time constraints, I could not + * implement these features. + * <li> This policy still neither supports priorities nor advance + * reservation. + * </ul> + * * @author Marcos Dias de Assuncao * @since GridSim Turbo Alpha 0.1 * * @see gridsim.GridSim * @see gridsim.ResourceCharacteristics * @see gridsim.turbo.TAllocPolicy - * @see gridsim.turbo.CBParallelSpaceShared + * @see gridsim.turbo.EBParallelSpaceShared + * @see gridsim.turbo.QueuePartitionPredicate * @see gridsim.turbo.PERange * @see gridsim.turbo.PERangeList */ @@ -39,10 +74,10 @@ public class MultipleEasyBackfillingQueues extends TAllocPolicy { // Queue of running Gridlets - protected LinkedList<MQGridlet> runningGridlets_; + protected LinkedList<SSGridlet> runningGridlets_; // Queue of Gridlets waiting in this queue - protected LinkedList<MQGridlet> queuedGridlets_; + protected LinkedList<SSGridlet> queuedGridlets_; // The rating of one PE protected int ratingPE_; @@ -51,10 +86,10 @@ protected TResourceCharacteristics resource_; // The availability profile - protected Profile profile_; + protected MultiPartitionProfile profile_; - // the number of queues in this scheduler - private int numQueues_; + // the number of partitions or queues in this scheduler + private int numPartitions_; // the last time when the schedule updated was called private double lastScheduleUpdate_; @@ -66,12 +101,14 @@ private static final int UNKNOWN = -1; /** - * Allocates a new <tt>EBParallelSpaceShared</tt> object + * Allocates a new <tt>MultiEasyBackfillingQueues</tt> object. + * If the policy is create with only one partition, it will then work as + * a normal aggressive (EASY) backfilling scheduler. * * @param resourceName the <tt>GridResource</tt> entity name that will * contain this allocation policy * @param entityName this object entity name - * @param numQueues The number of queues in the scheduler + * @param numPartitions The number of partitions of the scheduling queue * @throws Exception This happens when one of the following scenarios occur: * <ul> * <li> Creating this entity before initialising GridSim package @@ -87,28 +124,55 @@ * String[], String[], String) */ public MultipleEasyBackfillingQueues(String resourceName, - String entityName, int numQueues) throws Exception { + String entityName, int numPartitions) throws Exception { super(resourceName, entityName); // makes sure that the scheduler has at least one queue - if(numQueues <= 0) { - throw new ParameterException("Number of queues" + + if(numPartitions <= 0) { + throw new ParameterException("Number of partitions " + "should be larger than 1"); } // initialises local data structure - runningGridlets_ = new LinkedList<MQGridlet>(); - queuedGridlets_ = new LinkedList<MQGridlet>(); - numQueues_ = numQueues; - profile_ = new Profile(); + runningGridlets_ = new LinkedList<SSGridlet>(); + queuedGridlets_ = new LinkedList<SSGridlet>(); + numPartitions_ = numPartitions; + profile_ = new MultiPartitionProfile(); lastScheduleUpdate_ = 0.0D; ratingPE_ = 0; } - - public boolean createQueue(int queueId, int numPE, QueuePredicate predicate) { - EasyBackFillingQueue queue = new EasyBackFillingQueue(queueId, numPE, predicate); - profile_.addQueue(queue); + /** + * Creates a new partition in this scheduler. + * @param queueId the id of the partition + * @param numPE the number of PEs in this partition + * @param predicate the predicate to be used to select + * gridlets for this partition. + * @return <tt>true</tt> if the partition has been set + * correctly or <tt>false</tt> otherwise. + */ + public boolean createPartition(int queueId, int numPE, + QueuePartitionPredicate predicate) { + if(numPE < 0) { + System.out.println(super.get_name() + ".createPartition(): " + + "Error, the number of PEs should be > 0"); + return false; + } + else if(predicate == null) { + System.out.println(super.get_name() + ".createPartition(): " + + "Error, you have provided an invalid predicate"); + return false; + } + else if(profile_.queues_.size() == numPartitions_ + && !profile_.queues_.containsKey(queueId) ) { + System.out.println(super.get_name() + ".createPartition(): " + + "Error, you have already specified all the " + + numPartitions_ + " partitions."); + return false; + } + + QueuePartition partition = new QueuePartition(queueId, numPE, predicate); + profile_.queues_.put(queueId, partition); return true; } @@ -124,47 +188,45 @@ // of one PE assuming that the machines are homogeneous ratingPE_ = resource_.getMIPSRatingOfOnePE(); - if(numQueues_ > 1 && profile_.getNumberOfQueues() != numQueues_) { + int partInProfile = profile_.queues_.size(); + if(numPartitions_ > 1 && partInProfile != numPartitions_) { System.out.println(super.get_name() + ".body(): The scheduler" + - " is expected to have " + numQueues_ + " queues. However," + - " only " + profile_.getNumberOfQueues() + " have been defined"); + " is expected to have " + numPartitions_ + " queues. However," + + " only " + partInProfile + " have been defined"); return; } + else if (profile_.getNumberOfAssignedPEs() > resource_.getNumPE()) { + System.out.println(super.get_name() + ".body(): " + + "Error, you have assigned more PEs to the queues than available "+ + "at the resource"); + return; + } - //TODO: To validate the processing elements assigned to the queues - - // if the user has not specified the queues and the scheduler is - // expected to have only one queue, then creates the queue and - // includes it in the list. - if(profile_.getNumberOfQueues() == 0 && numQueues_ == 1) { - // creates the accept all predicate - QueuePredicate predicate = new QueuePredicate() { + // if the user has not specified the partitions and the scheduler is + // expected to have only one partition. So, it creates the partition and + // assigns an accept-all predicate to it. + if(partInProfile == 0 && numPartitions_ == 1) { + QueuePartitionPredicate predicate = new QueuePartitionPredicate() { public boolean match(SSGridlet gridlet) { return true; } }; - EasyBackFillingQueue queue = - new EasyBackFillingQueue(0, resource_.getNumPE(), predicate); - queue.idlePERanges_ = resource_.getFreePERanges().clone(); - profile_.addQueue(queue); + QueuePartition partition = + new QueuePartition(0, resource_.getNumPE(), predicate); + + partition.idlePERanges_ = resource_.getFreePERanges().clone(); + profile_.queues_.put(partition.partitionId_, partition); } - // assigns the PEs to the queues + // divides the PEs and assigns them to the partitions else { int allocPE = 0; PERangeList freeRanges = resource_.getFreePERanges().clone(); - for(EasyBackFillingQueue queue : profile_.queues_.values()) { - allocPE += queue.initialNumPEs_; - - if(allocPE > resource_.getNumPE()) { - System.out.println(super.get_name() + ".body(): The scheduler" + - " cannot allocate PEs to all queues because there are not" + - " anough PEs"); - return; - } - - PERangeList selected = super.selectPERangeList(queue.initialNumPEs_, freeRanges); - queue.idlePERanges_ = selected; + for(QueuePartition partition : profile_.queues_.values()) { + allocPE += partition.initialNumPEs_; + PERangeList selected = + super.selectPERangeList(partition.initialNumPEs_, freeRanges); + partition.idlePERanges_ = selected; freeRanges = PERangeList.difference(freeRanges, selected); } } @@ -192,10 +254,17 @@ } // reset variables to default values - runningGridlets_.clear(); + runningGridlets_.clear(); + queuedGridlets_.clear(); + profile_.clear(); lastScheduleUpdate_ = 0.0D; ratingPE_ = 0; resource_.resetFreePERanges(); + + for(QueuePartition partition : profile_.queues_.values()) { + partition.idlePERanges_ = null; + partition.pivot_ = null; + } } /** @@ -230,7 +299,7 @@ } // Create a resource Gridlet - MQGridlet sgl = new MQGridlet(gridlet); + SSGridlet sgl = new SSGridlet(gridlet); //-------------- FOR DEBUGGING PURPOSES ONLY -------------- @@ -258,7 +327,7 @@ return; } - sgl.setQueueID(queueId); + sgl.setPartitionID(queueId); // If there are no jobs in the queue list, then check if // there are enough PEs to process the job immediately @@ -270,9 +339,6 @@ queuedGridlets_.add(sgl); } -// System.out.println("\nFree Ranges=" + profile_.getIdlePEsPerQueue()); -// System.out.println(profile_); - //------------------ FOR DEBUGGING PURPOSES ONLY ---------------- // Notifies the listeners that a Gridlet has been either scheduled @@ -362,32 +428,33 @@ // -------------------- PRIVATE METHODS ---------------------------- /** - * + * Tries to start a gridlet if there are enough processing elements + * available at the current simulation time. + * @param sgl the gridlet to be started */ - private boolean startGridlet(MQGridlet sgl) { + private boolean startGridlet(SSGridlet sgl) { int reqPE = sgl.getNumPE(); if(reqPE > resource_.getNumFreePE()) return false; - boolean success = false; // to test various conditions - int queueId = sgl.getQueueID(); + boolean success = false; // to test a few conditions + int queueId = sgl.getPartitionID(); - // calculate the execution time of the Gridlet double executionTime = super.forecastExecutionTime(ratingPE_, sgl.getRemainingLength()); + + double currentTime = GridSim.clock() ; // calculates how much ahead to look into the availability profile - double currentTime = GridSim.clock() ; - // the Gridlet's expected finish time if it starts now double finishTime = currentTime + executionTime; + // checks the availability of PEs in the selected partition PERangeList ranges = profile_.getImmediateAvailability(queueId, executionTime); - - // if the above method returns null, it means that there are not enough - // PEs to serve the reservation or Gridlet + + // if there are enough PEs in the queue, then allocate them if(ranges.getNumPE() >= reqPE) { ranges = super.selectPERangeList(reqPE, ranges); profile_.allocateImmediateRanges(queueId, finishTime, ranges); @@ -395,34 +462,27 @@ } // If the queue to which the gridlet is assigned does not have the - // required PEs, then try to borrow the additional PEs from other queues. + // required PEs, then tries to borrow the additional PEs from other queues if(!success) { + // gets all available PEs during given time interval PERangeList overallAvailPEs = profile_.getImmediateAvailability(executionTime); // additional PEs required int addRequired = reqPE - ranges.getNumPE(); + // removes PEs already obtained from selected partition PERangeList addRanges = PERangeList.difference(overallAvailPEs, ranges); if(addRanges != null && addRanges.getNumPE() >= addRequired) { - // subtracts the ranges already obtained from the gridlet's queue - -// System.out.println("\nRanges to Add to queue " + queueId +" = " + -// addRanges + "\noverall = " + overallAvailPEs + -// "\n overall num available = " + overallAvailPEs.getNumPE() + -// "\n free PEs = " + resource_.getNumFreePE() + -// "\n free PEs profile = " + profile_.getNumFreePEs() + -// "\n PEs from the queue = " + ranges.getNumPE() + -// "\n req PEs = " + reqPE); - - // borrows the ranges from the queues and adds it into the - // specified queue + + // borrows the additional PEs required from the partitions + // and adds them into the specified queue addRanges = super.selectPERangeList(addRequired, addRanges); profile_.transferPEs(queueId, addRanges, currentTime, finishTime); - // allocate the ranges to the job + // allocates the ranges to the gridlet ranges.addAll(addRanges); profile_.allocateImmediateRanges(queueId, finishTime, ranges); success = true; @@ -430,7 +490,7 @@ } if(!success) - return false; + return false; // it was not possible to schedule the gridlet // sets the PEs to busy at resource class. This is just to provide // information to other classes that may query it @@ -462,13 +522,17 @@ } /** + * Tries to schedule a gridlet. Only the first job in the waiting queue + * for a given partition is scheduled. If a pivot for that partition already + * exists, them the method returns <tt>null</tt> * @param sgl the resource gridlet + * return <tt>true</tt> if gridlet was scheduled; <tt>false</tt> otherwise. */ - private boolean scheduleGridlet(MQGridlet sgl) { + private boolean scheduleGridlet(SSGridlet sgl) { int reqPE = sgl.getNumPE(); - int queueId = sgl.getQueueID(); + int queueId = sgl.getPartitionID(); - EasyBackFillingQueue queue = profile_.getQueue(queueId); + QueuePartition queue = profile_.getQueue(queueId); // if queue has a pivot already, then just add // the job to the waiting queue @@ -485,10 +549,13 @@ double startTime = -1; // keep the potential start time of the gridlet double finishTime = -1; // store the gridlet's expected finish time - // check whether there are PEs available over the time interval requested + // check when enough PEs to handle the gridlet will be available at + // the partition without borrowing PEs Object[] availObjQueue = profile_.checkPERangesAvailability(queueId, reqPE, executionTime); + // check when enough PEs to handle the gridlet will be available + // considering all the partitions Object[] availObj = profile_.checkPERangesAvailability(reqPE, executionTime); @@ -501,11 +568,12 @@ startTimeQueue=profile_.get(anchor).getTime(); } -// System.out.println(profile_); - anchor = (Integer)availObj[0]; double startTimeAll = profile_.get(anchor).getTime(); + // if the time if the selected partition is smaller or the same as + // considering all the partitions, so that means that we can select + // resources from the selected partition if(startTimeQueue <= startTimeAll) { ranges = (PERangeList)availObjQueue[2]; ranges = super.selectPERangeList(reqPE, ranges); @@ -524,7 +592,8 @@ else { PERangeList addRanges = (PERangeList)availObj[2]; - // the anchor index, the entry in the profile where the gridlet will be placed + // the anchor index, the entry in the profile where + // the gridlet will be placed int anchorIndex = (Integer)availObj[0]; // insert index represents the position after which the entry // corresponding to the gridlet's finish time will be placed @@ -534,16 +603,19 @@ startTime = startTimeAll; finishTime = startTime + executionTime; + // checks what PEs from those selected already belong + // to the gridlet's partition availObjQueue = profile_.checkPERangesAvailability(queueId, startTime, executionTime); - ranges = availObjQueue == null ? new PERangeList() : (PERangeList)availObjQueue[2]; - addRanges = availObjQueue == null ? addRanges : PERangeList.difference(addRanges, ranges); + ranges = availObjQueue == null ? new PERangeList() : + (PERangeList)availObjQueue[2]; + + addRanges = availObjQueue == null ? addRanges : + PERangeList.difference(addRanges, ranges); + addRanges = super.selectPERangeList(reqPE - ranges.getNumPE(), addRanges); -// System.out.println("\nRanges to transfer to queue " + queueId +" = " + -// addRanges + " from " + startTime + " to " + finishTime); - // borrows the ranges from the queues and adds it into the // specified queue profile_.transferPEs(queueId, addRanges, startTime, finishTime); @@ -647,9 +719,9 @@ int itemsFinished = 0; // iterates the list to check what has finished - Iterator<MQGridlet> iter = runningGridlets_.iterator(); + Iterator<SSGridlet> iter = runningGridlets_.iterator(); while (iter.hasNext()) { - MQGridlet gridlet = iter.next(); + SSGridlet gridlet = iter.next(); // as gridlets are removed from running queue once they finish // time is smaller than current time, then testing the time // is enough. There's no need to check status @@ -675,7 +747,7 @@ // first checks whether the pivots can be started // checks the pivots first - for(EasyBackFillingQueue queue : profile_.queues_.values()) { + for(QueuePartition queue : profile_.queues_.values()) { if(queue.pivot_ != null && queue.pivot_.getStartTime() <= currentTime) { runningGridlets_.add(queue.pivot_); queuedGridlets_.remove(queue.pivot_); @@ -691,9 +763,9 @@ // Start the execution of Gridlets that are queued and whose // potential start execution time is smaller than reference time - Iterator<MQGridlet> iter = queuedGridlets_.iterator(); + Iterator<SSGridlet> iter = queuedGridlets_.iterator(); while (iter.hasNext()) { - MQGridlet gridlet = iter.next(); + SSGridlet gridlet = iter.next(); if(gridlet.getStartTime() < 0) { boolean success = startGridlet(gridlet); @@ -725,73 +797,53 @@ super.sendFinishGridlet( sgl.getGridlet() ); } - - private class EasyBackFillingQueue { - int queueId_; // this queue's identifier + // ---------------------- PRIVATE CLASSES ------------------------ + + /** + * This class represents a partition in this scheduler. It only + * stores a few variables used to control the partition. + * @author Marcos Dias de Assuncao + * @since GridSim Turbo Alpha 0.1 + */ + private class QueuePartition { + int partitionId_; // this partition's identifier int initialNumPEs_; // the initial number of PEs allocated - PERangeList idlePERanges_; // idle resources in this queue - MQGridlet pivot_; // the first job of this queue in the general waiting queue + PERangeList idlePERanges_; // idle resources in this partition + SSGridlet pivot_; // the first job of this queue in the general waiting queue // to check whether a gridlet can be scheduled in this queue - QueuePredicate predicate_; + QueuePartitionPredicate predicate_; - protected EasyBackFillingQueue(int queueId, - int numPE, QueuePredicate predicate) { - this.queueId_ = queueId; + protected QueuePartition(int queueId, + int numPE, QueuePartitionPredicate predicate) { + this.partitionId_ = queueId; initialNumPEs_ = numPE; predicate_ = predicate; pivot_ = null; } - - protected int getNumIdlePEs() { - return (idlePERanges_ == null) ? 0 : idlePERanges_.getNumPE(); - } } - private class MQGridlet extends SSGridlet { - private int queueId_; - private int priority_; - - public MQGridlet(Gridlet gridlet) { - super(gridlet); - queueId_ = UNKNOWN; - } - - public void setQueueID(int queueId) { - queueId_ = queueId; - } - - public int getQueueID() { - return queueId_; - } - - public int getPriority() { - return priority_; - } - - public void setPriority(int priority) { - this.priority_ = priority; - } - } - /** - * This class represents an entry in the usage profile. There is an entry + * This class represents an entry in the profile. There is an entry * at most in the usage profile for each job scheduled by this policy. * * @author Marcos Dias de Assuncao * @since GridSim Turbo Alpha 0.1 */ private class ProfileEntry { + // the ranges available + private HashMap <Integer, PERangeList> ranges_; + // the time when the ranges will be available + private double time_; + // number of gridlets that rely on this entry + // to mark their completion time or anchor point + private int numGridlets_ = 1; - private HashMap <Integer, PERangeList> ranges_; // the ranges available - private double time_; // the time when the ranges will be available - private int numGridlets_ = 1; // number of gridlets that rely on this entry - // to mark their completion time or anchor point /** * Creates an instance of @link{ProfileEntry}. * @param time the time associated with this event */ - public ProfileEntry(double time) { + protected ProfileEntry(double time) { time_ = time; ranges_ = new HashMap<Integer, PERangeList>(); } @@ -801,11 +853,15 @@ * @param queue the queue whose ranges should be obtained * @return the ranges of free PEs associated with this entry */ - public PERangeList getPERanges(int queue) { + protected PERangeList getPERanges(int queue) { return ranges_.get(queue); } - - public PERangeList getPERanges() { + + /** + * Returns the general ranges of free PEs associated with this entry + * @return the ranges of free PEs associated with this entry + */ + protected PERangeList getPERanges() { PERangeList result = new PERangeList(); for(PERangeList list : ranges_.values()) { if(list.getNumPE() > 0) @@ -819,12 +875,13 @@ * @param queue the queue whose ranges should be set * @param list the range of PEs */ - public void setPERangeList(int queue, PERangeList list) { + protected void setPERangeList(int queue, PERangeList list) { ranges_.put(queue, list); // testNumPEs(); } - private void testNumPEs() { + // FOR DEBUGGING PURPOSES ONLY + protected void testNumPEs() { try { if(getNumPE() > resource_.getNumPE()) throw new Exception("Entry contains more PEs than the maximum allowed"); @@ -834,22 +891,21 @@ System.exit(1); } } - /** * Returns the time associated with this entry * @return the time associated */ - public double getTime() { + protected double getTime() { return time_; } /** * Gets the number of PEs associated with this entry * @param queue the queue whose number of PEs be obtained - * @return the number of PEs + * @return the number of PEs available for the queue */ - public int getNumPE(int queue) { + protected int getNumPE(int queue) { PERangeList ranges = getPERanges(queue); if(ranges == null) return 0; @@ -857,38 +913,43 @@ return ranges.getNumPE(); } - public int getNumPE() { + /** + * Gets the number of PEs associated with this entry + * @return the number of PEs + */ + protected int getNumPE() { int numPE = 0; for(PERangeList list : ranges_.values()) { numPE += list.getNumPE(); } return numPE; } - - public void transferPEs(int recQueueId, PERangeList list) { - + + /** + * Transfers PEs from partitions to one selected partition + * @param recQueueId the partition receiving the ranges + * @param list the list of ranges + */ + protected void transferPEs(int recQueueId, PERangeList list) { for(Integer queueId : ranges_.keySet()) { -// if(queueId != recQueueId) { - PERangeList uptList = PERangeList.difference(ranges_.get(queueId), list); - if(uptList == null) - uptList = new PERangeList(); - ranges_.put(queueId, uptList); -// } + PERangeList uptList = PERangeList.difference(ranges_.get(queueId), list); + if(uptList == null) + uptList = new PERangeList(); + ranges_.put(queueId, uptList); } PERangeList queueList = ranges_.get(recQueueId); queueList.addAll(list.clone()); queueList.mergePERanges(); ranges_.put(recQueueId, queueList); - -// testNumPEs(); +// testNumPEs(); // for debugging purposes } /** * Sets the time associated with this event * @param time the time to be set */ - public void setTime(double time) { + protected void setTime(double time) { time_ = time; } @@ -896,7 +957,7 @@ * Increases the number of Gridlets that rely on this entry to mark * their expected completion time or their anchor point */ - public void increaseGridlet() { + protected void increaseGridlet() { numGridlets_++; } @@ -904,7 +965,7 @@ * Decreases the number of Gridlets that rely on this entry to mark * their expected completion time or their anchor point */ - public void decreaseGridlet() { + protected void decreaseGridlet() { numGridlets_--; } @@ -913,7 +974,7 @@ * their expected completion time or their anchor point * @return the number of Gridlets that use this entry */ - public int getNumGridlets() { + protected int getNumGridlets() { return numGridlets_; } @@ -923,7 +984,7 @@ * @param time the time for the cloned entry * @return the cloned entry */ - public ProfileEntry clone(double time) { + protected ProfileEntry clone(double time) { ProfileEntry clone = new ProfileEntry(time); for(Integer queueId : ranges_.keySet()) { PERangeList clonedRanges = ranges_.get(queueId).clone(); @@ -953,59 +1014,60 @@ /** * This class represents the profile containing the ranges of PEs * available at given simulation times + * * @author Marcos Dias de Assuncao * @since GridSim Turbo Alpha 0.1 */ - private class Profile extends ArrayList<ProfileEntry> { + private class MultiPartitionProfile extends ArrayList<ProfileEntry> { private static final long serialVersionUID = -1853610061073508770L; // The queues used by this scheduler - HashMap<Integer, EasyBackFillingQueue> queues_; + HashMap<Integer, QueuePartition> queues_; /** * Creates a new @link{AvailabilityProfile} object. */ - public Profile() { + protected MultiPartitionProfile() { super(); - queues_ = new HashMap<Integer, EasyBackFillingQueue>(); + queues_ = new HashMap<Integer, QueuePartition>(); } - public void addQueue(EasyBackFillingQueue queue) { - queues_.put(queue.queueId_, queue); + /** + * Returns the number of PEs assigned to the partitions + * @return the number of PEs assigned to the partitions + */ + protected int getNumberOfAssignedPEs() { + int numPEs = 0; + for(QueuePartition queue : queues_.values()) { + numPEs += queue.initialNumPEs_; + } + return numPEs; } - public int getNumberOfQueues() { - return queues_.size(); - } - - - public EasyBackFillingQueue getQueue(int queueId) { + /** + * Gets a partition with the given ID + * @param queueId the id of the partition + * @return the partition with the given ID + */ + protected QueuePartition getQueue(int queueId) { return queues_.get(queueId); } - public int getCorrespondingQueue(SSGridlet sgl) { - for(EasyBackFillingQueue queue : queues_.values()) { + /** + * Gets the able to handle the given gridlet + * @param sgl the gridlet for which a partition is to be found + * @return the partition ID + */ + protected int getCorrespondingQueue(SSGridlet sgl) { + for(QueuePartition queue : queues_.values()) { if(queue.predicate_.match(sgl)) - return queue.queueId_; + return queue.partitionId_; } return UNKNOWN; } /** - * Returns a clone of this object.<br> - * <b>NOTE:</b> this method does not clone the entries - * @return the cloned object - */ - public Profile clone() { - Profile clone = new Profile(); - for(ProfileEntry entry : this){ - clone.add(entry); - } - return clone; - } - - /** * Returns the entry whose time is closest to the <tt>time</tt> given but * smaller, or whose time is equals to <tt>time</tt> * @param time the time to be used to search for the entry @@ -1032,8 +1094,10 @@ * entries whose date is smaller or equals to refTime will * be removed. * @param refTime the reference time to be used for entry removal. + * @return the last entry removed or <tt>null</tt> if no + * entry has been removed */ - public ProfileEntry removePastEntries(double refTime) { + protected ProfileEntry removePastEntries(double refTime) { // Update the availability profile ProfileEntry lastRemoved = null; Iterator<ProfileEntry> iterProfile = super.iterator(); @@ -1051,23 +1115,27 @@ return lastRemoved; } + /** + * Updates the idle PEs at the queues based on a given profile entry + * @param status the profile entry to bed used + */ protected void setCurrentStatus(ProfileEntry status) { - for(EasyBackFillingQueue queue : queues_.values()) { - queue.idlePERanges_ = status.getPERanges(queue.queueId_).clone(); + for(QueuePartition queue : queues_.values()) { + queue.idlePERanges_ = status.getPERanges(queue.partitionId_).clone(); } } /** - * Selects a list of PE ranges able to provide enough - * PEs to handle a Gridlet. + * Checks what are the PEs available for the specified queue during + * the given time duration. * @param duration the duration of the Gridlet - * @return the list of ranges of PEs that can be used by the gridlet. - * Note that this method may return more PEs than the gridlet requires. + * @return the list of ranges of PEs that can be used + * during the given period. */ - private PERangeList getImmediateAvailability(int queueId, double duration) { + protected PERangeList getImmediateAvailability(int queueId, double duration) { double startTime = GridSim.clock(); // start time is now - EasyBackFillingQueue queue = queues_.get(queueId); + QueuePartition queue = queues_.get(queueId); // the gridlet's expected finish time double finishTime = startTime + duration; @@ -1076,8 +1144,8 @@ PERangeList intersectList = queue.idlePERanges_.clone(); // scan the availability profile until the expected termination - // of the Gridlet to check whether enough PEs will be available - // for the Gridlet. Stop the search if not enough PEs are available + // of the Gridlet to check what PEs will be available. Stops the + // search if no PEs are found at a particular time for(ProfileEntry entry : this) { double entryTime = entry.getTime(); if(entryTime < startTime) { @@ -1092,27 +1160,31 @@ if(entryTime < finishTime) { PERangeList listEntry = entry.getPERanges(queueId); intersectList = PERangeList.intersection(intersectList, listEntry); - if(intersectList == null) + if(intersectList == null || intersectList.getNumPE() == 0) break; } } } - // return null if the number of PEs available over the required - // time interval is smaller than what the Gridlet/Reservation requires + // To avoid returning null if(intersectList == null) { - return new PERangeList(); + intersectList = new PERangeList(); } // the PEs that can be used by the gridlet return intersectList; } - + /** + * Creates an entry to be used as anchor when the profile is empty. + * The entry is based on the currently idle PEs at the partitions + * @param time the time for the entry + * @return the entry created. + */ private ProfileEntry createHeadEntry(double time) { ProfileEntry entry = new ProfileEntry(time); - for(EasyBackFillingQueue queue : queues_.values()) { - entry.setPERangeList(queue.queueId_, queue.idlePERanges_.clone()); + for(QueuePartition queue : queues_.values()) { + entry.setPERangeList(queue.partitionId_, queue.idlePERanges_.clone()); } return entry; } @@ -1120,14 +1192,15 @@ /** * Allocates a list of PE ranges to a gridlet or and updates the * availability profile accordingly + * @param queueId the partition from which PEs have been selected * @param finishTime the finish time of the Gridlet * @param selected the list of PE ranges selected */ - public void allocateImmediateRanges(int queueId, double finishTime, + protected void allocateImmediateRanges(int queueId, double finishTime, PERangeList selected) { double startTime = GridSim.clock(); // start time is now - EasyBackFillingQueue queue = queues_.get(queueId); + QueuePartition queue = queues_.get(queueId); // check whether a new tail is needed to mark the end of the request ProfileEntry tailEntry = getPrecedingEntry(finishTime); @@ -1154,53 +1227,37 @@ continue; } else { - PERangeList difference = PERangeList.difference(entry.getPERanges(queueId), selected); + PERangeList difference = + PERangeList.difference(entry.getPERanges(queueId), selected); difference = difference == null ? new PERangeList() : difference; entry.setPERangeList(queueId, difference); } } - PERangeList difference = PERangeList.difference(queue.idlePERanges_, selected); + PERangeList difference = PERangeList.difference(queue.idlePERanges_, selected); + // avoid idle PEs from being null difference = difference == null ? new PERangeList() : difference; - queue.idlePERanges_ = difference; + queue.idlePERanges_ = difference; } - /* + /** * Gets the idle PEs in all queues */ - private PERangeList getOverallIdlePEs() { + protected PERangeList getOverallIdlePEs() { PERangeList idlePEs = new PERangeList(); - for(EasyBackFillingQueue queue: queues_.values()) { + for(QueuePartition queue: queues_.values()) { if(queue.idlePERanges_.getNumPE() > 0) idlePEs.addAll(queue.idlePERanges_.clone()); } return idlePEs; } - private ProfileEntry getIdlePEsPerQueue() { - ProfileEntry entry = new ProfileEntry(GridSim.clock()); - for(EasyBackFillingQueue queue: queues_.values()) { - entry.setPERangeList(queue.queueId_, queue.idlePERanges_.clone()); - } - return entry; - } - - private int getNumFreePEs() { - int freePE = 0; - for(EasyBackFillingQueue queue: queues_.values()) { - freePE += queue.idlePERanges_.getNumPE(); - } - return freePE; - } - /** - * Selects a list of PE ranges able to provide enough - * PEs to handle a Gridlet. + * Checks what PE ranges are available during the given interval. * @param duration the duration of the Gridlet - * @return the list of ranges of PEs that can be used by the gridlet. - * Note that this method may return more PEs than the gridlet requires. + * @return the list of ranges of PEs available */ - private PERangeList getImmediateAvailability(double duration) { + protected PERangeList getImmediateAvailability(double duration) { double startTime = GridSim.clock(); // start time is now @@ -1211,8 +1268,8 @@ PERangeList intersectList = getOverallIdlePEs(); // scan the availability profile until the expected termination - // of the Gridlet to check whether enough PEs will be available - // for the Gridlet. Stop the search if not enough PEs are available + // of the Gridlet to check what PEs will be available until the + // finishTime. Stops the search if it finds null resources for(ProfileEntry entry : this) { double entryTime = entry.getTime(); if(entryTime < startTime) { @@ -1227,24 +1284,33 @@ if(entryTime < finishTime) { PERangeList listEntry = entry.getPERanges(); intersectList = PERangeList.intersection(intersectList, listEntry); - if(intersectList == null) + if(intersectList == null || intersectList.getNumPE() == 0) break; } } } - // return null if the number of PEs available over the required - // time interval is smaller than what the Gridlet/Reservation requires + // to avoid returning null if(intersectList == null) { - return new PERangeList(); + intersectList = new PERangeList(); } // the PEs that can be used by the gridlet return intersectList; } - /* - * + /** + * Checks when anough PEs ranges will be available at a given queue to + * handle a given gridlet + * @param queueId the selected queue + * @param reqPE the number of PEs required + * @param duration the duration of the gridlet + * @return an array where: + * array[0] = index of entry used as anchor + * array[1] = index of entry closest to the completion + * array[2] = the list of PEs available at that time + * or <tt>null</tt> if not enough pes will be available at the queue at + * any time */ protected Object[] checkPERangesAvailability(int queueId, int reqPE, double duration) { @@ -1341,8 +1407,15 @@ return result; } - /* - * + /** + * Checks when anough PEs ranges will be available at all queues to + * handle a given gridlet + * @param reqPE the number of PEs required + * @param duration the duration of the gridlet + * @return an array where: + * array[0] = index of entry used as anchor + * array[1] = index of entry closest to the completion + * array[2] = the list of PEs available at that time */ protected Object[] checkPERangesAvailability(int reqPE, double duration) { @@ -1438,9 +1511,17 @@ return result; } - - - private void allocatePERanges(int queueId, + /** + * Allocate processing elements to a gridlet + * @param queueId the id of the gridlet's selected partition + * @param anchorIndex the index of the entry used as anchor + * @param tailIndex the index of the last entry close to the gridlet's + * finish time + * @param selected the selected ranges of PEs + * @param startTime the gridlet's start time + * @param finishTime the gridlet's finish time + */ + protected void allocatePERanges(int queueId, int anchorIndex, int tailIndex, PERangeList selected, double startTime, double finishTime) { @@ -1489,10 +1570,18 @@ } } - private Object[] checkPERangesAvailability(int queueId, + /** + * Checks what ranges of PEs will be available for a gridlet in its + * partition a given time over a period of time + * @param queueId the selected partition id + * @param startTime the start time of the gridlet + * @param duration the duration of the gridlet + * @return the ranges of PEs available + */ + protected Object[] checkPERangesAvailability(int queueId, double startTime, double duration) { - EasyBackFillingQueue queue = queues_.get(queueId); + QueuePartition queue = queues_.get(queueId); // the anchor index, the entry in the profile where // the gridlet will be placed OR the closest entry to the @@ -1555,8 +1644,6 @@ } if(intersectList == null || intersectList.getNumPE() == 0) { - // there are not enough PEs available to serve the - // advance reservation request, then returns null return null; } } @@ -1572,25 +1659,31 @@ return result; } + /** + * Transfers ranges of PEs from other partitons to a selected partition + * @param recQueueId the partition that will receive the PEs + * @param list the list of ranges of PEs to transfer + * @param startTime the start time of the transfer + * @param finishTime the finish time of the transfer + */ protected void transferPEs(int recQueueId, PERangeList list, double startTime, double finishTime) { - + + // if start time is equals to current time, then we have + // to transfer ranges across the idle pes as well if(startTime <= GridSim.clock()) { - for(EasyBackFillingQueue queue : queues_.values()) { -// if(queue.queueId_ != recQueueId) { - queue.idlePERanges_ = PERangeList.difference(queue.idlePERanges_, list); - if(queue.idlePERanges_ == null) - queue.idlePERanges_ = new PERangeList(); -// } + for(QueuePartition queue : queues_.values()) { + queue.idlePERanges_ = PERangeList.difference(queue.idlePERanges_, list); + if(queue.idlePERanges_ == null) + queue.idlePERanges_ = new PERangeList(); } - EasyBackFillingQueue queue = queues_.get(recQueueId); -// queue.idlePERanges_ = PERangeList.difference(queue.idlePERanges_, list); -// queue.idlePERanges_ = queue.idlePERanges_ == null ? new PERangeList() : queue.idlePERanges_; + QueuePartition queue = queues_.get(recQueueId); queue.idlePERanges_.addAll(list.clone()); queue.idlePERanges_.mergePERanges(); } + // transfer the ranges for(int i=0; i<super.size(); i++) { ProfileEntry nextEntry = super.get(i); if(nextEntry.getTime() < startTime) @@ -1603,11 +1696,6 @@ } } } - - protected void releaseRanges(int queueId, PERangeList ranges) { - EasyBackFillingQueue queue = queues_.get(queueId); - queue.idlePERanges_.addAll(ranges.clone()); - } /** * Creates an string representation of the profile Copied: branches/gridsim4.0-branch3/source/gridsim/turbo/QueuePartitionPredicate.java (from rev 102, branches/gridsim4.0-branch3/source/gridsim/turbo/QueuePredicate.java) =================================================================== --- branches/gridsim4.0-branch3/source/gridsim/turbo/QueuePartitionPredicate.java (rev 0) +++ branches/gridsim4.0-branch3/source/gridsim/turbo/QueuePartitionPredicate.java 2008-02-15 04:13:00 UTC (rev 103) @@ -0,0 +1,29 @@ +/* + * Title: GridSim Toolkit + * Description: GridSim (Grid Simulation) Toolkit for Modelling and Simulation + * of Parallel and Distributed Systems such as Clusters and Grids + * Licence: GPL - http://www.gnu.org/copyleft/gpl.html + */ + +package gridsim.turbo; + +/** + * This interface is used to filter what gridlets should be put in a given + * partition by policies that use multiple partitions or queues. See for + * example {@link MultipleEasyBackfillingQueues}. + * + * @author Marcos Dias de Assuncao + * @since GridSim Turbo Alpha 0.1 + */ + +public interface QueuePartitionPredicate { + + /** + * Checks whether a given gridlet meets the criteria of the partition. + * @param gridlet the gridlet to be considered for scheduling. + * @return <tt>true</tt> if the gridlet can be included in this + * partition; <tt>false</tt> otherwise. + */ + boolean match(SSGridlet gridlet); + +} Deleted: branches/gridsim4.0-branch3/source/gridsim/turbo/QueuePredicate.java =================================================================== --- branches/gridsim4.0-branch3/source/gridsim/turbo/QueuePredicate.java 2008-02-14 12:00:22 UTC (rev 102) +++ branches/gridsim4.0-branch3/source/gridsim/turbo/QueuePredicate.java 2008-02-15 04:13:00 UTC (rev 103) @@ -1,28 +0,0 @@ -/* - * Title: GridSim Toolkit - * Description: GridSim (Grid Simulation) Toolkit for Modelling and Simulation - * of Parallel and Distributed Systems such as Clusters and Grids - * Licence: GPL - http://www.gnu.org/copyleft/gpl.html - */ - -package gridsim.turbo; - -/** - * This interface is used to filter what gridlets should be put in a given - * scheduling queue by the {@link MultipleEasyBackfillingQueues}. - * - * @author Marcos Dias de Assuncao - * @since GridSim Turbo Alpha 0.1 - */ - -public interface QueuePredicate { - - /** - * Checks whether a given gridlet meet the criteria of the scheduling queue. - * @param gridlet the gridlet to be considered for scheduling. - * @return <tt>true</tt> whether the gridlet can be included in this - * queue, or <tt>false</tt> otherwise. - */ - boolean match(SSGridlet gridlet); - -} Modified: branches/gridsim4.0-branch3/source/gridsim/turbo/SSGridlet.java =================================================================== --- branches/gridsim4.0-branch3/source/gridsim/turbo/SSGridlet.java 2008-02-14 12:00:22 UTC (rev 102) +++ branches/gridsim4.0-branch3/source/gridsim/turbo/SSGridlet.java 2008-02-15 04:13:00 UTC (rev 103) @@ -9,6 +9,7 @@ import java.text.DecimalFormat; +import gridsim.GridResource; import gridsim.GridSim; import gridsim.Gridlet; import gridsim.gui.GridSimVisualizer; @@ -49,7 +50,14 @@ private int numPE_; // A list of ranges of PEs used by this Gridlet - private PERangeList peRangeList_ = null; + private PERangeList peRangeList_ = null; + + // the partiton or queue in the resource to which this + // gridlet was scheduled + private int partition_; + + // the priority of this gridlet assigned by the scheduler + private int priority_; // NOTE: Below attributes are related to AR stuff private final int NOT_FOUND = -1; @@ -287,6 +295,50 @@ } /** + * Gets the id of the partition or queue to which this + * gridlet was scheduled + * @return the partition id or <tt>-1</tt> if not found + */ + public int getPartitionID() { + return partition_; + } + + /** + * Sets the id of the partition or queue to which this + * gridlet was scheduled + * @param partition the partition id + * @return <tt>true</tt> if set correctly or <tt>false</tt> otherwise. + */ + public boolean setPartitionID(int partition) { + if(partition < 0) + return false; + + partition_ = partition; + return true; + } + + /** + * Gets the priority of this gridlet assigned by the scheduler + * @return the priority or <tt>-1</tt> if not found + */ + public int getPriority() { + return priority_; + } + + /** + * Sets the priority of this gridlet assigned by the scheduler + * @param priority the priority + * @return <tt>true</tt> if set correctly or <tt>false</tt> otherwise. + */ + public boolean setPriority(int priority) { + if(priority < 0) + return false; + + priority_ = priority; + return true; + } + + /** * Gets the remaining gridlet length * @return gridlet length * @pre $none @@ -476,6 +528,8 @@ this.startTime_ = NOT_FOUND; this.totalCompletionTime_ = 0.0; this.startExecTime_ = 0.0; + this.partition_ = NOT_FOUND; + this.priority_ = NOT_FOUND; // In case a Gridlet has been executed partially by some other grid // ... [truncated message content] |
From: <mar...@us...> - 2008-02-14 12:00:17
|
Revision: 102 http://gridsim.svn.sourceforge.net/gridsim/?rev=102&view=rev Author: marcos_dias Date: 2008-02-14 04:00:22 -0800 (Thu, 14 Feb 2008) Log Message: ----------- This update includes a bug fix in the easy backfilling policy and a preliminary version of a multiple queue backfilling policy. Modified Paths: -------------- branches/gridsim4.0-branch3/examples/examples/workload/parallel/TurboExampleEasy01.java branches/gridsim4.0-branch3/examples/examples/workload/parallel/TurboExampleMultiEBQueues01.java branches/gridsim4.0-branch3/source/gridsim/GridResource.java branches/gridsim4.0-branch3/source/gridsim/gui/ResourceWindow.java branches/gridsim4.0-branch3/source/gridsim/turbo/AvailabilityProfile.java branches/gridsim4.0-branch3/source/gridsim/turbo/CBParallelSpaceShared.java branches/gridsim4.0-branch3/source/gridsim/turbo/EBParallelSpaceShared.java branches/gridsim4.0-branch3/source/gridsim/turbo/MultipleEasyBackfillingQueues.java branches/gridsim4.0-branch3/source/gridsim/turbo/PERangeList.java branches/gridsim4.0-branch3/source/gridsim/turbo/SSGridlet.java branches/gridsim4.0-branch3/source/gridsim/turbo/TAllocPolicy.java branches/gridsim4.0-branch3/source/gridsim/turbo/TResourceCharacteristics.java Added Paths: ----------- branches/gridsim4.0-branch3/examples/examples/workload/parallel/TurboExampleMultiEBQueues02.java branches/gridsim4.0-branch3/source/gridsim/turbo/QueuePredicate.java Modified: branches/gridsim4.0-branch3/examples/examples/workload/parallel/TurboExampleEasy01.java =================================================================== --- branches/gridsim4.0-branch3/examples/examples/workload/parallel/TurboExampleEasy01.java 2008-02-12 05:46:26 UTC (rev 101) +++ branches/gridsim4.0-branch3/examples/examples/workload/parallel/TurboExampleEasy01.java 2008-02-14 12:00:22 UTC (rev 102) @@ -85,10 +85,10 @@ ////////////////////////////////////////// // Starts the simulation in debug mode - GridSim.startGridSimulation(true); +// GridSim.startGridSimulation(true); // Start the simulation in normal mode -// GridSim.startGridSimulation(); + GridSim.startGridSimulation(); ////////////////////////////////////////// // Final step: Prints the Gridlets when simulation is over Modified: branches/gridsim4.0-branch3/examples/examples/workload/parallel/TurboExampleMultiEBQueues01.java =================================================================== --- branches/gridsim4.0-branch3/examples/examples/workload/parallel/TurboExampleMultiEBQueues01.java 2008-02-12 05:46:26 UTC (rev 101) +++ branches/gridsim4.0-branch3/examples/examples/workload/parallel/TurboExampleMultiEBQueues01.java 2008-02-14 12:00:22 UTC (rev 102) @@ -1,10 +1,14 @@ package examples.workload.parallel; +import gridsim.AllocPolicy; import gridsim.GridResource; import gridsim.GridSim; import gridsim.Machine; import gridsim.MachineList; +import gridsim.ResourceCalendar; +import gridsim.ResourceCharacteristics; +import gridsim.turbo.MultipleEasyBackfillingQueues; import gridsim.turbo.TResourceCharacteristics; import gridsim.util.Workload; @@ -85,10 +89,10 @@ ////////////////////////////////////////// // Starts the simulation in debug mode - GridSim.startGridSimulation(true); +// GridSim.startGridSimulation(true); // Start the simulation in normal mode -// GridSim.startGridSimulation(); + GridSim.startGridSimulation(); ////////////////////////////////////////// // Final step: Prints the Gridlets when simulation is over @@ -143,6 +147,13 @@ TResourceCharacteristics resConfig = new TResourceCharacteristics( arch, os, mList, TResourceCharacteristics.EB_PARALLEL_SPACE_SHARED, time_zone, cost); + + MultipleEasyBackfillingQueues policy = null; + try { + policy = new MultipleEasyBackfillingQueues(name, "Policy", 1); + } catch (Exception e1) { + e1.printStackTrace(); + } ////////////////////////////////////////// // 6. Finally, we need to create a GridResource object. @@ -160,10 +171,14 @@ // incorporates holidays. However, no holidays are set in this example LinkedList holidays = new LinkedList(); GridResource gridRes = null; + + ResourceCalendar resCalendar = new ResourceCalendar(time_zone, + peakLoad, offPeakLoad, holidayLoad, weekends, + holidays, seed); + try { - gridRes = new GridResource(name, baud_rate, seed, - resConfig, peakLoad, offPeakLoad, holidayLoad, weekends, - holidays); + gridRes = new GridResource(name, baud_rate, resConfig, + resCalendar, policy); } catch (Exception e) { e.printStackTrace(); Added: branches/gridsim4.0-branch3/examples/examples/workload/parallel/TurboExampleMultiEBQueues02.java =================================================================== --- branches/gridsim4.0-branch3/examples/examples/workload/parallel/TurboExampleMultiEBQueues02.java (rev 0) +++ branches/gridsim4.0-branch3/examples/examples/workload/parallel/TurboExampleMultiEBQueues02.java 2008-02-14 12:00:22 UTC (rev 102) @@ -0,0 +1,247 @@ + +package examples.workload.parallel; + +import gridsim.GridResource; +import gridsim.GridSim; +import gridsim.Machine; +import gridsim.MachineList; +import gridsim.ResourceCalendar; +import gridsim.turbo.MultipleEasyBackfillingQueues; +import gridsim.turbo.QueuePredicate; +import gridsim.turbo.SSGridlet; +import gridsim.turbo.TResourceCharacteristics; +import gridsim.util.Workload; + +import java.util.ArrayList; +import java.util.Calendar; +import java.util.LinkedList; +import java.util.Random; + + +/** + * Test Driver class for this example + */ +public class TurboExampleMultiEBQueues02 +{ + /** + * Creates main() to run this example + */ + public static void main(String[] args) + { + long startTime = System.currentTimeMillis(); + if(args.length == 0){ + System.out.println("Please provide the location of the workload file!"); + System.exit(1); + } + + try { + + ////////////////////////////////////////// + // Get the workload to be used The format should be: + // ASCII text, gzip or zip. + + String fileName = args[0]; + // /Users/marcosd/Documents/workspace/intergrid/workloads/sdsc_blue_2000_400.swf + + ArrayList<GridResource> resources = new ArrayList<GridResource>(); + + ////////////////////////////////////////// + // Initialize the GridSim package. It should be called + // before creating any entities. We can't run this example without + // initializing GridSim first. We will get run-time exception + // error. + + // number of grid user entities + any Workload entities. + int num_user = 1; + Calendar calendar = Calendar.getInstance(); + boolean trace_flag = false; // mean trace GridSim events + + // Initialize the GridSim package without any statistical + // functionalities. Hence, no GridSim_stat.txt file is created. + System.out.println("Initializing GridSim package"); + GridSim.init(num_user, calendar, trace_flag); + + ////////////////////////////////////////// + // Creates one or more GridResource entities + int totalResource = 1; // total number of Grid resources + int rating = 377; // rating of each PE in MIPS + int totalPE = 9; // total number of PEs for each Machine + int totalMachine = 128; // total number of Machines + int i = 0; + + String[] resArray = new String[totalResource]; + for (i = 0; i < totalResource; i++) { + String resName = "Res_" + i; + GridResource resource = createGridResource(resName, rating, totalMachine, totalPE); + resources.add(resource); + + // add a resource name into an array + resArray[i] = resName; + } + + ////////////////////////////////////////// + // Creates one Workload trace entity. + + int resID = 0; + Random r = new Random(); + resID = r.nextInt(totalResource); + Workload workload = new Workload("Load_1", fileName, resArray[resID], rating); + + ////////////////////////////////////////// + // Starts the simulation in debug mode + GridSim.startGridSimulation(true); + + // Start the simulation in normal mode +// GridSim.startGridSimulation(); + + ////////////////////////////////////////// + // Final step: Prints the Gridlets when simulation is over + long finishTime = System.currentTimeMillis(); + System.out.println("The simulation took " + (finishTime - startTime) + " milliseconds"); + + // prints the Gridlets inside a Workload entity + // workload.printGridletList(trace_flag); + } + catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * Creates one Grid resource. A Grid resource contains one or more + * Machines. Similarly, a Machine contains one or more PEs (Processing + * Elements or CPUs). + * @param name a Grid Resource name + * @param peRating rating of each PE + * @param totalMachine total number of Machines + * @param totalPE total number of PEs for each Machine + */ + private static GridResource createGridResource(String name, int peRating, + int totalMachine, int totalPE) + { + + ////////////////////////////////////////// + // Here are the steps needed to create a Grid resource: + // 1. We need to create an object of MachineList to store one or more + // Machines + MachineList mList = new MachineList(); + + for (int i = 0; i < totalMachine; i++) + { + ////////////////////////////////////////// + // 4. Create one Machine with its id and list of PEs or CPUs + mList.add( new Machine(i, totalPE, peRating) ); + } + + ////////////////////////////////////////// + // 5. Create a ResourceCharacteristics object that stores the + // properties of a Grid resource: architecture, OS, list of + // Machines, allocation policy: time- or space-shared, time zone + // and its price (G$/PE time unit). + String arch = "Sun Ultra"; // system architecture + String os = "Solaris"; // operating system + double time_zone = 0.0; // time zone this resource located + double cost = 3.0; // the cost of using this resource + + // this resource will use an aggressive backfilling policy (EASY) + TResourceCharacteristics resConfig = new TResourceCharacteristics( + arch, os, mList, TResourceCharacteristics.EB_PARALLEL_SPACE_SHARED, + time_zone, cost); + + MultipleEasyBackfillingQueues policy = null; + try { + policy = new MultipleEasyBackfillingQueues(name, "Policy", 2); + } catch (Exception e1) { + e1.printStackTrace(); + } + + // creates two partitions, one for small jobs and another for long jobs + // assign the same number of PEs to both + QueuePredicateExample pred1 = new QueuePredicateExample(0, 10000, peRating); + QueuePredicateExample pred2 = new QueuePredicateExample(10000, Integer.MAX_VALUE, peRating); + + policy.createQueue(0, resConfig.getNumPE() / 2, pred1); + policy.createQueue(1, resConfig.getNumPE() / 2, pred2); + + ////////////////////////////////////////// + // 6. Finally, we need to create a GridResource object. + double baud_rate = 10000.0; // communication speed + long seed = 11L*13*17*19*23+1; + double peakLoad = 0.0; // the resource load during peak hour + double offPeakLoad = 0.0; // the resource load during off-peak hr + double holidayLoad = 0.0; // the resource load during holiday + + // incorporates weekends so the grid resource is on 7 days a week + LinkedList weekends = new LinkedList(); + weekends.add(new Integer(Calendar.SATURDAY)); + weekends.add(new Integer(Calendar.SUNDAY)); + + // incorporates holidays. However, no holidays are set in this example + LinkedList holidays = new LinkedList(); + GridResource gridRes = null; + + ResourceCalendar resCalendar = new ResourceCalendar(time_zone, + peakLoad, offPeakLoad, holidayLoad, weekends, + holidays, seed); + + try { + gridRes = new GridResource(name, baud_rate, resConfig, + resCalendar, policy); + } + catch (Exception e) { + e.printStackTrace(); + } + + System.out.println("Creates one Grid resource with name = " + name); + return gridRes; + } +} // end class + +class QueuePredicateExample implements QueuePredicate { + int minRuntime_; + int maxRuntime_; + int resRating_; + + /* + * Default constructor + */ + public QueuePredicateExample(int minRuntime, + int maxRuntime, int rating) { + this.minRuntime_ = minRuntime; + this.maxRuntime_ = maxRuntime; + this.resRating_ = rating; + } + + /* + * (non-Javadoc) + * @see gridsim.turbo.QueuePredicate#match(gridsim.turbo.SSGridlet) + */ + public boolean match(SSGridlet gridlet) { + double runtime = forecastExecutionTime(gridlet); + if(runtime < minRuntime_ || runtime >= maxRuntime_) + return false; + + return true; + } + + /* + * Forecast execution time of a Gridlet. + * <tt>execution time = length / available rating</tt> + * @param gridlet the gridlet to be considered + * @return Gridlet's execution time. + */ + private double forecastExecutionTime(SSGridlet gridlet) { + double executionTime = (gridlet.getLength() / resRating_); + + // This is as a safeguard since the finish time can be extremely + // small close to 0.0, such as 4.5474735088646414E-14. Hence causing + // some Gridlets never to be finished and consequently hang the program + if (executionTime < 1.0) { + executionTime = 1.0; + } + return executionTime; + } +} + + + Modified: branches/gridsim4.0-branch3/source/gridsim/GridResource.java =================================================================== --- branches/gridsim4.0-branch3/source/gridsim/GridResource.java 2008-02-12 05:46:26 UTC (rev 101) +++ branches/gridsim4.0-branch3/source/gridsim/GridResource.java 2008-02-14 12:00:22 UTC (rev 102) @@ -14,7 +14,6 @@ import gridsim.turbo.EBParallelSpaceShared; import gridsim.turbo.CBParallelSpaceShared; import gridsim.turbo.MultipleEasyBackfillingQueues; -import gridsim.turbo.TAllocPolicy; import gridsim.turbo.TResourceCharacteristics; import gridsim.index.*; @@ -646,10 +645,11 @@ case TResourceCharacteristics.AR_PARALLEL_SPACE_SHARED: policy_ = new ARParallelSpaceShared(super.get_name(), "ARParallelSpaceShared"); break; - + + // creates the scheduler with only one queue case TResourceCharacteristics.MULTIPLE_EASY_BACKFILLING_QUEUES: policy_ = new MultipleEasyBackfillingQueues(super.get_name(), - "MultipleEasyBackfillingQueues"); + "MultipleEasyBackfillingQueues", 1); break; default: Modified: branches/gridsim4.0-branch3/source/gridsim/gui/ResourceWindow.java =================================================================== --- branches/gridsim4.0-branch3/source/gridsim/gui/ResourceWindow.java 2008-02-12 05:46:26 UTC (rev 101) +++ branches/gridsim4.0-branch3/source/gridsim/gui/ResourceWindow.java 2008-02-14 12:00:22 UTC (rev 102) @@ -694,7 +694,7 @@ for(int i=0; i<size; i++) { ScheduleItem item = (ScheduleItem)scheduledItems_.get(i); - if(item == null) + if(item == null || item.getStartTime() < 0) continue; int itemId = item.getID(); Modified: branches/gridsim4.0-branch3/source/gridsim/turbo/AvailabilityProfile.java =================================================================== --- branches/gridsim4.0-branch3/source/gridsim/turbo/AvailabilityProfile.java 2008-02-12 05:46:26 UTC (rev 101) +++ branches/gridsim4.0-branch3/source/gridsim/turbo/AvailabilityProfile.java 2008-02-14 12:00:22 UTC (rev 102) @@ -70,19 +70,25 @@ * entries whose date is smaller or equals to refTime will * be removed. * @param refTime the reference time to be used for entry removal. + * @return the last entry removed or <tt>null</tt> if no entry + * has been removed. */ - public void removePastEntries(double refTime) { + public AvailabilityProfileEntry removePastEntries(double refTime) { + AvailabilityProfileEntry lastRemoved = null; // Update the availability profile Iterator<AvailabilityProfileEntry> iterProfile = super.iterator(); while(iterProfile.hasNext()) { AvailabilityProfileEntry entry = iterProfile.next(); if(entry.getTime() <= refTime){ + lastRemoved = entry; iterProfile.remove(); } else{ break; } } + + return lastRemoved; } /** Modified: branches/gridsim4.0-branch3/source/gridsim/turbo/CBParallelSpaceShared.java =================================================================== --- branches/gridsim4.0-branch3/source/gridsim/turbo/CBParallelSpaceShared.java 2008-02-12 05:46:26 UTC (rev 101) +++ branches/gridsim4.0-branch3/source/gridsim/turbo/CBParallelSpaceShared.java 2008-02-14 12:00:22 UTC (rev 102) @@ -239,7 +239,7 @@ // If there are no jobs in the queue list, then check if // there are enough PEs to process the job immediately boolean success = false; - int freePE = super.resource_.getNumFreePE(); + int freePE = resource_.getNumFreePE(); if( reqPE <= freePE ){ success = startGridlet(sgl); @@ -908,7 +908,6 @@ break; } else { - // Sep. 29, 2007 - Changed by Marcos // if the finish time is equals to the entry time, so there // is no need to check the intersection if(entryTime < finishTime) { @@ -1116,7 +1115,7 @@ * start time or the place where the new anchor (if needed) will be placed * @param tailIndex the index of the entry closest to the finish time but * whose time is smaller or equals to the finish time - * @param selected the lsit of PE ranges selected + * @param selected the list of PE ranges selected * @param startTime the start time of the Gridlet * @param finishTime the finish time of the Gridlet */ Modified: branches/gridsim4.0-branch3/source/gridsim/turbo/EBParallelSpaceShared.java =================================================================== --- branches/gridsim4.0-branch3/source/gridsim/turbo/EBParallelSpaceShared.java 2008-02-12 05:46:26 UTC (rev 101) +++ branches/gridsim4.0-branch3/source/gridsim/turbo/EBParallelSpaceShared.java 2008-02-14 12:00:22 UTC (rev 102) @@ -37,8 +37,7 @@ * with Backfilling. IEEE Transactions on Parallel and Distributed * Systems, 12:(6), pp. 529-543, 2001. * </ul> - * - * This policy maintains an availability profile. The availability + * <br> This policy maintains an availability profile. The availability * profile contains information about the ranges of processing elements * (PEs) that will be released when the running jobs complete. * In addition, the policy maintains the list of extra nodes, that is, the nodes @@ -54,9 +53,7 @@ * simulate this, you have to model the local load as gridlets. * It is more precise and faster. To do so, please check * {@link Lublin99Workload}. - * <li> Gridlets cannot be paused nor migrated. This could be - * easily done, but due to time constraints, I could not - * implement these features. + * <li> Gridlets cannot be paused nor migrated. * </ul> * * @author Marcos Dias de Assuncao @@ -71,10 +68,12 @@ */ public class EBParallelSpaceShared extends TAllocPolicy { - // Queue of waiting Gridlets protected LinkedList<SSGridlet> queuedGridlets_; + // Pivot job (i.e. the first job in the queue) + private SSGridlet pivot_; + // Queue of running Gridlets protected LinkedList<SSGridlet> runningGridlets_; @@ -97,9 +96,6 @@ // queue is scheduled private PERangeList extraPEs_; - // used only to set the extraPEs_ back to the default value - private PERangeList allPEs_; - // a tag to indicate that a gridlet has finished private static final int UPDATE_SCHEDULE_TAG = 10; @@ -133,7 +129,9 @@ availProfile_ = new AvailabilityProfile(); lastScheduleUpdate_ = 0.0D; shadowTime_ = Double.MAX_VALUE; + extraPEs_ = null; ratingPE_ = 0; + pivot_ = null; } /** @@ -148,10 +146,6 @@ // of one PE assuming that the machines are homogeneous ratingPE_ = resource_.getMIPSRatingOfOnePE(); - // the extra PEs to start are the same that are free - extraPEs_ = resource_.getFreePERanges().clone(); - allPEs_ = extraPEs_.clone(); - // a loop that is looking for internal events only Sim_event ev = new Sim_event(); while ( Sim_system.running() ) { @@ -180,10 +174,8 @@ availProfile_.clear(); lastScheduleUpdate_ = 0.0D; shadowTime_ = Double.MAX_VALUE; - ratingPE_ = 0; + extraPEs_ = null; resource_.resetFreePERanges(); - extraPEs_ = resource_.getFreePERanges().clone(); - allPEs_ = extraPEs_.clone(); } /** @@ -233,21 +225,13 @@ if( reqPE <= freePE ) { success = startGridlet(sgl); - - //------------------ FOR DEBUGGING PURPOSES ONLY ---------------- - - // Notifies the listeners that a Gridlet has been either scheduled - // to run immediately or put in the waiting queue - GridSim.notifyListeners(this.get_id(), - AllocationAction.ITEM_SCHEDULED, true, sgl); - - //--------------------------------------------------------------- } // if the job could not be scheduled immediately, then // it has to be put in the waiting queue if(!success) { - enqueueGridlet(sgl); + scheduleGridlet(sgl); + queuedGridlets_.add(sgl); } // sends back an ack if required @@ -396,8 +380,7 @@ private boolean startGridlet(SSGridlet sgl) { int reqPE = sgl.getNumPE(); - if(resource_.getFreePERanges() == null || - resource_.getFreePERanges().getNumPE() < reqPE) { + if(resource_.getNumFreePE() < reqPE) { return false; } @@ -419,72 +402,23 @@ // time is equals to the gridlet's or advance reservation's finish time int tailIndex = -1; - // if there are no jobs in the queue or in execution - if(availProfile_.size() == 0 && shadowTime_ == Double.MAX_VALUE) { - selected = super.selectPERangeList(reqPE, resource_.getFreePERanges()); - } - else { - // a pointer to the last entry analysed - AvailabilityProfileEntry tailEntry = null; - - // the list of selected ranges - PERangeList intersectList = null; - - // For immediate gridlets the start point - // is the current list of PEs available - intersectList = resource_.getFreePERanges().clone(); - - // scan the availability profile until the expected termination - // of the Gridlet to check whether enough PEs will be available - // for the Gridlet. Stop the search if not enough PEs are available - for(AvailabilityProfileEntry entry : availProfile_) { - double entryTime = entry.getTime(); - if(entryTime < currentTime) { - continue; - } - else if(entryTime > finishTime) { - break; - } - else { - tailEntry = entry; - // if the finish time is equals to the entry time, so there - // is no need to check the intersection - if(entryTime < finishTime) { - PERangeList listEntry = entry.getPERanges(); - intersectList = PERangeList.intersection(listEntry, intersectList); - if(intersectList == null || intersectList.getNumPE() < reqPE) - break; - } - } - tailIndex = availProfile_.indexOf(tailEntry); - } + PERangeList intersect = resource_.getFreePERanges(); + + if(finishTime > shadowTime_) + intersect = PERangeList.intersection(intersect, extraPEs_); + + selected = super.selectPERangeList(reqPE, intersect); + if(selected == null || selected.getNumPE() < reqPE) + return false; - // return false if the number of PEs available over the required - // time interval is smaller than what the Gridlet requires - if(intersectList == null || intersectList.getNumPE() < reqPE) { - return false; - } - else { - // the job has to finish before the shadow time or has - // to use less PEs than the extra nodes - if(finishTime < shadowTime_) { - selected = super.selectPERangeList(reqPE, intersectList); - } - else { - intersectList = PERangeList.intersection(intersectList, extraPEs_); - if(intersectList == null || intersectList.getNumPE() < reqPE) { - return false; - } - else { - selected = super.selectPERangeList(reqPE, intersectList); - extraPEs_ = PERangeList.difference(extraPEs_, selected); - } - } - } - } + // a pointer to the last entry analysed + AvailabilityProfileEntry tailEntry = + availProfile_.getPrecedingEntry(finishTime); + + tailIndex = tailEntry == null ? -1 : availProfile_.indexOf(tailEntry); // allocate the ranges of PEs to the gridlet - allocatePERanges(tailIndex, selected, currentTime, finishTime); + allocatePERanges(tailIndex, selected, finishTime); // add this Gridlet into execution list runningGridlets_.add(sgl); @@ -500,29 +434,36 @@ // then send this event to itself to update the queues after // this gridlet's completion time super.sendInternalEvent(executionTime, UPDATE_SCHEDULE_TAG); + + //------------------ FOR DEBUGGING PURPOSES ONLY ---------------- + + // Notifies the listeners that a Gridlet has been either scheduled + // to run immediately or put in the waiting queue + GridSim.notifyListeners(this.get_id(), + AllocationAction.ITEM_SCHEDULED, true, sgl); + + //--------------------------------------------------------------- + return true; } /** - * Enqueues a gridlet. That is, put the gridlet into the - * queue of waiting gridlets. If the gridlet is the first into the queue, - * then updates the extra nodes and the shadow time. The shadow time will + * Tries to schedule a gridlet. That is, make the gridlet the pivot, + * or the first gridlet in the queue. If that is not possible, then return + * false. If the gridlet is the first into the queue, then updates the + * pivot, extra nodes and the shadow time. The shadow time will * be the start time of the gridlet whereas the extra PEs will be the * PEs left unused when the gridlet starts execution. * @param sgl the resource gridlet + * @return <tt>true</tt> if scheduled; <tt>false</tt> otherwise. */ - private void enqueueGridlet(SSGridlet sgl) { + private boolean scheduleGridlet(SSGridlet sgl) { int reqPE = sgl.getNumPE(); // if there are gridlets waiting execution already, then simply // insert this gridlet into the queue and return - if(queuedGridlets_.size() > 0) { - queuedGridlets_.add(sgl); - return; - } - - // otherwise, just add the gridlet in the queue and continue - queuedGridlets_.add(sgl); + if(pivot_ != null) + return false; // calculate the execution time of the Gridlet double executionTime = @@ -553,6 +494,7 @@ sgl.setStatus(Gridlet.QUEUED); sgl.setStartTime(startTime); sgl.setFinishTime(finishTime); + pivot_ = sgl; //------------------ FOR DEBUGGING PURPOSES ONLY ---------------- @@ -561,6 +503,8 @@ GridSim.notifyListeners(this.get_id(), AllocationAction.ITEM_SCHEDULED, true, sgl); //--------------------------------------------------------------- + + return true; } /** @@ -568,13 +512,13 @@ * availability profile accordingly * @param tailIndex the index of the entry closest to the finish time but * whose time is smaller or equals to the finish time - * @param selected the list of PE ranges selected - * @param startTime the start time of the Gridlet + * @param selected the list of PE ranges selected * @param finishTime the finish time of the Gridlet */ private void allocatePERanges(int tailIndex, - PERangeList selected, double startTime, double finishTime) { + PERangeList selected, double finishTime) { + double startTime = GridSim.clock(); AvailabilityProfileEntry newEntryAfterTail = null; // if the time of the entry at (tailIndex) is equals to @@ -616,7 +560,7 @@ // Update entries of the profile for(int index=0; index<=updTo; index++) { AvailabilityProfileEntry entry = availProfile_.get(index); - if(entry.getTime() < startTime){ + if(entry.getTime() < startTime) { continue; } PERangeList uptList = @@ -630,6 +574,10 @@ // subtract the selected ranges from the currently free ranges resource_.setPEsBusy(selected); + + if(finishTime > shadowTime_) + extraPEs_ = PERangeList.difference(extraPEs_, selected); + } /** @@ -642,102 +590,41 @@ * array[1] the list of PE ranges available at that time<br> */ private Object[] findStartTime(int reqPE, double duration) { - - // the anchor index, the entry in the profile where - // the gridlet will be placed OR the closest entry to the - // point where the anchor of the advance reservation will be placed - int anchorIndex = -1; - - // a pointer to the anchor entry (described above) - AvailabilityProfileEntry anchorEntry = null; - - // the list of selected ranges - PERangeList intersectList = null; - - double potStartTime = -1; // keep the potential start time of the gridlet - double potFinishTime = -1; // store the gridlet's expected finish time - - intersectList = null; - int length = availProfile_.size(); + PERangeList availRanges = null; // list of ranges available for the job + double startTime = -1; // the job's potential start time Iterator<AvailabilityProfileEntry> iterProfile = availProfile_.iterator(); while(iterProfile.hasNext()) { - - AvailabilityProfileEntry entry = iterProfile.next(); + AvailabilityProfileEntry entry = iterProfile.next(); // scan the profile until an entry with enough PEs is found if(entry.getNumPE() < reqPE) { continue; } else { - - anchorEntry = entry; - anchorIndex = availProfile_.indexOf(anchorEntry); - - // sets the start time as the time of the entry - potStartTime = entry.getTime(); - // calculates when the finish time will be if - // the gridlet is put at this position - potFinishTime = potStartTime + duration; - - // if an entry with enough PEs is found, then scan the profile - // from that point onwards analysing the intersection of - // the ranges available in the entries until the - // gridlet expected completion time - intersectList = entry.getPERanges().clone(); - - // Look for the intersection of available ranges from - // the anchor until the end of the profile or until - // the entries are further than the expected completion time - for(int i=anchorIndex+1; i<length; i++){ - AvailabilityProfileEntry nextEntry = availProfile_.get(i); - if(nextEntry.getTime() > potFinishTime){ - break; - } - else { - // if the finish time is equals to the entry time, so there - // is no need to check the intersection - if(nextEntry.getTime() < potFinishTime) { - intersectList = PERangeList.intersection(intersectList, - nextEntry.getPERanges()); - if(intersectList == null || intersectList.getNumPE() < reqPE) { - break; - } - } - } - } - // If a time slot with enough PEs has been found, then stop the search - if(intersectList != null && intersectList.getNumPE() >= reqPE) { - break; - } + // sets the start time as the time of the entry + startTime = entry.getTime(); + availRanges = entry.getPERanges().clone(); + break; } } // creates the array with the result Object[] result = new Object[3]; - result[0] = new Double(anchorEntry.getTime()); - result[1] = intersectList; + result[0] = new Double(startTime); + result[1] = availRanges; return result; } - /** - * This method is called to update the schedule. It removes completed - * gridlets and return them to the users and verifies whether the first gridlet - * in the waiting queue can be started. If it cannot be started, them - * tries to backfill with jobs waiting in the queue. The method also - * removes old entries from the availability profile. + /** + * This method finalises the gridlets in execution whose time + * is smaller or equals to the current simulation time. + * @param currentTime the current simulation time + * @return the number of gridlets completed */ - private void updateSchedule(){ + protected int finishRunningGridlets(double currentTime) { + int itemsFinished = 0; - double currentTime = GridSim.clock(); - int gridletFinished = 0; - int gridletStarted = 0; - - // removes all Gridlets that have already completed from - // the queue of running Gridlets - PERangeList releasedRanges = new PERangeList(); - LinkedList<SSGridlet> grlsCompleted = new LinkedList<SSGridlet>(); - // iterates the list to check what has finished Iterator<SSGridlet> iter = runningGridlets_.iterator(); while (iter.hasNext()) { @@ -747,92 +634,86 @@ // is enough. There's no need to check status if(gridlet.getFinishTime() <= currentTime) { // Update the list of ranges released - releasedRanges.addAll(gridlet.getPERangeList().clone()); - grlsCompleted.add(gridlet); gridletFinish(gridlet, Gridlet.SUCCESS); iter.remove(); - gridletFinished++; - } - } + itemsFinished++; + } + } + return itemsFinished; + } + + /** + * This method is called to update the schedule. It removes completed + * gridlets and return them to the users and verifies whether the first gridlet + * in the waiting queue can be started. If it cannot be started, them + * tries to backfill with jobs waiting in the queue. The method also + * removes old entries from the availability profile. + */ + private void updateSchedule() { + int itemsFinished = 0; + double currentTime = GridSim.clock(); + int itemsStarted = 0; - // returns ranges of PEs to the list of PEs available - resource_.setPEsAvailable(releasedRanges); + itemsFinished = finishRunningGridlets(currentTime); - // Updates the availability profile - Iterator<AvailabilityProfileEntry> iterProfile = availProfile_.iterator(); - while(iterProfile.hasNext()) { - AvailabilityProfileEntry entry = iterProfile.next(); - if(entry.getTime() <= currentTime){ - iterProfile.remove(); - } + // remove past entries from the availability profile + AvailabilityProfileEntry currentStatus = availProfile_.removePastEntries(currentTime); + if(currentStatus != null) { + resource_.resetFreePERanges(currentStatus.getPERanges()); } + + itemsStarted = startQueuedGridlets(currentTime); - // if at least a gridlet has finished, then we should iterate the - // waiting queue. We need to try to start the first gridlet in the queue. - // If it cannot be started, then we should backfill with the remaining - // gridlets in the queue. - if(gridletFinished > 0) { - if(queuedGridlets_.size() > 0) { - - // This is a tricky approach. We decided to clone the waiting - // queue, try to start the first job, and then enqueue all - // jobs again, including the first job if it cannot be started - LinkedList<SSGridlet> clonedQueue = - (LinkedList<SSGridlet>)queuedGridlets_.clone(); - queuedGridlets_.clear(); - - //TODO: To think a better way to do this. But the idea is to - // try to start first job, then enqueue all the other jobs again. - // If the first job cannot be started, then try to start the other - // jobs (ie. backfill) or enqueue them again - SSGridlet gridlet = clonedQueue.getFirst(); - clonedQueue.removeFirst(); - - if(gridlet.getStartTime() <= currentTime) { - // if the gridlet can be started, then the extra nodes - // and the shadow time will be set back to the default values - // and will be changed when the next gridlet in the waiting queue - // is scheduled. - extraPEs_ = allPEs_.clone(); - shadowTime_ = Double.MAX_VALUE; - if (!startGridlet(gridlet)) { - // NOTE that it should NOT happen, - // but if it does, enqueue the job - enqueueGridlet(gridlet); - } - } - else { - // if the first job cannot be started, then put it back into - // the queue and backfill with other jobs. That is, try to - // start the other jobs. - queuedGridlets_.add(gridlet); - iter = clonedQueue.iterator(); - while(iter.hasNext()) { - gridlet = iter.next(); - if(startGridlet(gridlet)) - iter.remove(); - } - } - - // Add the jobs still remaining back into the waiting queue - iter = clonedQueue.iterator(); - while(iter.hasNext()) { - gridlet = iter.next(); - enqueueGridlet(gridlet); - } - } - - //---------------- USED FOR DEBUGGING PURPOSES ONLY -------------------- + //---------------- USED FOR DEBUGGING PURPOSES ONLY -------------------- - // If a gridlet has started execution or one has finished, - // then inform the listeners - if(gridletStarted > 0 || gridletFinished > 0){ - GridSim.notifyListeners(this.get_id(), AllocationAction.ITEM_COMPLETED, - true, grlsCompleted); - } + // If a gridlet has started execution or one has finished, + // then inform the listeners + if(itemsStarted > 0 || itemsFinished > 0) { + GridSim.notifyListeners(this.get_id(), + AllocationAction.SCHEDULE_CHANGED, true); + } - //---------------------------------------------------------------------- + //---------------------------------------------------------------------- + } + + /** + * This method starts gridlets that are in the queue and + * whose start time is smaller than the reference time and updates + * the availability accordingly + * @param currentTime the current simulation time + * @return the number of gridlets started + */ + protected int startQueuedGridlets(double currentTime) { + int gridletStarted = 0; + + // first checks the pivot first + if(pivot_ != null) { + if(pivot_.getStartTime() <= currentTime) { + shadowTime_ = Double.MAX_VALUE; + startGridlet(pivot_); + gridletStarted++; + queuedGridlets_.remove(pivot_); + pivot_ = null; + } } + + // Start the execution of Gridlets that are queued + Iterator<SSGridlet> iter = queuedGridlets_.iterator(); + while (iter.hasNext()) { + SSGridlet gridlet = iter.next(); + boolean success = startGridlet(gridlet); + + // if the job could not be scheduled immediately, then enqueue it + if(success) { + iter.remove(); + gridletStarted++; + } + else if (pivot_ == null) { // if there is not a pivot already + scheduleGridlet(gridlet); + } + } + + return gridletStarted; } /** Modified: branches/gridsim4.0-branch3/source/gridsim/turbo/MultipleEasyBackfillingQueues.java =================================================================== --- branches/gridsim4.0-branch3/source/gridsim/turbo/MultipleEasyBackfillingQueues.java 2008-02-12 05:46:26 UTC (rev 101) +++ branches/gridsim4.0-branch3/source/gridsim/turbo/MultipleEasyBackfillingQueues.java 2008-02-14 12:00:22 UTC (rev 102) @@ -13,10 +13,12 @@ import gridsim.GridSim; import gridsim.GridSimTags; import gridsim.Gridlet; +import gridsim.ParameterException; import gridsim.gui.AllocationAction; import java.util.ArrayList; import java.util.Calendar; +import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; @@ -37,17 +39,23 @@ public class MultipleEasyBackfillingQueues extends TAllocPolicy { // Queue of running Gridlets - protected LinkedList<SSGridlet> runningGridlets_; + protected LinkedList<MQGridlet> runningGridlets_; + + // Queue of Gridlets waiting in this queue + protected LinkedList<MQGridlet> queuedGridlets_; - // The queues used by this scheduler - protected ArrayList<EasyBackfillingQueue> queues_; - // The rating of one PE protected int ratingPE_; // the resource characteristics object to be used - protected TResourceCharacteristics resource_; + protected TResourceCharacteristics resource_; + // The availability profile + protected Profile profile_; + + // the number of queues in this scheduler + private int numQueues_; + // the last time when the schedule updated was called private double lastScheduleUpdate_; @@ -56,13 +64,14 @@ // a constant that denotes an unknown value private static final int UNKNOWN = -1; - + /** * Allocates a new <tt>EBParallelSpaceShared</tt> object * * @param resourceName the <tt>GridResource</tt> entity name that will * contain this allocation policy * @param entityName this object entity name + * @param numQueues The number of queues in the scheduler * @throws Exception This happens when one of the following scenarios occur: * <ul> * <li> Creating this entity before initialising GridSim package @@ -78,14 +87,30 @@ * String[], String[], String) */ public MultipleEasyBackfillingQueues(String resourceName, - String entityName) throws Exception{ + String entityName, int numQueues) throws Exception { super(resourceName, entityName); + // makes sure that the scheduler has at least one queue + if(numQueues <= 0) { + throw new ParameterException("Number of queues" + + "should be larger than 1"); + } + // initialises local data structure - runningGridlets_ = new LinkedList<SSGridlet>(); + runningGridlets_ = new LinkedList<MQGridlet>(); + queuedGridlets_ = new LinkedList<MQGridlet>(); + numQueues_ = numQueues; + profile_ = new Profile(); lastScheduleUpdate_ = 0.0D; ratingPE_ = 0; } + + + public boolean createQueue(int queueId, int numPE, QueuePredicate predicate) { + EasyBackFillingQueue queue = new EasyBackFillingQueue(queueId, numPE, predicate); + profile_.addQueue(queue); + return true; + } /** * Handles internal events that come to this entity. @@ -99,6 +124,51 @@ // of one PE assuming that the machines are homogeneous ratingPE_ = resource_.getMIPSRatingOfOnePE(); + if(numQueues_ > 1 && profile_.getNumberOfQueues() != numQueues_) { + System.out.println(super.get_name() + ".body(): The scheduler" + + " is expected to have " + numQueues_ + " queues. However," + + " only " + profile_.getNumberOfQueues() + " have been defined"); + return; + } + + //TODO: To validate the processing elements assigned to the queues + + // if the user has not specified the queues and the scheduler is + // expected to have only one queue, then creates the queue and + // includes it in the list. + if(profile_.getNumberOfQueues() == 0 && numQueues_ == 1) { + // creates the accept all predicate + QueuePredicate predicate = new QueuePredicate() { + public boolean match(SSGridlet gridlet) { + return true; + } + }; + + EasyBackFillingQueue queue = + new EasyBackFillingQueue(0, resource_.getNumPE(), predicate); + queue.idlePERanges_ = resource_.getFreePERanges().clone(); + profile_.addQueue(queue); + } + // assigns the PEs to the queues + else { + int allocPE = 0; + PERangeList freeRanges = resource_.getFreePERanges().clone(); + for(EasyBackFillingQueue queue : profile_.queues_.values()) { + allocPE += queue.initialNumPEs_; + + if(allocPE > resource_.getNumPE()) { + System.out.println(super.get_name() + ".body(): The scheduler" + + " cannot allocate PEs to all queues because there are not" + + " anough PEs"); + return; + } + + PERangeList selected = super.selectPERangeList(queue.initialNumPEs_, freeRanges); + queue.idlePERanges_ = selected; + freeRanges = PERangeList.difference(freeRanges, selected); + } + } + // a loop that is looking for internal events only Sim_event ev = new Sim_event(); while ( Sim_system.running() ) { @@ -160,12 +230,63 @@ } // Create a resource Gridlet - SSGridlet sgl = new SSGridlet(gridlet); + MQGridlet sgl = new MQGridlet(gridlet); //-------------- FOR DEBUGGING PURPOSES ONLY -------------- - GridSim.notifyListeners(this.get_id(), AllocationAction.ITEM_ARRIVED, true, sgl); + GridSim.notifyListeners(this.get_id(), + AllocationAction.ITEM_ARRIVED, true, sgl); + + //---------------------------------------------------------- + + // the id of the queue where the job can be scheduled + int queueId = profile_.getCorrespondingQueue(sgl); + + // if no queue can handle the gridlet, then reject it + if(queueId == UNKNOWN) { + String userName = GridSim.getEntityName( gridlet.getUserID() ); + System.out.println(super.get_name() + ".gridletSubmit(): " + + " Gridlet #" + gridlet.getGridletID() + " from " + + userName + " cannot be handled by any queue in this resource."); + try { + gridlet.setGridletStatus(Gridlet.FAILED); + } catch (Exception ex) { + System.out.println(super.get_name() + + ": Exception on submission of a Gridlet"); + } + super.sendFinishGridlet(gridlet); + return; + } + + sgl.setQueueID(queueId); + + // If there are no jobs in the queue list, then check if + // there are enough PEs to process the job immediately + boolean success = startGridlet(sgl); + // if the job could not be scheduled immediately, then enqueue it + if(!success) { + scheduleGridlet(sgl); + queuedGridlets_.add(sgl); + } + +// System.out.println("\nFree Ranges=" + profile_.getIdlePEsPerQueue()); +// System.out.println(profile_); + + //------------------ FOR DEBUGGING PURPOSES ONLY ---------------- + + // Notifies the listeners that a Gridlet has been either scheduled + // to run immediately or put in the waiting queue + GridSim.notifyListeners(this.get_id(), AllocationAction.ITEM_SCHEDULED, true, sgl); + + //--------------------------------------------------------------- + + // sends back an ack if required + if (ack == true) { + super.sendAck(GridSimTags.GRIDLET_SUBMIT_ACK, true, + gridlet.getGridletID(), gridlet.getUserID() + ); + } } /** @@ -239,8 +360,222 @@ } // -------------------- PRIVATE METHODS ---------------------------- + + /** + * + */ + private boolean startGridlet(MQGridlet sgl) { + + int reqPE = sgl.getNumPE(); + if(reqPE > resource_.getNumFreePE()) + return false; + + boolean success = false; // to test various conditions + int queueId = sgl.getQueueID(); + + // calculate the execution time of the Gridlet + double executionTime = + super.forecastExecutionTime(ratingPE_, sgl.getRemainingLength()); + // calculates how much ahead to look into the availability profile + double currentTime = GridSim.clock() ; + + // the Gridlet's expected finish time if it starts now + double finishTime = currentTime + executionTime; + + PERangeList ranges = + profile_.getImmediateAvailability(queueId, executionTime); + + // if the above method returns null, it means that there are not enough + // PEs to serve the reservation or Gridlet + if(ranges.getNumPE() >= reqPE) { + ranges = super.selectPERangeList(reqPE, ranges); + profile_.allocateImmediateRanges(queueId, finishTime, ranges); + success = true; + } + + // If the queue to which the gridlet is assigned does not have the + // required PEs, then try to borrow the additional PEs from other queues. + if(!success) { + PERangeList overallAvailPEs = + profile_.getImmediateAvailability(executionTime); + + // additional PEs required + int addRequired = reqPE - ranges.getNumPE(); + + PERangeList addRanges = + PERangeList.difference(overallAvailPEs, ranges); + + if(addRanges != null && addRanges.getNumPE() >= addRequired) { + // subtracts the ranges already obtained from the gridlet's queue + +// System.out.println("\nRanges to Add to queue " + queueId +" = " + +// addRanges + "\noverall = " + overallAvailPEs + +// "\n overall num available = " + overallAvailPEs.getNumPE() + +// "\n free PEs = " + resource_.getNumFreePE() + +// "\n free PEs profile = " + profile_.getNumFreePEs() + +// "\n PEs from the queue = " + ranges.getNumPE() + +// "\n req PEs = " + reqPE); + + // borrows the ranges from the queues and adds it into the + // specified queue + addRanges = super.selectPERangeList(addRequired, addRanges); + profile_.transferPEs(queueId, addRanges, currentTime, finishTime); + + // allocate the ranges to the job + ranges.addAll(addRanges); + profile_.allocateImmediateRanges(queueId, finishTime, ranges); + success = true; + } + } + + if(!success) + return false; + + // sets the PEs to busy at resource class. This is just to provide + // information to other classes that may query it + resource_.setPEsBusy(ranges); + + // add this Gridlet into execution list + runningGridlets_.add(sgl); + sgl.setStartTime(currentTime); + sgl.setFinishTime(finishTime); + + // change Gridlet status + sgl.setStatus(Gridlet.INEXEC); + + // Sets the list of ranges used by the gridlet + sgl.setPERangeList(ranges); + + // then send this event to itself to update the queues after + // this gridlet's completion time + super.sendInternalEvent(executionTime, UPDATE_SCHEDULE_TAG); + + //------------------ FOR DEBUGGING PURPOSES ONLY ---------------- + + // Notifies the listeners that a Gridlet has been either scheduled + // to run immediately or put in the waiting queue + GridSim.notifyListeners(this.get_id(), AllocationAction.ITEM_SCHEDULED, true, sgl); + + //--------------------------------------------------------------- + return true; + } + /** + * @param sgl the resource gridlet + */ + private boolean scheduleGridlet(MQGridlet sgl) { + int reqPE = sgl.getNumPE(); + int queueId = sgl.getQueueID(); + + EasyBackFillingQueue queue = profile_.getQueue(queueId); + + // if queue has a pivot already, then just add + // the job to the waiting queue + if(queue.pivot_ != null) { + return false; + } + + PERangeList ranges = null; + + // calculate the execution time of the Gridlet + double executionTime = + super.forecastExecutionTime(ratingPE_, sgl.getRemainingLength()); + + double startTime = -1; // keep the potential start time of the gridlet + double finishTime = -1; // store the gridlet's expected finish time + + // check whether there are PEs available over the time interval requested + Object[] availObjQueue = + profile_.checkPERangesAvailability(queueId, reqPE, executionTime); + + Object[] availObj = + profile_.checkPERangesAvailability(reqPE, executionTime); + + int anchor; + double startTimeQueue; + if (availObjQueue == null) + startTimeQueue = Double.MAX_VALUE; + else { + anchor = (Integer)availObjQueue[0]; + startTimeQueue=profile_.get(anchor).getTime(); + } + +// System.out.println(profile_); + + anchor = (Integer)availObj[0]; + double startTimeAll = profile_.get(anchor).getTime(); + + if(startTimeQueue <= startTimeAll) { + ranges = (PERangeList)availObjQueue[2]; + ranges = super.selectPERangeList(reqPE, ranges); + + int anchorIndex = (Integer)availObjQueue[0]; + int tailIndex = (Integer)availObjQueue[1]; + + startTime = startTimeQueue; + finishTime = startTime + executionTime; + + profile_.allocatePERanges(queueId, anchorIndex, tailIndex, + ranges, startTime, finishTime); + } + // If the queue to which the gridlet is assigned does not have the + // required PEs, then try to borrow the additional PEs from other queues. + else { + PERangeList addRanges = (PERangeList)availObj[2]; + + // the anchor index, the entry in the profile where the gridlet will be placed + int anchorIndex = (Integer)availObj[0]; + // insert index represents the position after which the entry + // corresponding to the gridlet's finish time will be placed + int tailIndex = (Integer)availObj[1]; + + // a pointer to the anchor entry + startTime = startTimeAll; + finishTime = startTime + executionTime; + + availObjQueue = profile_.checkPERangesAvailability(queueId, + startTime, executionTime); + + ranges = availObjQueue == null ? new PERangeList() : (PERangeList)availObjQueue[2]; + addRanges = availObjQueue == null ? addRanges : PERangeList.difference(addRanges, ranges); + addRanges = super.selectPERangeList(reqPE - ranges.getNumPE(), addRanges); + +// System.out.println("\nRanges to transfer to queue " + queueId +" = " + +// addRanges + " from " + startTime + " to " + finishTime); + + // borrows the ranges from the queues and adds it into the + // specified queue + profile_.transferPEs(queueId, addRanges, startTime, finishTime); + + // finally allocate the ranges to the gridlet + ranges.addAll(addRanges); + profile_.allocatePERanges(queueId, anchorIndex, tailIndex, + ranges, startTime, finishTime); + } + + queue.pivot_ = sgl; + + // Set the list of ranges used by the gridlet + sgl.setPERangeList(ranges); + + // change Gridlet status + sgl.setStatus(Gridlet.QUEUED); + sgl.setStartTime(startTime); + sgl.setFinishTime(finishTime); + + //------------------ FOR DEBUGGING PURPOSES ONLY ---------------- + + // Notifies the listeners that a Gridlet has been either scheduled + // to run immediately or put in the waiting queue + GridSim.notifyListeners(this.get_id(), AllocationAction.ITEM_SCHEDULED, true, sgl); + + //--------------------------------------------------------------- + + return true; + } + + /** * Process and event sent to this entity * @param ev the event to be handled */ @@ -273,39 +608,109 @@ * tries to backfill with jobs waiting in the queue. The method also * removes old entries from the availability profile. */ - private void updateSchedule(){ - + private void updateSchedule() { - } + int itemsFinished = 0; + double currentTime = GridSim.clock(); + int itemsStarted = 0; - static class EasyBackfillingQueue { + itemsFinished = finishRunningGridlets(currentTime); - int queueId_ = UNKNOWN; + // remove past entries from the availability profile + ProfileEntry currentStatus = profile_.removePastEntries(currentTime); + if(currentStatus != null) { + profile_.setCurrentStatus(currentStatus); + resource_.resetFreePERanges(currentStatus.getPERanges()); + } - // initial number of PEs assigned to this queue - int initialNumPE_ = 0; - - // Queue of Gridlets waiting in this queue - LinkedList<SSGridlet> queuedGridlets_; - - // the time when the first job in the waiting queue can - // start its execution - double shadowTime_ = ... [truncated message content] |
From: <mar...@us...> - 2008-02-12 05:46:22
|
Revision: 101 http://gridsim.svn.sourceforge.net/gridsim/?rev=101&view=rev Author: marcos_dias Date: 2008-02-11 21:46:26 -0800 (Mon, 11 Feb 2008) Log Message: ----------- A scheduler with multiple queues and easy backfilling is under development. Added Paths: ----------- branches/gridsim4.0-branch3/examples/examples/workload/parallel/TurboExampleMultiEBQueues01.java branches/gridsim4.0-branch3/source/gridsim/turbo/MultipleEasyBackfillingQueues.java Added: branches/gridsim4.0-branch3/examples/examples/workload/parallel/TurboExampleMultiEBQueues01.java =================================================================== --- branches/gridsim4.0-branch3/examples/examples/workload/parallel/TurboExampleMultiEBQueues01.java (rev 0) +++ branches/gridsim4.0-branch3/examples/examples/workload/parallel/TurboExampleMultiEBQueues01.java 2008-02-12 05:46:26 UTC (rev 101) @@ -0,0 +1,176 @@ + +package examples.workload.parallel; + +import gridsim.GridResource; +import gridsim.GridSim; +import gridsim.Machine; +import gridsim.MachineList; +import gridsim.turbo.TResourceCharacteristics; +import gridsim.util.Workload; + +import java.util.ArrayList; +import java.util.Calendar; +import java.util.LinkedList; +import java.util.Random; + + +/** + * Test Driver class for this example + */ +public class TurboExampleMultiEBQueues01 +{ + /** + * Creates main() to run this example + */ + public static void main(String[] args) + { + long startTime = System.currentTimeMillis(); + if(args.length == 0){ + System.out.println("Please provide the location of the workload file!"); + System.exit(1); + } + + try { + + ////////////////////////////////////////// + // Get the workload to be used The format should be: + // ASCII text, gzip or zip. + + String fileName = args[0]; + // /Users/marcosd/Documents/workspace/intergrid/workloads/sdsc_blue_2000_400.swf + + ArrayList<GridResource> resources = new ArrayList<GridResource>(); + + ////////////////////////////////////////// + // Initialize the GridSim package. It should be called + // before creating any entities. We can't run this example without + // initializing GridSim first. We will get run-time exception + // error. + + // number of grid user entities + any Workload entities. + int num_user = 1; + Calendar calendar = Calendar.getInstance(); + boolean trace_flag = false; // mean trace GridSim events + + // Initialize the GridSim package without any statistical + // functionalities. Hence, no GridSim_stat.txt file is created. + System.out.println("Initializing GridSim package"); + GridSim.init(num_user, calendar, trace_flag); + + ////////////////////////////////////////// + // Creates one or more GridResource entities + int totalResource = 1; // total number of Grid resources + int rating = 377; // rating of each PE in MIPS + int totalPE = 9; // total number of PEs for each Machine + int totalMachine = 128; // total number of Machines + int i = 0; + + String[] resArray = new String[totalResource]; + for (i = 0; i < totalResource; i++) { + String resName = "Res_" + i; + GridResource resource = createGridResource(resName, rating, totalMachine, totalPE); + resources.add(resource); + + // add a resource name into an array + resArray[i] = resName; + } + + ////////////////////////////////////////// + // Creates one Workload trace entity. + + int resID = 0; + Random r = new Random(); + resID = r.nextInt(totalResource); + Workload workload = new Workload("Load_1", fileName, resArray[resID], rating); + + ////////////////////////////////////////// + // Starts the simulation in debug mode + GridSim.startGridSimulation(true); + + // Start the simulation in normal mode +// GridSim.startGridSimulation(); + + ////////////////////////////////////////// + // Final step: Prints the Gridlets when simulation is over + long finishTime = System.currentTimeMillis(); + System.out.println("The simulation took " + (finishTime - startTime) + " milliseconds"); + + // prints the Gridlets inside a Workload entity + // workload.printGridletList(trace_flag); + } + catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * Creates one Grid resource. A Grid resource contains one or more + * Machines. Similarly, a Machine contains one or more PEs (Processing + * Elements or CPUs). + * @param name a Grid Resource name + * @param peRating rating of each PE + * @param totalMachine total number of Machines + * @param totalPE total number of PEs for each Machine + */ + private static GridResource createGridResource(String name, int peRating, + int totalMachine, int totalPE) + { + + ////////////////////////////////////////// + // Here are the steps needed to create a Grid resource: + // 1. We need to create an object of MachineList to store one or more + // Machines + MachineList mList = new MachineList(); + + for (int i = 0; i < totalMachine; i++) + { + ////////////////////////////////////////// + // 4. Create one Machine with its id and list of PEs or CPUs + mList.add( new Machine(i, totalPE, peRating) ); + } + + ////////////////////////////////////////// + // 5. Create a ResourceCharacteristics object that stores the + // properties of a Grid resource: architecture, OS, list of + // Machines, allocation policy: time- or space-shared, time zone + // and its price (G$/PE time unit). + String arch = "Sun Ultra"; // system architecture + String os = "Solaris"; // operating system + double time_zone = 0.0; // time zone this resource located + double cost = 3.0; // the cost of using this resource + + // this resource will use an aggressive backfilling policy (EASY) + TResourceCharacteristics resConfig = new TResourceCharacteristics( + arch, os, mList, TResourceCharacteristics.EB_PARALLEL_SPACE_SHARED, + time_zone, cost); + + ////////////////////////////////////////// + // 6. Finally, we need to create a GridResource object. + double baud_rate = 10000.0; // communication speed + long seed = 11L*13*17*19*23+1; + double peakLoad = 0.0; // the resource load during peak hour + double offPeakLoad = 0.0; // the resource load during off-peak hr + double holidayLoad = 0.0; // the resource load during holiday + + // incorporates weekends so the grid resource is on 7 days a week + LinkedList weekends = new LinkedList(); + weekends.add(new Integer(Calendar.SATURDAY)); + weekends.add(new Integer(Calendar.SUNDAY)); + + // incorporates holidays. However, no holidays are set in this example + LinkedList holidays = new LinkedList(); + GridResource gridRes = null; + try { + gridRes = new GridResource(name, baud_rate, seed, + resConfig, peakLoad, offPeakLoad, holidayLoad, weekends, + holidays); + } + catch (Exception e) { + e.printStackTrace(); + } + + System.out.println("Creates one Grid resource with name = " + name); + return gridRes; + } +} // end class + Added: branches/gridsim4.0-branch3/source/gridsim/turbo/MultipleEasyBackfillingQueues.java =================================================================== --- branches/gridsim4.0-branch3/source/gridsim/turbo/MultipleEasyBackfillingQueues.java (rev 0) +++ branches/gridsim4.0-branch3/source/gridsim/turbo/MultipleEasyBackfillingQueues.java 2008-02-12 05:46:26 UTC (rev 101) @@ -0,0 +1,322 @@ +/* + * Title: GridSim Toolkit + * Description: GridSim (Grid Simulation) Toolkit for Modelling and Simulation + * of Parallel and Distributed Systems such as Clusters and Grids + * Licence: GPL - http://www.gnu.org/copyleft/gpl.html + * + */ + +package gridsim.turbo; + +import eduni.simjava.Sim_event; +import eduni.simjava.Sim_system; +import gridsim.GridSim; +import gridsim.GridSimTags; +import gridsim.Gridlet; +import gridsim.gui.AllocationAction; + +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Iterator; +import java.util.LinkedList; + +/** + * Under development... + * + * @author Marcos Dias de Assuncao + * @since GridSim Turbo Alpha 0.1 + * + * @see gridsim.GridSim + * @see gridsim.ResourceCharacteristics + * @see gridsim.turbo.TAllocPolicy + * @see gridsim.turbo.CBParallelSpaceShared + * @see gridsim.turbo.PERange + * @see gridsim.turbo.PERangeList + */ + +public class MultipleEasyBackfillingQueues extends TAllocPolicy { + + // Queue of running Gridlets + protected LinkedList<SSGridlet> runningGridlets_; + + // The queues used by this scheduler + protected ArrayList<EasyBackfillingQueue> queues_; + + // The rating of one PE + protected int ratingPE_; + + // the resource characteristics object to be used + protected TResourceCharacteristics resource_; + + // the last time when the schedule updated was called + private double lastScheduleUpdate_; + + // a tag to indicate that a gridlet has finished + private static final int UPDATE_SCHEDULE_TAG = 10; + + // a constant that denotes an unknown value + private static final int UNKNOWN = -1; + + /** + * Allocates a new <tt>EBParallelSpaceShared</tt> object + * + * @param resourceName the <tt>GridResource</tt> entity name that will + * contain this allocation policy + * @param entityName this object entity name + * @throws Exception This happens when one of the following scenarios occur: + * <ul> + * <li> Creating this entity before initialising GridSim package + * <li> The entity name is <tt>null</tt> or empty + * <li> The entity has <tt>zero</tt> number of PEs (Processing + * Elements). <br> + * No PEs, which means that the Gridlets cannot be processed. + * A GridResource must contain one or more Machines. + * A Machine must contain one or more PEs. + * </ul> + * + * @see gridsim.GridSim#init(int, Calendar, boolean, + * String[], String[], String) + */ + public MultipleEasyBackfillingQueues(String resourceName, + String entityName) throws Exception{ + super(resourceName, entityName); + + // initialises local data structure + runningGridlets_ = new LinkedList<SSGridlet>(); + lastScheduleUpdate_ = 0.0D; + ratingPE_ = 0; + } + + /** + * Handles internal events that come to this entity. + */ + public void body() { + + // get the resource characteristics object to be used + resource_ = getTResourceCharacteristics(); + + // Gets the information on number of PEs and rating + // of one PE assuming that the machines are homogeneous + ratingPE_ = resource_.getMIPSRatingOfOnePE(); + + // a loop that is looking for internal events only + Sim_event ev = new Sim_event(); + while ( Sim_system.running() ) { + super.sim_get_next(ev); + + // if the simulation finishes then exit the loop + if (ev.get_tag() == GridSimTags.END_OF_SIMULATION || + super.isEndSimulation() == true) { + break; + } + + processEvent(ev); + } + + // CHECK for ANY INTERNAL EVENTS WAITING TO BE PROCESSED + while (super.sim_waiting() > 0) { + // wait for event and ignore since it is likely to be related to + // internal event scheduled to update Gridlets processing + super.sim_get_next(ev); + System.out.println(super.get_name() + ".body(): ignore internal events"); + } + + // reset variables to default values + runningGridlets_.clear(); + lastScheduleUpdate_ = 0.0D; + ratingPE_ = 0; + resource_.resetFreePERanges(); + } + + /** + * Schedules/adds to the queue a new <tt>Gridlet</tt> received by the + * <tt>GridResource</tt> entity. + * @param gridlet a Gridlet object to be executed + * @param ack an acknowledgement, i.e. <tt>true</tt> if the + * user wants to know whether this operation is successful + * or not, <tt>false</tt> otherwise. + */ + public void gridletSubmit(Gridlet gridlet, boolean ack) { + int reqPE = gridlet.getNumPE(); + + try{ + // reject the Gridlet if it requires more PEs than the resource + // is able to provide + if(reqPE > super.totalPE_){ + String userName = GridSim.getEntityName( gridlet.getUserID() ); + System.out.println(super.get_name() + ".gridletSubmit(): " + + " Gridlet #" + gridlet.getGridletID() + " from " + + userName + " user requires " + gridlet.getNumPE() + " PEs."); + System.out.println("--> The resource has only " + + super.totalPE_ + " PEs."); + gridlet.setGridletStatus(Gridlet.FAILED); + super.sendFinishGridlet(gridlet); + return; + } + } + catch(Exception ex){ + System.out.println(super.get_name() + + ": Exception on submission of a Gridlet"); + } + + // Create a resource Gridlet + SSGridlet sgl = new SSGridlet(gridlet); + + //-------------- FOR DEBUGGING PURPOSES ONLY -------------- + + GridSim.notifyListeners(this.get_id(), AllocationAction.ITEM_ARRIVED, true, sgl); + + } + + /** + * Finds the status of a specified <tt>Gridlet</tt>. + * @param gridletId a Gridlet ID + * @param userId the user or owner's ID of this Gridlet + * @return the Gridlet status or <tt>-1</tt> if not found + * @see gridsim.Gridlet + * @pre gridletId > 0 + * @pre userId > 0 + * @post $none + */ + public int gridletStatus(int gridletId,int userId){ + return UNKNOWN; + } + + /** + * Cancels a Gridlet running or in the waiting queue.<br> + * <b>NOTE: Not implemented YET.</b> + * @param gridletId a Gridlet ID + * @param userId the user or owner's ID of this Gridlet + * @pre gridletId > 0 + * @pre userId > 0 + */ + public void gridletCancel(int gridletId, int userId) { + System.out.println(super.get_name() + + ".gridletCancel(): not supported at the moment."); + } + + /** + * Pauses a <tt>Gridlet</tt> only if it is currently executing. + * <b>NOTE: This operation is not supported. </b> + * @param gridletId a Gridlet ID + * @param userId the user or owner's ID of this Gridlet + * @param ack an acknowledgement, i.e. <tt>true</tt> if wanted to know + * whether this operation is success or not, <tt>false</tt> + * otherwise. + */ + public void gridletPause(int gridletId, int userId, boolean ack){ + System.out.println(super.get_name() + + ".gridletMove(): not supported at the moment."); + } + + /** + * Moves a Gridlet from this GridResource entity to a different one. + * <b>NOTE: This operation is not supported. </b> + * @param gridletId a Gridlet ID + * @param userId the user or owner's ID of this Gridlet + * @param destId a new destination GridResource ID for this Gridlet + * @param ack an acknowledgement, i.e. <tt>true</tt> if wanted to know + * whether this operation is success or not, <tt>false</tt> + * otherwise + */ + public void gridletMove(int gridletId, int userId, int destId, boolean ack){ + System.out.println(super.get_name() + + ".gridletPause(): not supported at the moment."); + } + + /** + * Resumes a Gridlet only in the paused list. + * <b>NOTE: This operation is not supported. </b> + * @param gridletId a Gridlet ID + * @param userId the user or owner's ID of this Gridlet + * @param ack an acknowledgement, i.e. <tt>true</tt> if wanted to know + * whether this operation is success or not, <tt>false</tt> + * otherwise + */ + public void gridletResume(int gridletId, int userId, boolean ack){ + System.out.println(super.get_name() + + ".gridletResume(): not supported at the moment."); + } + + // -------------------- PRIVATE METHODS ---------------------------- + + /** + * Process and event sent to this entity + * @param ev the event to be handled + */ + private void processEvent(Sim_event ev) { + + // handle an internal event + double currentTime = GridSim.clock(); + + // Internal Event if the event source is this entity + if(ev.get_src() == myId_) { + // time to update the schedule, finish gridlets, + // finish reservations, start reservations and start gridlets + if (ev.get_tag() == UPDATE_SCHEDULE_TAG) { + if(currentTime > lastScheduleUpdate_) { + updateSchedule(); + } + lastScheduleUpdate_ = currentTime; + } + else + processOtherEvent(ev); + } + else + processOtherEvent(ev); + } + + /** + * This method is called to update the schedule. It removes completed + * gridlets and return them to the users and verifies whether the first gridlet + * in the waiting queue can be started. If it cannot be started, them + * tries to backfill with jobs waiting in the queue. The method also + * removes old entries from the availability profile. + */ + private void updateSchedule(){ + + + } + + static class EasyBackfillingQueue { + + int queueId_ = UNKNOWN; + + // initial number of PEs assigned to this queue + int initialNumPE_ = 0; + + // Queue of Gridlets waiting in this queue + LinkedList<SSGridlet> queuedGridlets_; + + // the time when the first job in the waiting queue can + // start its execution + double shadowTime_ = Double.MAX_VALUE; + + // the list of PEs left unused when the first job in the waiting + // queue is scheduled + PERangeList extraPEs_ = null; + + // a list containing the availability of PEs + AvailabilityProfile availProfile_; + + // The list of PEs available at the current simulation time + PERangeList freePERanges_ = null; + + + + } + + /** + * Updates the Gridlet's properties, such as status once a + * Gridlet is considered finished. + * @param sgl a SSGridlet object + * @param status the Gridlet status + */ + private void gridletFinish(SSGridlet sgl, int status) { + // the order is important! Set the status first then finalise + // due to timing issues in SSGridlet class + sgl.setStatus(status); + sgl.finalizeGridlet(); + super.sendFinishGridlet( sgl.getGridlet() ); + } +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mar...@us...> - 2008-02-12 05:42:46
|
Revision: 100 http://gridsim.svn.sourceforge.net/gridsim/?rev=100&view=rev Author: marcos_dias Date: 2008-02-11 21:42:41 -0800 (Mon, 11 Feb 2008) Log Message: ----------- A scheduler with multiple queues and easy backfilling is under development. Modified Paths: -------------- branches/gridsim4.0-branch3/source/gridsim/GridResource.java branches/gridsim4.0-branch3/source/gridsim/turbo/ARTPolicy.java branches/gridsim4.0-branch3/source/gridsim/turbo/CBParallelSpaceShared.java branches/gridsim4.0-branch3/source/gridsim/turbo/EBParallelSpaceShared.java branches/gridsim4.0-branch3/source/gridsim/turbo/TResourceCharacteristics.java Modified: branches/gridsim4.0-branch3/source/gridsim/GridResource.java =================================================================== --- branches/gridsim4.0-branch3/source/gridsim/GridResource.java 2008-02-11 23:42:40 UTC (rev 99) +++ branches/gridsim4.0-branch3/source/gridsim/GridResource.java 2008-02-12 05:42:41 UTC (rev 100) @@ -13,6 +13,7 @@ import gridsim.turbo.ARParallelSpaceShared; import gridsim.turbo.EBParallelSpaceShared; import gridsim.turbo.CBParallelSpaceShared; +import gridsim.turbo.MultipleEasyBackfillingQueues; import gridsim.turbo.TAllocPolicy; import gridsim.turbo.TResourceCharacteristics; import gridsim.index.*; @@ -646,6 +647,11 @@ policy_ = new ARParallelSpaceShared(super.get_name(), "ARParallelSpaceShared"); break; + case TResourceCharacteristics.MULTIPLE_EASY_BACKFILLING_QUEUES: + policy_ = new MultipleEasyBackfillingQueues(super.get_name(), + "MultipleEasyBackfillingQueues"); + break; + default: throw new Exception(super.get_name()+" : Error - supports"+ " only TimeShared or SpaceShared policy."); Modified: branches/gridsim4.0-branch3/source/gridsim/turbo/ARTPolicy.java =================================================================== --- branches/gridsim4.0-branch3/source/gridsim/turbo/ARTPolicy.java 2008-02-11 23:42:40 UTC (rev 99) +++ branches/gridsim4.0-branch3/source/gridsim/turbo/ARTPolicy.java 2008-02-12 05:42:41 UTC (rev 100) @@ -27,7 +27,7 @@ public interface ARTPolicy { /** - * An abstract method that handles a new advanced reservation request. + * A method that handles a new advanced reservation request. * @param message the advance reservation message received requesting * the reservation * @pre message != null @@ -35,7 +35,7 @@ void handleCreateReservation(ARMessage message); /** - * An abstract method that handles a modify reservation request. + * A method that handles a modify reservation request. * @param message the advance reservation message received requesting * the change * @pre message != null @@ -43,7 +43,7 @@ void handleModifyReservation(ARMessage message); /** - * An abstract method that handles a cancel reservation request. + * A method that handles a cancel reservation request. * @param message the advance reservation message received requesting * the cancellation * @pre message != null @@ -51,21 +51,21 @@ void handleCancelReservation(ARMessage message); /** - * An abstract method that handles a commit reservation request. + * A method that handles a commit reservation request. * @param message the advance reservation message received * @pre message != null */ void handleCommitReservation(ARMessage message); /** - * An abstract method that handles a query reservation request. + * A method that handles a query reservation request. * @param message the advance reservation message received * @pre message != null */ void handleQueryReservation(ARMessage message); /** - * An abstract method that handles a query free time request. + * A method that handles a query free time request. * @param message the advance reservation message received * @pre message != null */ Modified: branches/gridsim4.0-branch3/source/gridsim/turbo/CBParallelSpaceShared.java =================================================================== --- branches/gridsim4.0-branch3/source/gridsim/turbo/CBParallelSpaceShared.java 2008-02-11 23:42:40 UTC (rev 99) +++ branches/gridsim4.0-branch3/source/gridsim/turbo/CBParallelSpaceShared.java 2008-02-12 05:42:41 UTC (rev 100) @@ -1076,7 +1076,6 @@ break; } else { - // Sep. 29, 2007 - Changed by Marcos // if the finish time is equals to the entry time, so there // is no need to check the intersection if(nextEntry.getTime() < potFinishTime) { Modified: branches/gridsim4.0-branch3/source/gridsim/turbo/EBParallelSpaceShared.java =================================================================== --- branches/gridsim4.0-branch3/source/gridsim/turbo/EBParallelSpaceShared.java 2008-02-11 23:42:40 UTC (rev 99) +++ branches/gridsim4.0-branch3/source/gridsim/turbo/EBParallelSpaceShared.java 2008-02-12 05:42:41 UTC (rev 100) @@ -21,8 +21,8 @@ /** * <tt>EBParallelSpaceShared</tt> class is an allocation policy for - * <tt>GridResource</tt> that behaves exactly like First Come First - * Served (FCFS) with aggressive backfilling (EASY). The policy is based + * <tt>GridResource</tt> that implements First Come First Served (FCFS) + * with aggressive backfilling (EASY). The policy is based * on the conservative backfilling algorithm described in the * following papers: * <p> @@ -41,11 +41,10 @@ * This policy maintains an availability profile. The availability * profile contains information about the ranges of processing elements * (PEs) that will be released when the running jobs complete. - * In addition, it maintains the list of extra nodes, that is, the nodes + * In addition, the policy maintains the list of extra nodes, that is, the nodes * that are left when the first job of the waiting queue is scheduled. * We recommend you to read the papers mentioned above if you want to * understand this policy. - * * <p> * <b>LIMITATIONS:</b><br> * <ul> @@ -53,10 +52,11 @@ * homogeneous. * <li> Local load is not considered. If you would like to * simulate this, you have to model the local load as gridlets. - * It is more precise and faster. + * It is more precise and faster. To do so, please check + * {@link Lublin99Workload}. * <li> Gridlets cannot be paused nor migrated. This could be * easily done, but due to time constraints, I could not - * implement these. + * implement these features. * </ul> * * @author Marcos Dias de Assuncao @@ -64,7 +64,7 @@ * * @see gridsim.GridSim * @see gridsim.ResourceCharacteristics - * @see gridsim.AllocPolicy + * @see gridsim.turbo.TAllocPolicy * @see gridsim.turbo.CBParallelSpaceShared * @see gridsim.turbo.PERange * @see gridsim.turbo.PERangeList @@ -73,19 +73,19 @@ public class EBParallelSpaceShared extends TAllocPolicy { // Queue of waiting Gridlets - private LinkedList<SSGridlet> queuedGridlets_; + protected LinkedList<SSGridlet> queuedGridlets_; // Queue of running Gridlets - private LinkedList<SSGridlet> runningGridlets_; + protected LinkedList<SSGridlet> runningGridlets_; // The rating of one PE - private int ratingPE_; + protected int ratingPE_; // a list containing the availability of PEs - private AvailabilityProfile availProfile_; + protected AvailabilityProfile availProfile_; // the resource characteristics object to be used - private TResourceCharacteristics resource_; + protected TResourceCharacteristics resource_; // the last time when the schedule updated was called private double lastScheduleUpdate_; @@ -101,7 +101,7 @@ private PERangeList allPEs_; // a tag to indicate that a gridlet has finished - private static final int GRIDLET_FINISHED = 10; + private static final int UPDATE_SCHEDULE_TAG = 10; /** * Allocates a new <tt>EBParallelSpaceShared</tt> object @@ -162,19 +162,8 @@ super.isEndSimulation() == true) { break; } - - // Internal Event if the event source is this entity - if (ev.get_src() == super.myId_ && - ev.get_tag() == GRIDLET_FINISHED) { - double currentTime = GridSim.clock(); - if(currentTime > lastScheduleUpdate_) { - updateSchedule(); - } - lastScheduleUpdate_ = currentTime; - } - else { - processOtherEvent(ev); - } + + processEvent(ev); } // CHECK for ANY INTERNAL EVENTS WAITING TO BE PROCESSED @@ -185,11 +174,18 @@ System.out.println(super.get_name() + ".body(): ignore internal events"); } + // reset variables to default values queuedGridlets_.clear(); runningGridlets_.clear(); availProfile_.clear(); + lastScheduleUpdate_ = 0.0D; + shadowTime_ = Double.MAX_VALUE; + ratingPE_ = 0; + resource_.resetFreePERanges(); + extraPEs_ = resource_.getFreePERanges().clone(); + allPEs_ = extraPEs_.clone(); } - + /** * Schedules/adds to the queue a new <tt>Gridlet</tt> received by the * <tt>GridResource</tt> entity. @@ -242,7 +238,8 @@ // Notifies the listeners that a Gridlet has been either scheduled // to run immediately or put in the waiting queue - GridSim.notifyListeners(this.get_id(), AllocationAction.ITEM_SCHEDULED, true, sgl); + GridSim.notifyListeners(this.get_id(), + AllocationAction.ITEM_SCHEDULED, true, sgl); //--------------------------------------------------------------- } @@ -350,20 +347,48 @@ // -------------------- PRIVATE METHODS ---------------------------- + /** + * Process and event sent to this entity + * @param ev the event to be handled + */ + private void processEvent(Sim_event ev) { + + // handle an internal event + double currentTime = GridSim.clock(); + + // Internal Event if the event source is this entity + if(ev.get_src() == myId_) { + // time to update the schedule, finish gridlets, + // finish reservations, start reservations and start gridlets + if (ev.get_tag() == UPDATE_SCHEDULE_TAG) { + if(currentTime > lastScheduleUpdate_) { + updateSchedule(); + } + lastScheduleUpdate_ = currentTime; + } + else + processOtherEvent(ev); + } + else + processOtherEvent(ev); + } + /** * Allocates a Gridlet into free PEs, sets the Gridlet status to INEXEC, * updates the availability profile and the ranges currently available. * @param sgl a SSGridlet object - * @return <tt>true</tt> if one of the two following conditions holds true: + * @return <tt>true</tt> if one of the two following conditions + * holds true: * <ul> * <li> There are currently free PE to process the Gridlet and the Gridlet - * WILL NOT execute beyond the <b>shadow time</b>. That is, it WILL NOT not - * delay the first gridlet in the waiting queue. + * WILL NOT execute beyond the <b>shadow time</b>. That is, it + * WILL NOT delay the first gridlet in the waiting queue. * <li> There are currently free PE to process the Gridlet, the Gridlet - * WILL execute beyond the <b>shadow time</b> but WILL NOT use more PEs - * than those left as <b>extra nodes<b>. That is, nodes remaining idle when - * the first gridlet in the waiting queue starts. - * </ul><br> + * WILL execute beyond the <b>shadow time</b> but WILL NOT use more + * PEs than those left as <b>extra nodes<b>. That is, nodes remaining + * idle when the first gridlet in the waiting queue starts. + * </ul> + * <br> * The method returns <tt>false</tt> otherwise. * @pre sgl != null * @post $none @@ -399,7 +424,6 @@ selected = super.selectPERangeList(reqPE, resource_.getFreePERanges()); } else { - // a pointer to the last entry analysed AvailabilityProfileEntry tailEntry = null; @@ -475,7 +499,7 @@ // then send this event to itself to update the queues after // this gridlet's completion time - super.sendInternalEvent(executionTime, GRIDLET_FINISHED); + super.sendInternalEvent(executionTime, UPDATE_SCHEDULE_TAG); return true; } Modified: branches/gridsim4.0-branch3/source/gridsim/turbo/TResourceCharacteristics.java =================================================================== --- branches/gridsim4.0-branch3/source/gridsim/turbo/TResourceCharacteristics.java 2008-02-11 23:42:40 UTC (rev 99) +++ branches/gridsim4.0-branch3/source/gridsim/turbo/TResourceCharacteristics.java 2008-02-12 05:42:41 UTC (rev 100) @@ -50,6 +50,10 @@ /** Parallel spaced-shared system using First Come First Serve (FCFS) * algorithm, conservative backfilling and supporting advance reservations */ public static final int AR_PARALLEL_SPACE_SHARED = 12; + + /** Parallel spaced-shared system using multiple + * queues and Easy Backfilling */ + public static final int MULTIPLE_EASY_BACKFILLING_QUEUES = 13; /** * Allocates a new {@link TResourceCharacteristics} object. This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mar...@us...> - 2008-02-11 23:42:34
|
Revision: 99 http://gridsim.svn.sourceforge.net/gridsim/?rev=99&view=rev Author: marcos_dias Date: 2008-02-11 15:42:40 -0800 (Mon, 11 Feb 2008) Log Message: ----------- This update contains: + A simpler advance reservation policy. Now the advance reservation policy extends the normal conservative backfilling so the repeating methods were eliminated. The advance reservation policy has become smaller and simpler. + Small corrections in the comments and java documentation. Modified Paths: -------------- branches/gridsim4.0-branch3/examples/examples/workload/ar/TurboARExample01.java branches/gridsim4.0-branch3/source/gridsim/turbo/ARParallelSpaceShared.java branches/gridsim4.0-branch3/source/gridsim/turbo/ARTGridResource.java branches/gridsim4.0-branch3/source/gridsim/turbo/ARTPolicy.java branches/gridsim4.0-branch3/source/gridsim/turbo/AvailabilityProfile.java branches/gridsim4.0-branch3/source/gridsim/turbo/CBParallelSpaceShared.java branches/gridsim4.0-branch3/source/gridsim/turbo/Lublin99Workload.java branches/gridsim4.0-branch3/source/gridsim/turbo/TResourceCharacteristics.java Modified: branches/gridsim4.0-branch3/examples/examples/workload/ar/TurboARExample01.java =================================================================== --- branches/gridsim4.0-branch3/examples/examples/workload/ar/TurboARExample01.java 2008-02-11 06:09:53 UTC (rev 98) +++ branches/gridsim4.0-branch3/examples/examples/workload/ar/TurboARExample01.java 2008-02-11 23:42:40 UTC (rev 99) @@ -89,10 +89,10 @@ ////////////////////////////////////////// // Starts the simulation in debug mode -// GridSim.startGridSimulation(true); + GridSim.startGridSimulation(true); // Start the simulation in normal mode - GridSim.startGridSimulation(); +// GridSim.startGridSimulation(); ////////////////////////////////////////// // Final step: Prints the Gridlets when simulation is over Modified: branches/gridsim4.0-branch3/source/gridsim/turbo/ARParallelSpaceShared.java =================================================================== --- branches/gridsim4.0-branch3/source/gridsim/turbo/ARParallelSpaceShared.java 2008-02-11 06:09:53 UTC (rev 98) +++ branches/gridsim4.0-branch3/source/gridsim/turbo/ARParallelSpaceShared.java 2008-02-11 23:42:40 UTC (rev 99) @@ -8,14 +8,14 @@ package gridsim.turbo; import eduni.simjava.Sim_event; -import eduni.simjava.Sim_system; import gridsim.GridSim; import gridsim.GridSimTags; import gridsim.Gridlet; +import gridsim.IO_data; import gridsim.gui.AllocationAction; import java.util.Calendar; -import java.util.Collections; +import java.util.Collection; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.LinkedList; @@ -39,43 +39,15 @@ * Systems, 12:(6), pp. 529-543, 2001. * </ul> * - * This policy maintains an availability profile. The availability - * profile contains information about the ranges of processing elements - * (PEs) available at future times. The size of the availability profile - * is proportional to the number of gridlets in the running and waiting - * queues. To illustrate how the availability profile works, imagine that - * the simulation has just started and the availability profile is empty. - * The grid resource has 500 PEs. Therefore, the range of PEs available - * is [0..499]. At simulation time 100, a gridlet (GA) arrives requiring - * 100 PEs. The Gridlet is expected to execute for 500 seconds. As the - * resource is not executing any gridlets, GA is accepted and given - * the range [0..99]. The ranges of current PEs available is updated - * to [100..499] and one entry is inserted at the profile to indicate - * that the range [0..499] will be available again at simulation time - * 600 seconds. Now suppose that a Gridlet (GB) arrives at simulation - * time 200 requiring 400 PEs and expected to run for 500 seconds. - * The policy checks the ranges currently available and find [100..499]. - * It then scans the availability profile and analyses all the entries whose - * time is smaller than the expected termination time of GB. The policy - * finds the intersections of PEs amongst the entries, process similar - * to finding intersections of sequences. While scanning the profile, - * the policy finds the entry at 600 seconds. The intersection of - * [100..499] and [0..499] is [100..499]. That means that there are - * enough resources to schedule GB and then GB starts the execution. - * The policy then updates the ranges of current PEs to []. - * After that, the policy updates the entry at 600 seconds to [0..99] - * and inserts an entry with time 700 seconds with the range [0..499]. - * Now consider that a third Gridlet (GC) arrives at simulation time 250 - * requiring 500 PEs and expected to run for 100 seconds. As the - * current ranges available is [], the policy scans the profile until - * it finds an entry with enough PEs available. In this case, the entry - * found is at 700 seconds. The policy would continue scanning the profile - * finding the intersection with other ranges if there were more. In this - * case, 700 seconds is the last entry in the profile. The Gridlet is - * then set to start execution at time 700 seconds. The policy then - * updates the entry at time 700 seconds to [] and creates an entry - * at 800 with [0..499]. GC is then put in the waiting queue. - * <p> + * This policy extends <tt>CBParallelSpaceShared</tt> so also maintains + * an availability profile. The main difference is that in many instances + * an advance reservation will require two entries in the availability profile, + * one to mark its start time and another to delimit its finish time. For more + * details on the availability profile see {@link CBParallelSpaceShared}. + * Another important difference is that when a Gridlet is cancelled, the + * advance reservations are not removed from the availability profile and + * therefore are not moved forwards in the queue. + * <br> * This scheduler supports parallel jobs and some AR functionalities, * such as: * <ul> @@ -84,18 +56,20 @@ * <li> commit a reservation * <li> process a reservation status query * <li> list free time over a certain period of time + * <li> provide availability information when an advance + * reservation is cancelled. * </ul> * <p> * <b>LIMITATIONS:</b><br> * <ul> * <li> The list of machines comprising this resource must * be homogeneous. - * <li> Local load is not considered. If you would like to - * simulate this, you have to model the local load as - * gridlets. It is more precise and faster. + * <li> Local load is not considered. If you would like to simulate this, + * you have to model the local load as gridlets. It is more precise + * and faster. To do so, please check {@link Lublin99Workload}. * <li> Gridlets cannot be paused nor migrated. This could be * easily done, but due to time constraints, I could not - * implement these. + * implement these features. * </ul> * * @author Marcos Dias de Assuncao @@ -109,54 +83,22 @@ * @see CBParallelSpaceShared */ -public class ARParallelSpaceShared extends ARTPolicy { +public class ARParallelSpaceShared extends + CBParallelSpaceShared implements ARTPolicy { - // Queue of waiting Gridlets - private LinkedList<SSGridlet> queuedGridlets_; - - // Queue of running Gridlets - private LinkedList<SSGridlet> runningGridlets_; - - // Comparator to order gridlets by start time - private OrderGridletByStartTime orderStartTime_; - // a new reservation table private LinkedHashMap<Integer, SSReservation> reservTable_; // a table that contains expired reservations private LinkedHashMap<Integer, SSReservation> expiryTable_; - // The rating of one PE - private int ratingPE_; - - // a list containing the availability of PEs - private AvailabilityProfile availProfile_; - - // the resource characteristics object to be used - private TResourceCharacteristics resource_; - // default booking/reservation commit period private int commitPeriod_; // internal event tags used by this gridlet // a tag to denote expiry time private final int EXPIRY_TIME = 12; - - // a tag to indicate that a reservation has to start - private final int START_RESERVATION = 13; - - // a tag to indicate that a reservation has to finish - private final int FINISH_RESERVATION = 14; - - // a tag to indicate that a gridlet has finished - private static final int GRIDLET_FINISHED = 10; - - // Some variables to prevent the policy from iterating - // the lists unnecessarily - // the last time when the schedule update was called - private double lastScheduleUpdate_; - // last time the expiration of reservations was checked private double lastCheckExpiryTime_; @@ -243,42 +185,10 @@ * Handles internal events that are received by this entity. */ public void body() { - - // get the resource characteristics object to be used - resource_ = getTResourceCharacteristics(); - - // Gets the information on number of PEs and rating - // of one PE assuming that the machines are homogeneous - ratingPE_ = resource_.getMIPSRatingOfOnePE(); - - // a loop that is looking for internal events only - // This loop does not stop when the policy receives an - // end of simulation event because it needs to handle - // all the internal events before it finishes its - // execution. This is important particularly for the - // graphical user interface to show the completion of - // advance reservations - Sim_event ev = new Sim_event(); - while ( Sim_system.running() ) { - super.sim_get_next(ev); - processEvent(ev); - } - - // CHECK for ANY INTERNAL EVENTS WAITING TO BE PROCESSED - while (super.sim_waiting() > 0) { - // wait for event and ignore since it is likely to be related to - // internal event scheduled to update Gridlets processing - super.sim_get_next(ev); - System.out.println(super.get_name() + - ".body(): ignore internal events"); - } - - queuedGridlets_.clear(); - runningGridlets_.clear(); - orderStartTime_ = null; + super.body(); reservTable_.clear(); - expiryTable_.clear(); - availProfile_.clear(); + expiryTable_.clear(); + lastCheckExpiryTime_ = 0.0D; } //---------------- RESERVATION RELATED PUBLIC METHODS --------------------- @@ -323,7 +233,7 @@ reservation.setStatus(Reservation.STATUS_FAILED); response.setErrorCode(ARMessage.EC_OPERATION_FAILURE); - super.sendARMessage(response); + sendARMessage(response); return; } @@ -436,7 +346,8 @@ // committed and sends an internal event to start the reservation if(currentTime == startTime) { sRes.setStatus(Reservation.STATUS_COMMITTED); - super.sendInternalEvent(GridSimTags.SCHEDULE_NOW, START_RESERVATION); + super.sendInternalEvent(GridSimTags.SCHEDULE_NOW, + CBParallelSpaceShared.UPDATE_SCHEDULE_TAG); } else { sRes.setStatus(Reservation.STATUS_NOT_COMMITTED); @@ -447,7 +358,7 @@ // add the reservation into the reservation table and sends the // response message to the requester reservTable_.put(new Integer(sRes.getID()), sRes); - super.sendARMessage(response); + sendARMessage(response); // then send this into itself to check for expired reservations super.sendInternalEvent(expTime - currentTime, @@ -469,7 +380,7 @@ reservation.setStatus(Reservation.STATUS_FAILED); reservation.setReservationOptions(availability); response.setErrorCode(ARMessage.EC_OPERATION_FAILURE_BUT_OPTIONS); - super.sendARMessage(response); + sendARMessage(response); } } @@ -515,7 +426,7 @@ // an error message back to the requester if(!success) { response.setErrorCode(ARMessage.EC_OPERATION_FAILURE); - super.sendARMessage(response); + sendARMessage(response); return; } @@ -550,7 +461,7 @@ //---------------------------------------------------------------------- // send the response message back to the requester - super.sendARMessage(response); + sendARMessage(response); } /** @@ -606,7 +517,7 @@ // sends the message back to the requester if(!success) { response.setErrorCode(ARMessage.EC_OPERATION_FAILURE); - super.sendARMessage(response); + sendARMessage(response); return; } @@ -616,11 +527,11 @@ // then send this into itself to start the reservation super.sendInternalEvent(sRes.getStartTime() - currentTime, - START_RESERVATION); + CBParallelSpaceShared.UPDATE_SCHEDULE_TAG); } // sends the response message with no error - super.sendARMessage(response); + sendARMessage(response); //-------------- FOR DEBUGGING PURPOSES ONLY -------------- @@ -663,7 +574,7 @@ response.getReservation().setReservationOptions(availability); // Sends the response back to the user - super.sendARMessage(response); + sendARMessage(response); } /** @@ -690,7 +601,7 @@ // Just sends the message because the reply has a reference to // the reservation object, which contains the status of the reservation - super.sendARMessage(response); + sendARMessage(response); } //---------------- GRIDLET RELATED PUBLIC METHODS ------------------------ @@ -704,247 +615,42 @@ */ public void gridletSubmit(Gridlet gridlet, boolean ack) { if(!gridlet.hasReserved()) { - handleNonReservationGridlet(gridlet, ack); + super.gridletSubmit(gridlet, ack); } else { handleReservationGridlet(gridlet, ack); } } - /** - * Finds the status of a specified <tt>Gridlet</tt>. - * @param gridletId a Gridlet ID - * @param userId the user or owner's ID of this Gridlet - * @return the Gridlet status or <tt>-1</tt> if not found - * @see gridsim.Gridlet - * @pre gridletId > 0 - * @pre userId > 0 - * @post $none - */ - public int gridletStatus(int gridletId, int userId) { - SSGridlet sgl = null; - - // Look for the Gridlet in the running queue - sgl = findSSGridlet(runningGridlets_, gridletId, userId); - if (sgl != null) { - // Get the Gridlet from the execution list - return sgl.getStatus(); - } - - // Look for the gridlet in the waiting queue - sgl = findSSGridlet(queuedGridlets_, gridletId, userId); - if (sgl != null) { - // Get the Gridlet from the execution list - return sgl.getStatus(); - } - - // if not found in all lists then report the Gridlet has not found - return -1; - } - - /** - * Cancels a Gridlet running or in the waiting queue. - * This method will search the running and waiting queues. - * The User ID is important as many users might have the same - * Gridlet ID in the lists. If a Gridlet is cancelled, the - * availability profile is shifted forwards. This process ensures - * that the Gridlets will not have an expected completion time - * worse than the one initially stipulated for the Gridlet. - * This process if known as the compression of the schedule. - * For more details please look at the references provided - * at the initial part of this documentation.<br> - * <b>NOTE:</b> - * <ul> - * <li> Before cancelling a Gridlet, this method updates when - * the expected completion time of the Gridlet is. If the - * completion time is smaller than the current time, then - * the Gridlet is considered to be <tt>finished</tt>. - * Therefore the Gridlet cannot be cancelled. - * - * <li> Once a Gridlet has been cancelled, it cannot be resumed - * to execute again since this method will pass the Gridlet - * back to sender, i.e. the <tt>userId</tt>. - * - * <li> If a Gridlet cannot be found in either execution and - * paused list, then a <tt>null</tt> Gridlet will be send back - * to sender, i.e. the <tt>userId</tt>. - * - * <li> Once a Gridlet is cancelled, the availability profile - * is scanned and Gridlets are moved forwards. The entries - * in the profile incurred by each Gridlet are updated and - * the new anchor for the Gridlet is found again. This process - * is repeated for each Gridlet. This guarantees that Gridlets - * will not have a time completion worse than those initially - * provided. - * </ul> - * @param gridletId a Gridlet ID - * @param userId the user or owner's ID of this Gridlet - * @pre gridletId > 0 - * @pre userId > 0 - */ - public void gridletCancel(int gridletId, int userId) { - double currentTime = GridSim.clock(); - - // stores the gridlet if found - SSGridlet sgl = null; - boolean found = false; - - // The gridlets whose execution time is larger than - // this time onwards have to be shifted forwards - double referenceTime = currentTime; - - // Look for the Gridlet in the running queue - sgl = findSSGridlet(runningGridlets_, gridletId, userId); - if (sgl != null) { - found = true; - - // if the Gridlet's finish time is smaller than the current - // time or the status is FINISHED, it means that the Gridlet - // has finished, but has not been removed from the running - // queue yet. It will probably be done shortly, - // so just send a null to the user. - if(sgl.getStatus() == Gridlet.SUCCESS || - sgl.getFinishTime() <= currentTime){ - super.sendCancelGridlet(GridSimTags.GRIDLET_CANCEL, - null, gridletId, userId); - return; // return as it is impossible to cancel the Gridlet - } - else{ - // remove from the queue before compressing the schedule - runningGridlets_.remove(sgl); - } - } - - if(!found) { - // Look for the gridlet in the waiting queue - sgl = findSSGridlet(queuedGridlets_, gridletId, userId); - if (sgl != null) { - found = true; - - // Get the Gridlet from the waiting queue and - // remove from the queue before compressing the schedule - queuedGridlets_.remove(sgl); - referenceTime = sgl.getStartTime(); - } - } - - // If the Gridlet could not be found in neither queue, then send a null - // Gridlet to the user and return because there is no need to - // compress the schedule - if(!found) { - System.out.println(super.get_name() + ".gridletCancel():" + - " Cannot find Gridlet #" + gridletId + " for User #" + userId); - super.sendCancelGridlet(GridSimTags.GRIDLET_CANCEL, - null, gridletId, userId); - return; - } - - //----------------- USED FOR DEBUGGING PURPOSES ONLY ------------------- - - // If a gridlet has been cancelled, then inform the listeners - GridSim.notifyListeners(this.get_id(), AllocationAction.ITEM_CANCELLED, true, sgl); - - //---------------------------------------------------------------------- - - // remove/update entries of the gridlet in the profile - this.removeGridlet(sgl); - - // compress the schedule, that is, moves the gridlets forwards - compressSchedule(referenceTime, sgl.getStatus() == Gridlet.INEXEC); - - //------------------- USED FOR DEBUGGING PURPOSES ONLY ----------------- - - // Inform the listeners about the new schedule - GridSim.notifyListeners(this.get_id(), AllocationAction.SCHEDULE_CHANGED, true); - - //---------------------------------------------------------------------- - - // sends the Gridlet back to user - sgl.setStatus(Gridlet.CANCELED); - sgl.finalizeGridlet(); - super.sendCancelGridlet(GridSimTags.GRIDLET_CANCEL, - sgl.getGridlet(), gridletId, userId); - } - - /** - * Moves a Gridlet from this GridResource entity to a different one. - * <b>NOTE: This operation is not supported. </b> - * @param gridletId a Gridlet ID - * @param userId the user or owner's ID of this Gridlet - * @param destId a new destination GridResource ID for this Gridlet - * @param ack an acknowledgement, i.e. <tt>true</tt> if wanted to know - * whether this operation is success or not, <tt>false</tt> - * otherwise - */ - public void gridletMove(int gridletId, int userId, - int destId, boolean ack) { - System.out.println(super.get_name() + - ".gridletMove(): not supported at the moment."); - } - - /** - * Pauses a Gridlet only if it is currently executing. - * <b>NOTE: This operation is not supported. </b> - * @param gridletId a Gridlet ID - * @param userId the user or owner's ID of this Gridlet - * @param ack an acknowledgement, i.e. <tt>true</tt> if wanted to know - * whether this operation is success or not, <tt>false</tt> - * otherwise. - */ - public void gridletPause(int gridletId, int userId, boolean ack) { - System.out.println(super.get_name() + - ".gridletPause(): not supported at the moment."); - } - - /** - * Resumes a Gridlet only in the paused list. - * <b>NOTE: This operation is not supported. </b> - * @param gridletId a Gridlet ID - * @param userId the user or owner's ID of this Gridlet - * @param ack an acknowledgement, i.e. <tt>true</tt> if wanted to know - * whether this operation is success or not, <tt>false</tt> - * otherwise - */ - public void gridletResume(int gridletId, int userId, boolean ack) { - System.out.println(super.get_name() + - ".gridletResume(): not supported at the moment."); - } - // -------------------- PRIVATE METHODS ---------------------------- /** * Process and event sent to this entity * @param ev the event to be handled */ - private void processEvent(Sim_event ev) { + public void processOtherEvent(Sim_event ev) { // handle an internal event double currentTime = GridSim.clock(); - switch(ev.get_tag()) { - // time to update the schedule, finish gridlets, - // finish reservations, start reservations and start gridlets - case GRIDLET_FINISHED: - case START_RESERVATION: - case FINISH_RESERVATION: - if(currentTime > lastScheduleUpdate_) { - updateSchedule(); - } - lastScheduleUpdate_ = currentTime; - break; + if(ev.get_src() == myId_) { + switch(ev.get_tag()) { - // checks the expiry time for a given gridlet - case EXPIRY_TIME: - if(currentTime > lastCheckExpiryTime_) { - checkExpiryTime(); - } - lastCheckExpiryTime_ = currentTime; - break; - - default: - processOtherEvent(ev); - break; - } + // checks the expiry time for a given gridlet + case EXPIRY_TIME: + if(currentTime > lastCheckExpiryTime_) { + checkExpiryTime(); + } + lastCheckExpiryTime_ = currentTime; + break; + + default: + super.processOtherEvent(ev); + break; + } + } + else + super.processOtherEvent(ev); } /** @@ -954,92 +660,13 @@ */ private void init() { // initialises local data structure - runningGridlets_ = new LinkedList<SSGridlet>(); - queuedGridlets_ = new LinkedList<SSGridlet>(); - availProfile_ = new AvailabilityProfile(); reservTable_ = new LinkedHashMap<Integer, SSReservation>(); expiryTable_ = new LinkedHashMap<Integer, SSReservation>(); - orderStartTime_ = new OrderGridletByStartTime(); - lastScheduleUpdate_ = -1; - lastCheckExpiryTime_ = -1; - ratingPE_ = 0; + lastCheckExpiryTime_ = 0.0D; } /** * Schedules a new Gridlet received by the <tt>ARTGridResource</tt> - * entity and for which no advance reservation has been made. - * @param gridlet a Gridlet object to be executed - * @param ack an acknowledgement, i.e. <tt>true</tt> if the - * user wants to know whether this operation is successful - * or not, <tt>false</tt> otherwise. - */ - private void handleNonReservationGridlet(Gridlet gridlet, boolean ack) { - int reqPE = gridlet.getNumPE(); - - try{ - // reject the Gridlet if it requires more PEs than the resource - // is able to provide - if(reqPE > super.totalPE_){ - String userName = GridSim.getEntityName( gridlet.getUserID() ); - System.out.println(super.get_name() + ".gridletSubmit(): " + - " Gridlet #" + gridlet.getGridletID() + " from " + - userName + " user requires " + gridlet.getNumPE() + " PEs."); - System.out.println("--> The resource has only " + - super.totalPE_ + " PEs."); - gridlet.setGridletStatus(Gridlet.FAILED); - super.sendFinishGridlet(gridlet); - return; - } - } - catch(Exception ex){ - System.out.println(super.get_name() + - ": Exception on submission of a Gridlet"); - } - - // Create a resource Gridlet - SSGridlet sgl = new SSGridlet(gridlet); - - //------------------ FOR DEBUGGING PURPOSES ONLY------------------------ - - GridSim.notifyListeners(this.get_id(), AllocationAction.ITEM_ARRIVED, true, sgl); - - //---------------------------------------------------------------------- - - // If there enough PEs available at the moment, then - // check if it is possible to start the gridlet immediately - boolean success = false; - int freePE = resource_.getNumFreePE(); - - if( reqPE <= freePE ){ - success = scheduleGridletImmediately(sgl); - } - - // if the job could not be scheduled immediately, then - // find the anchor point where the job can be put - if(!success){ - findAnchorPoint(sgl); - // add this Gridlet into waiting list - queuedGridlets_.add(sgl); - } - - //------------------ FOR DEBUGGING PURPOSES ONLY ---------------- - - // Notifies the listeners that a Gridlet has been either scheduled - // to run immediately or put in the waiting queue - GridSim.notifyListeners(this.get_id(), AllocationAction.ITEM_SCHEDULED, true, sgl); - - //--------------------------------------------------------------- - - // sends back an ack if required - if (ack == true) { - super.sendAck(GridSimTags.GRIDLET_SUBMIT_ACK, true, - gridlet.getGridletID(), gridlet.getUserID() - ); - } - } - - /** - * Schedules a new Gridlet received by the <tt>ARTGridResource</tt> * entity and for which an advance reservation has been made. * @param gridlet a Gridlet object to be executed * @param ack an acknowledgement, i.e. <tt>true</tt> if the @@ -1130,13 +757,15 @@ // reservation if (sRes.getStatus() == Reservation.STATUS_NOT_COMMITTED) { sRes.setStatus(Reservation.STATUS_COMMITTED); - super.sendInternalEvent(resStartTime - currentTime, START_RESERVATION); + super.sendInternalEvent(resStartTime - currentTime, + CBParallelSpaceShared.UPDATE_SCHEDULE_TAG); } // if the reservation has already started, then update the // schedule, which will force the gridlets in the queue to // be started else if(sRes.getStatus() == Reservation.STATUS_IN_PROGRESS) { - startQueuedGridlets(); + super.sendInternalEvent(resStartTime - currentTime, + CBParallelSpaceShared.UPDATE_SCHEDULE_TAG); } } @@ -1156,113 +785,7 @@ } } - /** - * Allocates a Gridlet into free PEs, sets the Gridlet status to INEXEC, - * updates the availability profile and the ranges currently available - * @param sgl a SSGridlet object - * @return <tt>true</tt> if there is are free PE to process this Gridlet, - * <tt>false</tt> otherwise - * @pre sgl != null - * @post $none - */ - private boolean scheduleGridletImmediately(SSGridlet sgl) { - int reqPE = sgl.getNumPE(); - - // calculate the execution time of the Gridlet - double executionTime = - super.forecastExecutionTime(ratingPE_, sgl.getRemainingLength()); - - // calculates how much ahead to look into the availability profile - double currentTime = GridSim.clock() ; - // the Gridlet's expected finish time - double finishTime = currentTime + executionTime; - - // check whether there are PEs available over the time interval requested - Object[] availObj = - checkImmediatePERangesAvailability(reqPE, currentTime, executionTime); - - // if the above method returns null, it means that there are not enough - // PEs to serve the reservation or Gridlet - if(availObj == null || availObj.length < 2){ - return false; - } - - int tailIndex = ((Integer)availObj[0]).intValue(); - PERangeList selected = (PERangeList)availObj[1]; - allocateImmediatePERanges(tailIndex, selected, currentTime, finishTime); - - // add this Gridlet into execution list - runningGridlets_.add(sgl); - sgl.setStartTime(currentTime); - sgl.setFinishTime(finishTime); - - // change Gridlet status - sgl.setStatus(Gridlet.INEXEC); - - // Sets the list of ranges used by the gridlet - sgl.setPERangeList(selected); - - // then send this event to itself to update the queues after - // this gridlet's completion time - super.sendInternalEvent(executionTime, GRIDLET_FINISHED); - return true; - } - /** - * Update the information about the jobs scheduled - * @param sgl the resource gridlet - */ - private void findAnchorPoint(SSGridlet sgl){ - int reqPE = sgl.getNumPE(); - - // calculate the execution time of the Gridlet - double executionTime = - super.forecastExecutionTime(ratingPE_, sgl.getRemainingLength()); - - double startTime = -1; // keep the potential start time of the gridlet - double finishTime = -1; // store the gridlet's expected finish time - - // check whether there are PEs available over the time - // interval requested - Object[] availObj = checkPERangesAvailability(reqPE, executionTime); - - // the anchor index, the entry in the profile where the gridlet - // will be placed - int anchorIndex = (Integer)availObj[0]; - // insert index represents the position after which the entry - // corresponding to the gridlet's finish time will be placed - int tailIndex = (Integer)availObj[1]; - PERangeList selected = (PERangeList)availObj[2]; - - // a pointer to the anchor entry - AvailabilityProfileEntry anchorEntry = availProfile_.get(anchorIndex); - startTime = anchorEntry.getTime(); - finishTime = startTime + executionTime; - allocatePERanges(anchorIndex, tailIndex, selected, startTime, finishTime); - - // Set the list of ranges used by the gridlet - sgl.setPERangeList(selected); - - // change Gridlet status - sgl.setStatus(Gridlet.QUEUED); - sgl.setStartTime(startTime); - sgl.setFinishTime(finishTime); - } - - /** - * This method removes/updates all the entries of a gridlet from the profile - * and updates the ranges of current free PEs if the gridlet was in execution. - * @param gridlet the Gridlet to be removed - */ - private void removeGridlet(SSGridlet gridlet) { - // check whether the Gridlet is running - boolean isRunning = gridlet.getStatus() == Gridlet.INEXEC; - - // removes the gridlet from the profile - updateEntriesAtProfile(isRunning, gridlet); - } - - /** * This method removes/updates all the entries of a reservation from * the profile and updates the ranges of current free PEs if the * reservation was in execution. @@ -1313,161 +836,6 @@ } /** - * This method performs the compression of the schedule and - * availability profile. The method iterates the queued gridlets list. - * For each gridlet, it removes its entry from the profile and - * then tries to reinsert the gridlet in the profile. In the worst case, - * the Gridlet will be put back in the same place. This process - * compress the schedule by shifting the jobs forwards, guarantees the - * initial order of jobs given by the scheduler and makes sure that - * no job will have a worse estimate than the one initially given.<br> - * <b>NOTE:</b> - * <ul> - * <li> Optimisations can be made so it may not be required to - * scan the whole list of gridlets. However, this will be - * left for future work as this feature is not required - * for my work YET. - * <li> You are more than welcome to improve it if you want. - * However, do please let me know if come up with a better algorithm. - * <li> This algorithm can be used in case you implement - * gridlets that finish before the expected completion time. - * </ul> - * - * @param referenceTime all gridlets whose start time is larger than - * @param runImmediately <tt>true</tt> means that the gridlet cancelled - * was running, so this method will try to run the gridlets immediately. - * If not possible they are reinserted in the queue with the new start time. - * reference time have to be shifted forwards. - * @return <tt>true</tt> if the Gridlet has been removed and - * the profile has successfully been updated or <tt>false</tt> - * otherwise. - */ - private boolean compressSchedule(double referenceTime, - boolean runImmediately) { - - // iterates the waiting queue and for each gridlet, put the ranges - // used back in the profile. That is, updates the entries - Collections.sort(queuedGridlets_, orderStartTime_); - - Iterator<SSGridlet> iterQueue = queuedGridlets_.iterator(); - while(iterQueue.hasNext()) { - SSGridlet queuedSgl = iterQueue.next(); - - // if the start time of the gridlet is already smaller or equals - // to reference time, then continue. It cannot get better than this. - if(queuedSgl.getStartTime() <= referenceTime) { - continue; - } - - // if the gridlet has not reserved resources, then it can be moved - if(!queuedSgl.hasReserved()) { - - updateEntriesAtProfile(false, queuedSgl); - - // Now try to either schedule the gridlet immediately or - // find the new anchor point - boolean success = false; - if(runImmediately) { - success = scheduleGridletImmediately(queuedSgl); - } - - if(success) { - iterQueue.remove(); - } - else { - findAnchorPoint(queuedSgl); - } - } - } - return true; - } - - /** - * This method removes/updates the entries from the profile - * corresponding to a the given Gridlet or advance reservation. - * - * @param wasRunning indicates whether the gridlet or advance - * reservation was in progress. - * <tt>true</tt> indicates that it was in progress and - * <tt>false</tt> otherwise. - * @param removedItem the Gridlet or advance reservation whose entries - * have to be removed or updated - */ - private void updateEntriesAtProfile(boolean wasRunning, - ScheduleItem removedItem) { - // ranges of PEs used by the Gridlet - PERangeList allocatedRanges = removedItem.getPERangeList(); - - // the reference time used to update the entries in the profile - double startTime = removedItem.getStartTime(); - - // the entries between reference time and endTime must be updated - double endTime = removedItem.getFinishTime(); - - // if the Gridlet was running, then update the range of PEs currently - // available and set the reference time as current simulation time - if(wasRunning) { - // returns the ranges to the list of free ranges - resource_.setPEsAvailable(allocatedRanges); - } - - Iterator<AvailabilityProfileEntry> iterProfile = - availProfile_.iterator(); - - while(iterProfile.hasNext()) { - AvailabilityProfileEntry entry = iterProfile.next(); - - double entryTime = entry.getTime(); - if(entryTime < startTime) { - continue; - } - else if(entryTime > endTime) { - break; - } - else{ - if(entryTime == endTime) { - // if the entry is equals to the finish time of the - // gridlet, then it means that the gridlet uses this entry - // to mark its termination. Therefore, it decreases the - // number of gridlets that rely on this entry to mark - // the finish time. If the number of gridlets is 0, it - // means that the entry can be deleted because it is - // not needed anymore - entry.decreaseGridlet(); - if(entry.getNumGridlets() == 0){ - iterProfile.remove(); - } - continue; - } - // if the entry is the gridlet's anchor point, then - // decrease the number of gridlets that rely on this - // entry to either mark their start time or completion - // time. If the number of Gridlets is 0 then, the - // entry is removed from the profile - if(entryTime == startTime) { - entry.decreaseGridlet(); - if(entry.getNumGridlets() == 0){ - iterProfile.remove(); - continue; - } - } - // returns the ranges to the list of free ranges in - // the entry, and consolidates the ranges to avoid fragments - // As the list may be null, make sure that the list will not be - // null so the released ranges can be added back to it - PERangeList listEntry = entry.getPERanges(); - if(listEntry == null){ - listEntry = new PERangeList(); - } - - listEntry.addAll(allocatedRanges.clone()); - listEntry.mergePERanges(); - entry.setPERangeList(listEntry); - } - } - } - - /** * Checks for expiry time of a given reservations in the list. * @param reservation the reservation to be checked */ @@ -1520,11 +888,6 @@ // gridlets in the queue forwards) compressSchedule(referenceTime, false); - // tries to start the Gridlets. - // TODO: I am not sure whether this is in fact needed. - // TODO: To check this later -// startQueuedGridlets(); - //---------------- USED FOR DEBUGGING PURPOSES ONLY ---------------- // If a gridlet has started execution or one has finished, @@ -1534,65 +897,8 @@ //----------------------------------------------------------------- } } - + /** - * This method is called to update the schedule. It removes completed - * gridlets and return them to the users and verifies whether there are - * gridlets in the waiting list that should start execution. It also - * removes old entries from the availability profile. - */ - private void updateSchedule() { - - int itemsFinished = 0; - double currentTime = GridSim.clock(); - int itemsStarted = 0; - - // finishes the advance reservations first - itemsFinished = finishReservation(currentTime); - - boolean reserved; - // remove all Gridlets that have already completed from - // the queue of running Gridlets - PERangeList releasedRanges = new PERangeList(); - - // iterates the list to check what has finished - Iterator<SSGridlet> iter = runningGridlets_.iterator(); - while (iter.hasNext()) { - SSGridlet gridlet = iter.next(); - reserved = gridlet.hasReserved(); - // as gridlets are removed from running queue once they finish - // time is smaller than current time, then testing the time - // is enough. There's no need to check status - if(gridlet.getFinishTime() <= currentTime) { - // Update the list of ranges released - if(!reserved) { - releasedRanges.addAll(gridlet.getPERangeList().clone()); - } - gridletFinish(gridlet, Gridlet.SUCCESS); - iter.remove(); - itemsFinished++; - } - } - resource_.setPEsAvailable(releasedRanges); - itemsStarted = startReservation(currentTime); - - // remove past entries from the availability profile - cleanAvailabilityProfile(currentTime); - - // Start the execution of Gridlets that are queued and whose - // potential start execution time is smaller than current time - itemsStarted += startQueuedGridlets(); - - //---------------- USED FOR DEBUGGING PURPOSES ONLY -------------------- - - // If a gridlet has started execution or one has finished, - // then inform the listeners - if(itemsStarted > 0 || itemsFinished > 0){ - GridSim.notifyListeners(this.get_id(), AllocationAction.SCHEDULE_CHANGED, true); - } - } - - /** * This method is called to start a reservation and consequently update * the availability profile. * @refTime the reservations whose start time is smaller @@ -1619,7 +925,7 @@ startedReservations.add(sRes); super.sendInternalEvent(sRes.getFinishTime()-refTime, - FINISH_RESERVATION); + CBParallelSpaceShared.UPDATE_SCHEDULE_TAG); numStartedRes++; } @@ -1694,81 +1000,6 @@ return reservationFinished; } - /** - * Removes all the past entries from the availability profile that are - * older than the reference time - * @param referenceTime the time to be used as reference when removing - * past entries. - */ - private void cleanAvailabilityProfile(double referenceTime) { - // Update the availability profile - Iterator<AvailabilityProfileEntry> iterProfile = availProfile_.iterator(); - while(iterProfile.hasNext()) { - AvailabilityProfileEntry entry = iterProfile.next(); - - if(entry.getTime() <= referenceTime){ - iterProfile.remove(); - } - else{ - return; - } - } - } - - /** - * This method starts gridlets that are in the queue and - * whose start time is smaller than the reference time and updates - * the availability profile and ranges of PEs currently available accordingly - * @return the number of gridlets started - */ - private int startQueuedGridlets() { - - int gridletStarted = 0; - boolean reserved; // to indicate whether the gridlet refers to a reserv. - double currentTime = GridSim.clock(); - - // Start the execution of Gridlets that are queued and whose - // potential start execution time is smaller than reference time - PERangeList allocatedRanges = new PERangeList(); - Iterator<SSGridlet> iter = queuedGridlets_.iterator(); - while (iter.hasNext()) { - SSGridlet gridlet = iter.next(); - // check whether there is a reservation for this gridlet - reserved = gridlet.hasReserved(); - if(gridlet.getStartTime() <= currentTime) { - // Update the list of ranges allocated - if(!reserved) - allocatedRanges.addAll(gridlet.getPERangeList()); - - runningGridlets_.add(gridlet); - iter.remove(); - gridletStarted++; - - // change Gridlet status - gridlet.setStatus(Gridlet.INEXEC); - super.sendInternalEvent(gridlet.getFinishTime()-currentTime, - GRIDLET_FINISHED); - } - } - - resource_.setPEsBusy(allocatedRanges); - return gridletStarted++; - } - - /** - * Updates the Gridlet's properties, such as status once a - * Gridlet is considered finished. - * @param sgl a SSGridlet object - * @param status the Gridlet status - */ - private void gridletFinish(SSGridlet sgl, int status) { - // the order is important! Set the status first then finalise - // due to timing issues in SSGridlet class - sgl.setStatus(status); - sgl.finalizeGridlet(); - super.sendFinishGridlet( sgl.getGridlet() ); - } - /** * Selects a list of PE ranges able to provide enough PEs to handle * a reservation or a Gridlet. @@ -1856,114 +1087,6 @@ /** * Selects a list of PE ranges able to provide enough PEs - * to handle a Gridlet. - * - * @param reqPE the number of PEs - * @param duration the duration in seconds to execute the Gridlet - * @return an array[2] of Objects as follows:<br> - * array[0] the index of the anchor point<br> - * array[1] the index of the last entry before or equals to the finish time - * of the Gridlet in the availability profile<br> - * array[2] the list of PE ranges<br> - */ - private Object[] checkPERangesAvailability(int reqPE, double duration) { - - // the anchor index, the entry in the profile where - // the gridlet will be placed OR the closest entry to the - // point where the anchor of the advance reservation will be placed - int anchorIndex = -1; - - // tail index represents the position which corresponds to the closest - // entry to the gridlet's finish time OR an existing entry whose - // time is equals to the gridlet's or advance reservation's finish time - int tailIndex = -1; - - // a pointer to the last entry analysed (described above) - AvailabilityProfileEntry tailEntry = null; - - // a pointer to the anchor entry (described above) - AvailabilityProfileEntry anchorEntry = null; - - // the list of selected ranges - PERangeList intersectList = null; - - double potStartTime = -1; // keep the potential start time of the gridlet - double potFinishTime = -1; // store the gridlet's expected finish time - - intersectList = null; - int length = availProfile_.size(); - - Iterator<AvailabilityProfileEntry> iterProfile = availProfile_.iterator(); - while(iterProfile.hasNext()) { - - AvailabilityProfileEntry entry = iterProfile.next(); - - // scan the profile until an entry with enough PEs is found - if(entry.getNumPE() < reqPE) { - continue; - } - else { - - anchorEntry = entry; - anchorIndex = availProfile_.indexOf(anchorEntry); - tailEntry = entry; - - // sets the start time as the time of the entry - potStartTime = entry.getTime(); - // calculates when the finish time will be if - // the gridlet is put at this position - potFinishTime = potStartTime + duration; - - // if an entry with enough PEs is found, then scan the profile - // from that point onwards analysing the intersection of - // the ranges available in the entries until the - // gridlet expected completion time - intersectList = entry.getPERanges().clone(); - - // Look for the intersection of available ranges from - // the anchor until the end of the profile or until - // the entries are further than the expected completion time - for(int i=anchorIndex+1; i<length; i++){ - AvailabilityProfileEntry nextEntry = availProfile_.get(i); - if(nextEntry.getTime() > potFinishTime){ - break; - } - else{ - // if the finish time is equals to the entry time, so there - // is no need to check the intersection - if(nextEntry.getTime() < potFinishTime) { - intersectList = PERangeList.intersection(intersectList, - nextEntry.getPERanges()); - if(intersectList == null || intersectList.getNumPE() < reqPE) { - break; - } - } - tailEntry = nextEntry; - } - } - // If a time slot with enough PEs has been found, then stop the search - if(intersectList != null && intersectList.getNumPE() >= reqPE) { - break; - } - } - } - - if(intersectList == null || intersectList.getNumPE() < reqPE) - return null; - - anchorIndex = availProfile_.indexOf(anchorEntry); - tailIndex = availProfile_.indexOf(tailEntry); - - // creates the array with the result - Object[] result = new Object[3]; - result[0] = new Integer(anchorIndex); - result[1] = new Integer(tailIndex); - result[2] = super.selectPERangeList(reqPE, intersectList); - return result; - } - - /** - * Selects a list of PE ranges able to provide enough PEs * to handle a reservation. * * @param reqPE the number of PEs @@ -2042,7 +1165,6 @@ break; } else { - // Sep. 29, 2007 - Changed by Marcos // if the finish time is equals to the entry time, so there // is no need to check the intersection if(nextEntry.getTime() < finishTime) { @@ -2247,6 +1369,46 @@ } } + // ---------------------- PROTECTED METHODS ------------------------ + + /** + * This method is called to update the schedule. It removes completed + * gridlets and return them to the users and verifies whether there are + * gridlets in the waiting list that should start execution. It also + * removes old entries from the availability profile. + */ + protected void updateSchedule() { + + double currentTime = GridSim.clock(); + int itemsFinished = 0; + int itemsStarted = 0; + + // finishes the advance reservations first + itemsFinished = finishReservation(currentTime); + + // then finishes the Gridlets whose start time is smaller + // or equals to the current simulation time + itemsFinished += super.finishRunningGridlets(currentTime); + + // remove past entries from the availability profile + availProfile_.removePastEntries(currentTime); + + // starts the advance reservations + itemsStarted = startReservation(currentTime); + + // Start the execution of Gridlets that are queued and whose + // potential start execution time is smaller than current time + itemsStarted += super.startQueuedGridlets(currentTime); + + //---------------- USED FOR DEBUGGING PURPOSES ONLY -------------------- + + // If a gridlet has started execution or one has finished, + // then inform the listeners + if(itemsStarted > 0 || itemsFinished > 0){ + GridSim.notifyListeners(this.get_id(), AllocationAction.SCHEDULE_CHANGED, true); + } + } + /** * This method returns a list that corresponds to the free time slots * in the scheduling queue managed by this scheduler or @@ -2329,4 +1491,48 @@ return list; } + + /** + * Search for a particular reservation in a data structure + * @param obj a data structure + * @param reservID a reservation ID + * @return location in the data structure; <tt>-1</tt> if not found + */ + protected int searchReservation(Collection<Reservation> obj, int reservID) { + + Reservation arObj = null; + int found = -1; // means the reservation is not in the list + + try { + // Search through the list to find the given reservation + int i = 0; + Iterator<Reservation> iter = obj.iterator(); + while ( iter.hasNext() ) { + arObj = iter.next(); + + if (arObj.getID() == reservID) { + found = i; + break; + } + i++; + } + } + catch (Exception e) { + System.out.println("ARTPolicy.findReservation(): " + + "The following error occured:" + e.getMessage()); + } + + return found; + } + + /** + * Sends a reservation message. + * @param message the message to be sent + */ + protected void sendARMessage(ARMessage message) { + // send message to the destination + super.sim_schedule(super.outputPort_, GridSimTags.SCHEDULE_NOW, + message.getMessageType(), new IO_data(message, + message.getMessageSize(), message.getDestinationID())); + } } Modified: branches/gridsim4.0-branch3/source/gridsim/turbo/ARTGridResource.java =================================================================== --- branches/gridsim4.0-branch3/source/gridsim/turbo/ARTGridResource.java 2008-02-11 06:09:53 UTC (rev 98) +++ branches/gridsim4.0-branch3/source/gridsim/turbo/ARTGridResource.java 2008-02-11 23:42:40 UTC (rev 99) @@ -68,7 +68,7 @@ */ public ARTGridResource(String name, double baud_rate, TResourceCharacteristics resource, ResourceCalendar calendar, - ARTPolicy policy) throws Exception { + TAllocPolicy policy) throws Exception { super(name, baud_rate, resource, calendar, policy); if(resource.getResourceAllocationPolicy() != TResourceCharacteristics.AR_PARALLEL_SPACE_SHARED) { @@ -110,7 +110,7 @@ */ public ARTGridResource(String name, Link link, TResourceCharacteristics resource, ResourceCalendar calendar, - ARTPolicy policy) throws Exception { + TAllocPolicy policy) throws Exception { super(name, link, resource, calendar, policy); if(resource.getResourceAllocationPolicy() != TResourceCharacteristics.AR_PARALLEL_SPACE_SHARED) { Modified: branches/gridsim4.0-branch3/source/gridsim/turbo/ARTPolicy.java =================================================================== --- branches/gridsim4.0-branch3/source/gridsim/turbo/ARTPolicy.java 2008-02-11 06:09:53 UTC (rev 98) +++ branches/gridsim4.0-branch3/source/gridsim/turbo/ARTPolicy.java 2008-02-11 23:42:40 UTC (rev 99) @@ -8,19 +8,12 @@ package gridsim.turbo; -import gridsim.GridSimTags; -import gridsim.IO_data; - -import java.util.Calendar; -import java.util.Collection; -import java.util.Iterator; - /** - * <tt>ARTPolicy</tt> is an abstract class that handles the internal - * <tt>ARTGridResource</tt> allocation policy related to Advanced - * Reservation functionalities. New scheduling algorithms can be added - * into a <tt>ARTGridResource</tt> entity by extending this class - * and implement the required abstract methods. + * <tt>ARTPolicy</tt> is an interface that defines the methods that an + * <tt>ARTGridResource</tt>'s needs to implement in order to have + * Advanced Reservation functionalities. New scheduling algorithms can be added + * into a <tt>ARTGridResource</tt> entity by implementing this interface + * and extending <tt>TAllocPolicy</tt>. * @author Marcos Dias de Assuncao * @since GridSim Turbo Alpha 0.1 @@ -31,48 +24,15 @@ * @see TAllocPolicy * */ -public abstract class ARTPolicy extends TAllocPolicy { +public interface ARTPolicy { /** - * Allocates a new <tt>ARTPolicy</tt> object. A child class should call this method - * during its constructor. The name of this entity (or the child class that - * inherits this class) will be <tt>"resName_entityName"</tt>. - * - * @param resourceName the GridResource entity name that will contain - * this allocation policy - * @param entityName this object entity name - * @throws Exception This happens when one of the following scenarios occur: - * <ul> - * <li> creating this entity before initialising GridSim package - * <li> this entity name is <tt>null</tt> or empty - * <li> this entity has <tt>zero</tt> number of PEs (Processing - * Elements). <br> - * No PEs mean the Gridlets can't be processed. - * A GridResource must contain one or more Machines. - * A Machine must contain one or more PEs. - * </ul> - * - * @see gridsim.GridSim#init(int, Calendar, boolean) - * @see gridsim.GridSim#init(int, Calendar, boolean, String[], String[], - * String) - * @pre resourceName != null - * @pre entityName != null - * @post $none - */ - public ARTPolicy(String resourceName, String entityName) - throws Exception { - super(resourceName, entityName); - } - - ///////////////////// ABSTRACT METHODS //////////////////////////////// - - /** * An abstract method that handles a new advanced reservation request. * @param message the advance reservation message received requesting * the reservation * @pre message != null */ - public abstract void handleCreateReservation(ARMessage message); + void handleCreateReservation(ARMessage message); /** * An abstract method that handles a modify reservation request. @@ -80,7 +40,7 @@ * the change * @pre message != null */ - public abstract void handleModifyReservation(ARMessage message); + void handleModifyReservation(ARMessage message); /** * An abstract method that handles a cancel reservation request. @@ -88,78 +48,27 @@ * the cancellation * @pre message != null */ - public abstract void handleCancelReservation(ARMessage message); + void handleCancelReservation(ARMessage message); /** * An abstract method that handles a commit reservation request. * @param message the advance reservation message received * @pre message != null */ - public abstract void handleCommitReservation(ARMessage message); + void handleCommitReservation(ARMessage message); /** * An abstract method that handles a query reservation request. * @param message the advance reservation message received * @pre message != null */ - public abstract void handleQueryReservation(ARMessage message); + void handleQueryReservation(ARMessage message); /** * An abstract method that handles a query free time request. * @param message the advance reservation message received ... [truncated message content] |
From: <mar...@us...> - 2008-02-11 06:09:48
|
Revision: 98 http://gridsim.svn.sourceforge.net/gridsim/?rev=98&view=rev Author: marcos_dias Date: 2008-02-10 22:09:53 -0800 (Sun, 10 Feb 2008) Log Message: ----------- This update contains small bug fixes and improvements: + The advance reservation policy and the conservative backfilling could present overlapping ranges of available processing elements. Although that did not affect the resource allocation results, that could lead to infinite loops on software that queried the resource availability. + Small changes in the availability information objects and the lists of PEs. Modified Paths: -------------- branches/gridsim4.0-branch3/source/gridsim/turbo/ARParallelSpaceShared.java branches/gridsim4.0-branch3/source/gridsim/turbo/CBParallelSpaceShared.java branches/gridsim4.0-branch3/source/gridsim/util/SimReport.java Modified: branches/gridsim4.0-branch3/source/gridsim/turbo/ARParallelSpaceShared.java =================================================================== --- branches/gridsim4.0-branch3/source/gridsim/turbo/ARParallelSpaceShared.java 2008-02-11 05:28:07 UTC (rev 97) +++ branches/gridsim4.0-branch3/source/gridsim/turbo/ARParallelSpaceShared.java 2008-02-11 06:09:53 UTC (rev 98) @@ -261,10 +261,7 @@ Sim_event ev = new Sim_event(); while ( Sim_system.running() ) { super.sim_get_next(ev); - if (ev.get_src() == super.myId_) - processEvent(ev); - else - processOtherEvent(ev); + processEvent(ev); } // CHECK for ANY INTERNAL EVENTS WAITING TO BE PROCESSED @@ -1577,12 +1574,6 @@ } } resource_.setPEsAvailable(releasedRanges); - -// if(PERangeList.containsOverlappingRanges(resource_.getFreePERanges())) { -// System.out.println("Overlap! Ranges = " + resource_.getFreePERanges()); -// System.exit(1); -// } - itemsStarted = startReservation(currentTime); // remove past entries from the availability profile @@ -1715,12 +1706,6 @@ while(iterProfile.hasNext()) { AvailabilityProfileEntry entry = iterProfile.next(); -// if(PERangeList.containsOverlappingRanges(entry.getPERanges())) { -// System.out.println(" Profile entry at time " + entry.getTime() + -// " contains overlapping ranges. Ranges = " + entry.getPERanges()); -// System.exit(0); -// } - if(entry.getTime() <= referenceTime){ iterProfile.remove(); } @@ -1976,7 +1961,6 @@ result[2] = super.selectPERangeList(reqPE, intersectList); return result; } - /** * Selects a list of PE ranges able to provide enough PEs @@ -2147,9 +2131,7 @@ // Update entries of the profile for(int index=0; index<tailIndex; index++) { AvailabilityProfileEntry entry = availProfile_.get(index); -// if(entry.getTime() < startTime){ -// continue; -// } + PERangeList uptList = PERangeList.difference(entry.getPERanges(), selected); entry.setPERangeList(uptList); Modified: branches/gridsim4.0-branch3/source/gridsim/turbo/CBParallelSpaceShared.java =================================================================== --- branches/gridsim4.0-branch3/source/gridsim/turbo/CBParallelSpaceShared.java 2008-02-11 05:28:07 UTC (rev 97) +++ branches/gridsim4.0-branch3/source/gridsim/turbo/CBParallelSpaceShared.java 2008-02-11 06:09:53 UTC (rev 98) @@ -101,19 +101,19 @@ public class CBParallelSpaceShared extends TAllocPolicy { // Queue of waiting Gridlets - private LinkedList<SSGridlet> queuedGridlets_; + protected LinkedList<SSGridlet> queuedGridlets_; // Queue of running Gridlets - private LinkedList<SSGridlet> runningGridlets_; + protected LinkedList<SSGridlet> runningGridlets_; - // The rating of one PE - private int ratingPE_; - // a list containing the availability of PEs - private AvailabilityProfile availProfile_; + protected AvailabilityProfile availProfile_; // the resource characteristics object to be used - private TResourceCharacteristics resource_; + protected TResourceCharacteristics resource_; + + // The rating of one PE + private int ratingPE_; // to order gridlets by potential start time private OrderGridletByStartTime orderStartTime_; @@ -170,28 +170,16 @@ ratingPE_ = resource_.getMIPSRatingOfOnePE(); // a loop that is looking for internal events only + // This loop does not stop when the policy receives an + // end of simulation event because it needs to handle + // all the internal events before it finishes its + // execution. This is important particularly for the + // graphical user interface to show the completion of + // advance reservations Sim_event ev = new Sim_event(); while ( Sim_system.running() ) { super.sim_get_next(ev); - - // if the simulation finishes then exit the loop - if (ev.get_tag() == GridSimTags.END_OF_SIMULATION || - super.isEndSimulation() == true) { - break; - } - - // Internal Event if the event source is this entity - if (ev.get_src() == super.myId_ && - ev.get_tag() == GRIDLET_FINISHED) { - double currentTime = GridSim.clock(); - if(currentTime > lastScheduleUpdate_) { - updateSchedule(); - } - lastScheduleUpdate_ = currentTime; - } - else { - processOtherEvent(ev); - } + processEvent(ev); } // CHECK for ANY INTERNAL EVENTS WAITING TO BE PROCESSED @@ -207,7 +195,7 @@ orderStartTime_ = null; availProfile_.clear(); } - + /** * Schedules a new <tt>Gridlet</tt> received by the * <tt>GridResource</tt> entity. @@ -472,6 +460,31 @@ } // -------------------- PRIVATE METHODS ---------------------------- + + /** + * Process and event sent to this entity + * @param ev the event to be handled + */ + private void processEvent(Sim_event ev) { + + // handle an internal event + double currentTime = GridSim.clock(); + + switch(ev.get_tag()) { + // time to update the schedule, finish gridlets, + // finish reservations, start reservations and start gridlets + case GRIDLET_FINISHED: + if(currentTime > lastScheduleUpdate_) { + updateSchedule(); + } + lastScheduleUpdate_ = currentTime; + break; + + default: + processOtherEvent(ev); + break; + } + } /** * Allocates a Gridlet into free PEs, sets the Gridlet status to INEXEC, Modified: branches/gridsim4.0-branch3/source/gridsim/util/SimReport.java =================================================================== --- branches/gridsim4.0-branch3/source/gridsim/util/SimReport.java 2008-02-11 05:28:07 UTC (rev 97) +++ branches/gridsim4.0-branch3/source/gridsim/util/SimReport.java 2008-02-11 06:09:53 UTC (rev 98) @@ -124,7 +124,7 @@ * @pre $none * @post $none */ - public void write(int num, String desc) + public synchronized void write(int num, String desc) { buffer_.append( GridSim.clock() ); buffer_.append(indent_); @@ -144,7 +144,7 @@ * @pre $none * @post $none */ - public void write(double num, String desc) + public synchronized void write(double num, String desc) { buffer_.append( GridSim.clock() ); buffer_.append(indent_); @@ -164,7 +164,7 @@ * @pre $none * @post $none */ - public void write(long num, String desc) + public synchronized void write(long num, String desc) { buffer_.append( GridSim.clock() ); buffer_.append(indent_); @@ -183,7 +183,7 @@ * @pre $none * @post $none */ - public void write(String data) + public synchronized void write(String data) { buffer_.append( GridSim.clock() ); buffer_.append(indent_); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mar...@us...> - 2008-02-11 05:29:51
|
Revision: 97 http://gridsim.svn.sourceforge.net/gridsim/?rev=97&view=rev Author: marcos_dias Date: 2008-02-10 21:28:07 -0800 (Sun, 10 Feb 2008) Log Message: ----------- Policy updated to provide options when a reservation is rejected. Modified Paths: -------------- branches/gridsim4.0-branch3/examples/examples/WorkloadWithReservation.java branches/gridsim4.0-branch3/examples/examples/ar/ARTest.java branches/gridsim4.0-branch3/examples/examples/workload/ar/TurboARExample01.java branches/gridsim4.0-branch3/examples/examples/workload/parallel/LublinWorkloadExample01.java Modified: branches/gridsim4.0-branch3/examples/examples/WorkloadWithReservation.java =================================================================== --- branches/gridsim4.0-branch3/examples/examples/WorkloadWithReservation.java 2008-02-11 05:27:42 UTC (rev 96) +++ branches/gridsim4.0-branch3/examples/examples/WorkloadWithReservation.java 2008-02-11 05:28:07 UTC (rev 97) @@ -632,7 +632,7 @@ reservation = super.createReservation(startTime, duration, resGl.getNumPE(), resID_); success = true; - if(reservation == null) { + if(reservation == null || reservation.getStatus() == Reservation.STATUS_FAILED) { success = false; } Modified: branches/gridsim4.0-branch3/examples/examples/ar/ARTest.java =================================================================== --- branches/gridsim4.0-branch3/examples/examples/ar/ARTest.java 2008-02-11 05:27:42 UTC (rev 96) +++ branches/gridsim4.0-branch3/examples/examples/ar/ARTest.java 2008-02-11 05:28:07 UTC (rev 97) @@ -205,7 +205,7 @@ boolean success = false; reservation = super.createReservation(time, duration, totalPE, resID); - if(reservation != null) { + if(reservation != null && reservation.getStatus() != Reservation.STATUS_FAILED) { System.out.println(super.get_name() + ": reservation has been accepted by "+ resName + " at time = " + GridSim.clock()); success = true; Modified: branches/gridsim4.0-branch3/examples/examples/workload/ar/TurboARExample01.java =================================================================== --- branches/gridsim4.0-branch3/examples/examples/workload/ar/TurboARExample01.java 2008-02-11 05:27:42 UTC (rev 96) +++ branches/gridsim4.0-branch3/examples/examples/workload/ar/TurboARExample01.java 2008-02-11 05:28:07 UTC (rev 97) @@ -89,10 +89,10 @@ ////////////////////////////////////////// // Starts the simulation in debug mode - GridSim.startGridSimulation(true); +// GridSim.startGridSimulation(true); // Start the simulation in normal mode -// GridSim.startGridSimulation(); + GridSim.startGridSimulation(); ////////////////////////////////////////// // Final step: Prints the Gridlets when simulation is over Modified: branches/gridsim4.0-branch3/examples/examples/workload/parallel/LublinWorkloadExample01.java =================================================================== --- branches/gridsim4.0-branch3/examples/examples/workload/parallel/LublinWorkloadExample01.java 2008-02-11 05:27:42 UTC (rev 96) +++ branches/gridsim4.0-branch3/examples/examples/workload/parallel/LublinWorkloadExample01.java 2008-02-11 05:28:07 UTC (rev 97) @@ -92,10 +92,10 @@ ////////////////////////////////////////// // Starts the simulation in debug mode -// GridSim.startGridSimulation(true); + GridSim.startGridSimulation(true); // Start the simulation in normal mode - GridSim.startGridSimulation(); +// GridSim.startGridSimulation(); ////////////////////////////////////////// // Final step: Prints the Gridlets when simulation is over @@ -148,7 +148,7 @@ TResourceCharacteristics resConfig = new TResourceCharacteristics( arch, os, mList, TResourceCharacteristics.CB_PARALLEL_SPACE_SHARED, time_zone, cost); - + ////////////////////////////////////////// // 6. Finally, we need to create a GridResource object. double baud_rate = 10000.0; // communication speed This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mar...@us...> - 2008-02-11 05:27:39
|
Revision: 96 http://gridsim.svn.sourceforge.net/gridsim/?rev=96&view=rev Author: marcos_dias Date: 2008-02-10 21:27:42 -0800 (Sun, 10 Feb 2008) Log Message: ----------- Policy updated to provide options when a reservation is rejected. Modified Paths: -------------- branches/gridsim4.0-branch3/source/gridsim/turbo/ARParallelSpaceShared.java Modified: branches/gridsim4.0-branch3/source/gridsim/turbo/ARParallelSpaceShared.java =================================================================== --- branches/gridsim4.0-branch3/source/gridsim/turbo/ARParallelSpaceShared.java 2008-02-11 02:35:48 UTC (rev 95) +++ branches/gridsim4.0-branch3/source/gridsim/turbo/ARParallelSpaceShared.java 2008-02-11 05:27:42 UTC (rev 96) @@ -303,7 +303,7 @@ // creates a Server Side Reservation (i.e. SSReservation) SSReservation sRes = new SSReservation(reservation); - double expTime; + double expTime = Double.NaN; // creates a response message to be sent to the requester ARMessage response = message.createResponse(); @@ -330,8 +330,10 @@ return; } + boolean success = true; + // if start time is 0, then it is an immediate reservation - if(startTime == 0) { + if(startTime == 0 || startTime == currentTime) { // sets the start time of the reservation as the current time startTime = currentTime; @@ -353,31 +355,29 @@ userName + " user requires " + reservation.getNumPE() + " PEs from " + startTime + " to " + (startTime + duration)); System.out.println("--> The resource cannot handle the reservation"); - - reservation.setStatus(Reservation.STATUS_FAILED); - response.setErrorCode(ARMessage.EC_OPERATION_FAILURE); - super.sendARMessage(response); - return; + success = false; } - - // gets the index of the entry closest to the termination of the - // reservation but whose time is not larger than the reservation's - // termination time - int tailIndex = (Integer)availObj[0]; - - // gets the list of PEs selected for the reservation - PERangeList selected = (PERangeList)availObj[1]; - - // allocates the list of PEs to the reservation - sRes.setPERangeList(selected); - - // updates the availability profile accordingly - allocateImmediatePERanges(tailIndex, selected, - currentTime, sRes.getFinishTime()); - - // the expiration time for immediate reservation is the - // termination time - expTime = sRes.getFinishTime(); + else { // there resources available + + // gets the index of the entry closest to the termination of the + // reservation but whose time is not larger than the reservation's + // termination time + int tailIndex = (Integer)availObj[0]; + + // gets the list of PEs selected for the reservation + PERangeList selected = (PERangeList)availObj[1]; + + // allocates the list of PEs to the reservation + sRes.setPERangeList(selected); + + // updates the availability profile accordingly + allocateImmediatePERanges(tailIndex, selected, + currentTime, sRes.getFinishTime()); + + // the expiration time for immediate reservation is the + // termination time + expTime = sRes.getFinishTime(); + } } // It is not an immediate reservation else { @@ -396,71 +396,84 @@ userName + " user requires " + reservation.getNumPE() + " PEs from " + startTime + " to " + (startTime + duration) ); System.out.println("--> The resource cannot handle the reservation"); - - reservation.setStatus(Reservation.STATUS_FAILED); - response.setErrorCode(ARMessage.EC_OPERATION_FAILURE); - super.sendARMessage(response); - return; + success = false; } - - // gets the index of the entry closest to the start time - // of the reservation and whose time is smaller or equals - // to the reservation's start time - int anchorIndex = (Integer)availObj[0]; - - // gets the index of the entry closest to the termination of the - // reservation but whose time is not larger than the reservation's - // termination time - int tailIndex = (Integer)availObj[1]; - - // gets the list of PE ranges selected for the reservation - // and sets the reservation to use them - PERangeList selected = (PERangeList)availObj[2]; - sRes.setPERangeList(selected); - - // allocates the ranges and updates the availability profile - allocatePERanges(anchorIndex, tailIndex, selected, - startTime, sRes.getFinishTime()); - - // calculate the expiration time of the reservation - expTime = currentTime + commitPeriod_; - - // if the expiration time is greater than the start time of the - // reservation, then set the expiration time as the start time - if(expTime > startTime) { - expTime = startTime; + else { // there are resource available + + // gets the index of the entry closest to the start time + // of the reservation and whose time is smaller or equals + // to the reservation's start time + int anchorIndex = (Integer)availObj[0]; + + // gets the index of the entry closest to the termination of the + // reservation but whose time is not larger than the reservation's + // termination time + int tailIndex = (Integer)availObj[1]; + + // gets the list of PE ranges selected for the reservation + // and sets the reservation to use them + PERangeList selected = (PERangeList)availObj[2]; + sRes.setPERangeList(selected); + + // allocates the ranges and updates the availability profile + allocatePERanges(anchorIndex, tailIndex, selected, + startTime, sRes.getFinishTime()); + + // calculate the expiration time of the reservation + expTime = currentTime + commitPeriod_; + + // if the expiration time is greater than the start time of the + // reservation, then set the expiration time as the start time + if(expTime > startTime) { + expTime = startTime; + } } } - // if the start time of the reservation is equals to the current - // time, meaning that it is an immediate reservation, then start - // the reservation straight away. Therefore, sets the status to - // committed and sends an internal event to start the reservation - if(currentTime == startTime) { - sRes.setStatus(Reservation.STATUS_COMMITTED); - super.sendInternalEvent(GridSimTags.SCHEDULE_NOW, START_RESERVATION); + // resources are available and have been allocated for the reservation + if(success) { + + // if the start time of the reservation is equals to the current + // time, meaning that it is an immediate reservation, then start + // the reservation straight away. Therefore, sets the status to + // committed and sends an internal event to start the reservation + if(currentTime == startTime) { + sRes.setStatus(Reservation.STATUS_COMMITTED); + super.sendInternalEvent(GridSimTags.SCHEDULE_NOW, START_RESERVATION); + } + else { + sRes.setStatus(Reservation.STATUS_NOT_COMMITTED); + } + + sRes.setExpiryTime(expTime); + + // add the reservation into the reservation table and sends the + // response message to the requester + reservTable_.put(new Integer(sRes.getID()), sRes); + super.sendARMessage(response); + + // then send this into itself to check for expired reservations + super.sendInternalEvent(expTime - currentTime, + EXPIRY_TIME); + + //-------------- FOR DEBUGGING PURPOSES ONLY -------------- + + // Informs the listeners about the reservation that has been created + GridSim.notifyListeners(this.get_id(), AllocationAction.ITEM_SCHEDULED, true, sRes); + + //---------------------------------------------------------- } - else { - sRes.setStatus(Reservation.STATUS_NOT_COMMITTED); + else { // Creates a list of options + + // Gets availability information and provides it as options + AvailabilityInfo availability = + getAvailabilityInfo(startTime, Integer.MAX_VALUE); + + reservation.setStatus(Reservation.STATUS_FAILED); + reservation.setReservationOptions(availability); + response.setErrorCode(ARMessage.EC_OPERATION_FAILURE_BUT_OPTIONS); + super.sendARMessage(response); } - - sRes.setExpiryTime(expTime); - - // add the reservation into the reservation table and sends the - // response message to the requester - reservTable_.put(new Integer(sRes.getID()), sRes); - super.sendARMessage(response); - - // then send this into itself to check for expired reservations - super.sendInternalEvent(expTime - currentTime, - EXPIRY_TIME); - - //-------------- FOR DEBUGGING PURPOSES ONLY -------------- - - // Informs the listeners about the reservation that has been created - GridSim.notifyListeners(this.get_id(), AllocationAction.ITEM_SCHEDULED, true, sRes); - - //---------------------------------------------------------- } /** This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mar...@us...> - 2008-02-11 02:35:44
|
Revision: 95 http://gridsim.svn.sourceforge.net/gridsim/?rev=95&view=rev Author: marcos_dias Date: 2008-02-10 18:35:48 -0800 (Sun, 10 Feb 2008) Log Message: ----------- Bug fix in the method that collects information regarding the resources available at a given time. Repeated entries could be included in the resulting list. Modified Paths: -------------- branches/gridsim4.0-branch3/source/gridsim/gui/ResourceWindow.java branches/gridsim4.0-branch3/source/gridsim/turbo/ARParallelSpaceShared.java branches/gridsim4.0-branch3/source/gridsim/turbo/AvailabilityProfileEntry.java Modified: branches/gridsim4.0-branch3/source/gridsim/gui/ResourceWindow.java =================================================================== --- branches/gridsim4.0-branch3/source/gridsim/gui/ResourceWindow.java 2008-02-10 07:09:51 UTC (rev 94) +++ branches/gridsim4.0-branch3/source/gridsim/gui/ResourceWindow.java 2008-02-11 02:35:48 UTC (rev 95) @@ -147,7 +147,7 @@ private static final int WINDOW_HEIGHT = 350; private static final int SHIFT_X = 30; private static final int SHIFT_Y = 25; - private static final int SHIFT_BOTTOM = 15; + private static final int SHIFT_BOTTOM = 25; private static final float PROPORTION_LEFT_PANEL = 0.6f; private static final float PROPORTION_RIGHT_PANEL = 1f - PROPORTION_LEFT_PANEL; private static final int HEIGHT_COLOR_PANEL = 90; Modified: branches/gridsim4.0-branch3/source/gridsim/turbo/ARParallelSpaceShared.java =================================================================== --- branches/gridsim4.0-branch3/source/gridsim/turbo/ARParallelSpaceShared.java 2008-02-10 07:09:51 UTC (rev 94) +++ branches/gridsim4.0-branch3/source/gridsim/turbo/ARParallelSpaceShared.java 2008-02-11 02:35:48 UTC (rev 95) @@ -1804,15 +1804,12 @@ // a pointer to the last entry analysed (described above) AvailabilityProfileEntry tailEntry = null; - // the list of selected ranges - PERangeList intersectList = null; - // NOTE: freePERanges_ does not need to be cloned here as the // PERangeList.intersection() and selectPERangeList() methods will // create a new list of ranges with the intersection anyway. // For immediate gridlets or advance reservations, the start point // is the current list of PEs available - intersectList = resource_.getFreePERanges(); + PERangeList intersectList = resource_.getFreePERanges(); // if time is unknown, then make the current time the start time if(startTime < 0) @@ -1834,7 +1831,6 @@ } else { tailEntry = entry; - // Sep. 29, 2007 - Changed by Marcos // if the finish time is equals to the entry time, so there // is no need to check the intersection if(entryTime < finishTime) { @@ -1903,21 +1899,23 @@ while(iterProfile.hasNext()) { AvailabilityProfileEntry entry = iterProfile.next(); - anchorEntry = entry; - anchorIndex = availProfile_.indexOf(anchorEntry); - tailEntry = entry; - - // sets the start time as the time of the entry - potStartTime = entry.getTime(); - // calculates when the finish time will be if - // the gridlet is put at this position - potFinishTime = potStartTime + duration; // scan the profile until an entry with enough PEs is found if(entry.getNumPE() < reqPE) { continue; } else { + + anchorEntry = entry; + anchorIndex = availProfile_.indexOf(anchorEntry); + tailEntry = entry; + + // sets the start time as the time of the entry + potStartTime = entry.getTime(); + // calculates when the finish time will be if + // the gridlet is put at this position + potFinishTime = potStartTime + duration; + // if an entry with enough PEs is found, then scan the profile // from that point onwards analysing the intersection of // the ranges available in the entries until the @@ -2016,8 +2014,7 @@ // the list of selected ranges PERangeList intersectList = null; - - intersectList = null; + int length = availProfile_.size(); anchorEntry = tailEntry = availProfile_.getPrecedingEntry(startTime); @@ -2137,9 +2134,9 @@ // Update entries of the profile for(int index=0; index<tailIndex; index++) { AvailabilityProfileEntry entry = availProfile_.get(index); - if(entry.getTime() < startTime){ - continue; - } +// if(entry.getTime() < startTime){ +// continue; +// } PERangeList uptList = PERangeList.difference(entry.getPERanges(), selected); entry.setPERangeList(uptList); @@ -2186,27 +2183,44 @@ // entries in the availability profile. boolean addEntryAfterAnchor = false; - int updFrom = anchorIndex; - int updTo = tailIndex; - int anchorInsertPos = anchorIndex; - int tailInsertPos = tailIndex; + if (tailIndex > -1) { + AvailabilityProfileEntry tailEntry = availProfile_.get(tailIndex); + + if (tailEntry.getTime() == finishTime) { + addEntryAfterTail = false; + tailEntry.increaseGridlet(); + } + // If a new entry is required, then created it to be added + // to the profile + else { + // Creates a new entry to be added to the profile + newEntryAfterTail = new AvailabilityProfileEntry(finishTime); + newEntryAfterTail.setPERangeList(tailEntry.getPERanges().clone()); + tailIndex++; + } + } + else { + // Creates a new entry to be added to the profile + newEntryAfterTail = new AvailabilityProfileEntry(finishTime); + newEntryAfterTail.setPERangeList(resource_.getFreePERanges().clone()); + tailIndex++; + } + + if(addEntryAfterTail) { + availProfile_.add(tailIndex, newEntryAfterTail); + } if (anchorIndex > -1) { - AvailabilityProfileEntry anchorEntry = - availProfile_.get(anchorIndex); + AvailabilityProfileEntry anchorEntry = availProfile_.get(anchorIndex); double anchorTime = anchorEntry.getTime(); if ( anchorTime < startTime ) { addEntryAfterAnchor = true; - updFrom++; // Creates a new entry to be added to the profile newEntryAfterAnchor = new AvailabilityProfileEntry(startTime); - PERangeList difference = - PERangeList.difference(anchorEntry.getPERanges(), selected); - newEntryAfterAnchor.setPERangeList(difference); - // increment the tail index as a new anchor will be - // inserted before the new tail entry - tailInsertPos++; + newEntryAfterAnchor.setPERangeList(anchorEntry.getPERanges().clone()); + // increment the position where the new anchor will be added + anchorIndex++; } else if (anchorTime == startTime) { anchorEntry.increaseGridlet(); @@ -2217,58 +2231,25 @@ // Creates a new entry to be added to the profile newEntryAfterAnchor = new AvailabilityProfileEntry(startTime); - PERangeList difference = - PERangeList.difference(resource_.getFreePERanges(), selected); - newEntryAfterAnchor.setPERangeList(difference); - // increment the tail index as a new anchor will be - // inserted before the new tail entry - tailInsertPos++; - updFrom++; + newEntryAfterAnchor.setPERangeList(resource_.getFreePERanges().clone()); + // increment the position where the new anchor will be added + anchorIndex++; } - if (tailIndex > -1) { - AvailabilityProfileEntry tailEntry = - availProfile_.get(tailIndex); - - if (tailEntry.getTime() == finishTime) { - addEntryAfterTail = false; - updTo--; - tailEntry.increaseGridlet(); - } - // If a new entry is required, then created it to be added - // to the profile - else { - // Creates a new entry to be added to the profile - newEntryAfterTail = new AvailabilityProfileEntry(finishTime); - newEntryAfterTail.setPERangeList(tailEntry.getPERanges().clone()); - } - } - else { - // Creates a new entry to be added to the profile - newEntryAfterTail = new AvailabilityProfileEntry(finishTime); - newEntryAfterTail.setPERangeList(resource_.getFreePERanges().clone()); - } - + if(addEntryAfterAnchor) { + availProfile_.add(anchorIndex, newEntryAfterAnchor); + tailIndex++; + } + // Update entries of the profile if(tailIndex > -1) { - for(int index=updFrom; index<=updTo; index++){ + for(int index=anchorIndex; index<tailIndex; index++){ AvailabilityProfileEntry entry = availProfile_.get(index); PERangeList uptList = PERangeList.difference(entry.getPERanges(), selected); entry.setPERangeList(uptList); } } - - anchorInsertPos++; - tailInsertPos++; - - if(addEntryAfterAnchor) { - availProfile_.add(anchorInsertPos, newEntryAfterAnchor); - } - - if(addEntryAfterTail) { - availProfile_.add(tailInsertPos, newEntryAfterTail); - } } /** @@ -2283,15 +2264,16 @@ * specified by the requester. */ protected AvailabilityInfo getAvailabilityInfo(double startTime, int duration) { - + AvailabilityInfo list = new AvailabilityInfo(); int anchorIndex = -1; + double currentTime = GridSim.clock(); // if the user specified the start time as 0, it means that the // user is interested to know the availability starting from the // current time, or the time when the resource received this request if(startTime == 0) { - startTime = GridSim.clock(); + startTime = currentTime; } list.setStartTime(startTime); @@ -2305,48 +2287,51 @@ int length = availProfile_.size(); AvailabilityInfoEntry firstEntry = null; - anchorEntry = availProfile_.getPrecedingEntry(startTime); + anchorEntry = (startTime <= currentTime) ? null : + availProfile_.getPrecedingEntry(startTime); // if the entry is null, then it means that the reservation is // before the first entry of the profile, so the intersection list // has to start with the ranges of PEs currently available if (anchorEntry == null) { - PERangeList peList = (resource_.getFreePERanges() == null) ? null : - resource_.getFreePERanges().clone(); + PERangeList peList = (resource_.getFreePERanges() == null) ? + new PERangeList() : resource_.getFreePERanges().clone(); firstEntry = new AvailabilityInfoEntry(startTime, peList); } else { PERangeList newList = anchorEntry.getPERanges(); - if(newList != null) { - newList = newList.clone(); - } - firstEntry = new AvailabilityInfoEntry(startTime, newList); + newList = (newList != null) ? newList.clone() : new PERangeList(); + firstEntry = new AvailabilityInfoEntry(startTime, newList); anchorIndex = availProfile_.indexOf(anchorEntry); } list.add(firstEntry); + AvailabilityInfoEntry previousEntry = firstEntry; // Iterates the availability profile and adds all the entries // whose times are between start and finish time in the list - // to be returned. + // to be returned. It removes repeated entries. for(int i=anchorIndex+1; i<length; i++) { AvailabilityProfileEntry nextEntry = availProfile_.get(i); + if(nextEntry.getTime() <= startTime) + continue; if(nextEntry.getTime() > finishTime){ break; } else { PERangeList peList = nextEntry.getPERanges(); - if(peList != null) { - peList = peList.clone(); + peList = (peList != null) ? peList.clone() : new PERangeList(); + + if( !previousEntry.getAvailRanges().equals(peList)) { + AvailabilityInfoEntry tsEntry = + new AvailabilityInfoEntry(nextEntry.getTime(), peList); + list.add(tsEntry); + previousEntry = tsEntry; } - AvailabilityInfoEntry tsEntry = - new AvailabilityInfoEntry(nextEntry.getTime(), peList); - list.add(tsEntry); } } - - list.sort(); // sort the list before send it back + return list; } } Modified: branches/gridsim4.0-branch3/source/gridsim/turbo/AvailabilityProfileEntry.java =================================================================== --- branches/gridsim4.0-branch3/source/gridsim/turbo/AvailabilityProfileEntry.java 2008-02-10 07:09:51 UTC (rev 94) +++ branches/gridsim4.0-branch3/source/gridsim/turbo/AvailabilityProfileEntry.java 2008-02-11 02:35:48 UTC (rev 95) @@ -107,23 +107,6 @@ } /** - * Returns <tt>true</tt> if this entry has the same list of ranges of PEs - * as the entry provided. - * @param entry the entry whose ranges have to be compared - * @return <tt>true</tt> if the ranges are the same or false otherwise. - */ - public boolean hasSamePERanges(AvailabilityProfileEntry entry) { - boolean result = false; - if(ranges_ == null && entry.ranges_ == null) { - result = true; - } - else if(ranges_ != null) { - result = ranges_.equals(entry.ranges_); - } - return result; - } - - /** * Creates a string representation of this entry */ public String toString(){ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mar...@us...> - 2008-02-10 07:09:47
|
Revision: 94 http://gridsim.svn.sourceforge.net/gridsim/?rev=94&view=rev Author: marcos_dias Date: 2008-02-09 23:09:51 -0800 (Sat, 09 Feb 2008) Log Message: ----------- This update contains small bug fixes and improvements: + The advance reservation policy and the conservative backfilling could present overlapping ranges of available processing elements. Although that did not affect the resource allocation results, that could lead to infinite loops on software that queried the resource availability. + Small changes in the availability information objects and the lists of PEs. Modified Paths: -------------- branches/gridsim4.0-branch3/source/gridsim/turbo/ARParallelSpaceShared.java branches/gridsim4.0-branch3/source/gridsim/turbo/CBParallelSpaceShared.java branches/gridsim4.0-branch3/source/gridsim/turbo/EBParallelSpaceShared.java Modified: branches/gridsim4.0-branch3/source/gridsim/turbo/ARParallelSpaceShared.java =================================================================== --- branches/gridsim4.0-branch3/source/gridsim/turbo/ARParallelSpaceShared.java 2008-02-10 06:19:19 UTC (rev 93) +++ branches/gridsim4.0-branch3/source/gridsim/turbo/ARParallelSpaceShared.java 2008-02-10 07:09:51 UTC (rev 94) @@ -261,7 +261,10 @@ Sim_event ev = new Sim_event(); while ( Sim_system.running() ) { super.sim_get_next(ev); - processEvent(ev); + if (ev.get_src() == super.myId_) + processEvent(ev); + else + processOtherEvent(ev); } // CHECK for ANY INTERNAL EVENTS WAITING TO BE PROCESSED @@ -906,39 +909,32 @@ private void processEvent(Sim_event ev) { // handle an internal event - if(ev.get_src() == super.myId_) { - double currentTime = GridSim.clock(); + double currentTime = GridSim.clock(); - switch(ev.get_tag()) { - // time to update the schedule, finish gridlets, - // finish reservations, start reservations and start gridlets - case GRIDLET_FINISHED: - case START_RESERVATION: - case FINISH_RESERVATION: - if(currentTime > lastScheduleUpdate_) { - updateSchedule(); - } - lastScheduleUpdate_ = currentTime; - break; + switch(ev.get_tag()) { + // time to update the schedule, finish gridlets, + // finish reservations, start reservations and start gridlets + case GRIDLET_FINISHED: + case START_RESERVATION: + case FINISH_RESERVATION: + if(currentTime > lastScheduleUpdate_) { + updateSchedule(); + } + lastScheduleUpdate_ = currentTime; + break; - // checks the expiry time for a given gridlet - case EXPIRY_TIME: - if(currentTime > lastCheckExpiryTime_) { - checkExpiryTime(); - } - lastCheckExpiryTime_ = currentTime; - break; + // checks the expiry time for a given gridlet + case EXPIRY_TIME: + if(currentTime > lastCheckExpiryTime_) { + checkExpiryTime(); + } + lastCheckExpiryTime_ = currentTime; + break; - default: - System.out.println(super.get_name() + ".processEvent():" + - "could not handle the event with tag #" + ev.get_tag()); - break; - } - } - else { - System.out.println(super.get_name() + ".processEvent():" + - "could not handle the event with tag #" + ev.get_tag()); - } + default: + processOtherEvent(ev); + break; + } } /** @@ -2309,20 +2305,7 @@ int length = availProfile_.size(); AvailabilityInfoEntry firstEntry = null; - double entryTime; - - Iterator<AvailabilityProfileEntry> iterProfile = - availProfile_.iterator(); - while(iterProfile.hasNext()) { - AvailabilityProfileEntry entry = iterProfile.next(); - entryTime = entry.getTime(); - if(entryTime > startTime) { - break; - } - else { - anchorEntry = entry; - } - } + anchorEntry = availProfile_.getPrecedingEntry(startTime); // if the entry is null, then it means that the reservation is // before the first entry of the profile, so the intersection list @@ -2346,24 +2329,20 @@ // Iterates the availability profile and adds all the entries // whose times are between start and finish time in the list - // to be returned. It removes duplicated entries - AvailabilityProfileEntry previousEntry = null; + // to be returned. for(int i=anchorIndex+1; i<length; i++) { AvailabilityProfileEntry nextEntry = availProfile_.get(i); if(nextEntry.getTime() > finishTime){ break; } else { - if( !(previousEntry != null && previousEntry.hasSamePERanges(nextEntry)) ) { - PERangeList peList = nextEntry.getPERanges(); - if(peList != null) { - peList = peList.clone(); - } - AvailabilityInfoEntry tsEntry = - new AvailabilityInfoEntry(nextEntry.getTime(), peList); - list.add(tsEntry); - } - previousEntry = nextEntry; + PERangeList peList = nextEntry.getPERanges(); + if(peList != null) { + peList = peList.clone(); + } + AvailabilityInfoEntry tsEntry = + new AvailabilityInfoEntry(nextEntry.getTime(), peList); + list.add(tsEntry); } } Modified: branches/gridsim4.0-branch3/source/gridsim/turbo/CBParallelSpaceShared.java =================================================================== --- branches/gridsim4.0-branch3/source/gridsim/turbo/CBParallelSpaceShared.java 2008-02-10 06:19:19 UTC (rev 93) +++ branches/gridsim4.0-branch3/source/gridsim/turbo/CBParallelSpaceShared.java 2008-02-10 07:09:51 UTC (rev 94) @@ -120,6 +120,9 @@ // the last time when the schedule updated was called private double lastScheduleUpdate_; + + // a tag to indicate that a gridlet has finished + private static final int GRIDLET_FINISHED = 10; /** * Allocates a new <tt>CBParallelSpaceShared</tt> object @@ -178,13 +181,17 @@ } // Internal Event if the event source is this entity - if (ev.get_src() == super.myId_) { + if (ev.get_src() == super.myId_ && + ev.get_tag() == GRIDLET_FINISHED) { double currentTime = GridSim.clock(); if(currentTime > lastScheduleUpdate_) { updateSchedule(); } lastScheduleUpdate_ = currentTime; } + else { + processOtherEvent(ev); + } } // CHECK for ANY INTERNAL EVENTS WAITING TO BE PROCESSED @@ -514,7 +521,7 @@ // then send this event to itself to update the queues after // this gridlet's completion time - super.sendInternalEvent(executionTime); + super.sendInternalEvent(executionTime, GRIDLET_FINISHED); return true; } @@ -933,7 +940,7 @@ // change Gridlet status gridlet.setStatus(Gridlet.INEXEC); - super.sendInternalEvent(gridlet.getFinishTime()-currentTime); + super.sendInternalEvent(gridlet.getFinishTime()-currentTime, GRIDLET_FINISHED); } } resource_.setPEsBusy(allocatedRanges); Modified: branches/gridsim4.0-branch3/source/gridsim/turbo/EBParallelSpaceShared.java =================================================================== --- branches/gridsim4.0-branch3/source/gridsim/turbo/EBParallelSpaceShared.java 2008-02-10 06:19:19 UTC (rev 93) +++ branches/gridsim4.0-branch3/source/gridsim/turbo/EBParallelSpaceShared.java 2008-02-10 07:09:51 UTC (rev 94) @@ -99,6 +99,9 @@ // used only to set the extraPEs_ back to the default value private PERangeList allPEs_; + + // a tag to indicate that a gridlet has finished + private static final int GRIDLET_FINISHED = 10; /** * Allocates a new <tt>EBParallelSpaceShared</tt> object @@ -161,13 +164,17 @@ } // Internal Event if the event source is this entity - if (ev.get_src() == super.myId_) { + if (ev.get_src() == super.myId_ && + ev.get_tag() == GRIDLET_FINISHED) { double currentTime = GridSim.clock(); if(currentTime > lastScheduleUpdate_) { updateSchedule(); } lastScheduleUpdate_ = currentTime; } + else { + processOtherEvent(ev); + } } // CHECK for ANY INTERNAL EVENTS WAITING TO BE PROCESSED @@ -468,7 +475,7 @@ // then send this event to itself to update the queues after // this gridlet's completion time - super.sendInternalEvent(executionTime); + super.sendInternalEvent(executionTime, GRIDLET_FINISHED); return true; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mar...@us...> - 2008-02-10 06:19:14
|
Revision: 93 http://gridsim.svn.sourceforge.net/gridsim/?rev=93&view=rev Author: marcos_dias Date: 2008-02-09 22:19:19 -0800 (Sat, 09 Feb 2008) Log Message: ----------- This update contains small bug fixes and improvements: + The advance reservation policy and the conservative backfilling could present overlapping ranges of available processing elements. Although that did not affect the resource allocation results, that could lead to infinite loops on software that queried the resource availability. + Small changes in the availability information objects and the lists of PEs. Modified Paths: -------------- branches/gridsim4.0-branch3/source/gridsim/turbo/ARParallelSpaceShared.java Modified: branches/gridsim4.0-branch3/source/gridsim/turbo/ARParallelSpaceShared.java =================================================================== --- branches/gridsim4.0-branch3/source/gridsim/turbo/ARParallelSpaceShared.java 2008-02-10 06:04:30 UTC (rev 92) +++ branches/gridsim4.0-branch3/source/gridsim/turbo/ARParallelSpaceShared.java 2008-02-10 06:19:19 UTC (rev 93) @@ -1569,10 +1569,10 @@ } resource_.setPEsAvailable(releasedRanges); - if(PERangeList.containsOverlappingRanges(resource_.getFreePERanges())) { - System.out.println("Overlap! Ranges = " + resource_.getFreePERanges()); - System.exit(1); - } +// if(PERangeList.containsOverlappingRanges(resource_.getFreePERanges())) { +// System.out.println("Overlap! Ranges = " + resource_.getFreePERanges()); +// System.exit(1); +// } itemsStarted = startReservation(currentTime); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mar...@us...> - 2008-02-10 06:04:25
|
Revision: 92 http://gridsim.svn.sourceforge.net/gridsim/?rev=92&view=rev Author: marcos_dias Date: 2008-02-09 22:04:30 -0800 (Sat, 09 Feb 2008) Log Message: ----------- This update contains small bug fixes and improvements: + The advance reservation policy and the conservative backfilling could present overlapping ranges of available processing elements. Although that did not affect the resource allocation results, that could lead to infinite loops on software that queried the resource availability. + Small changes in the availability information objects and the lists of PEs. Modified Paths: -------------- branches/gridsim4.0-branch3/source/gridsim/turbo/ARParallelSpaceShared.java branches/gridsim4.0-branch3/source/gridsim/turbo/AvailabilityInfo.java branches/gridsim4.0-branch3/source/gridsim/turbo/AvailabilityInfoEntry.java branches/gridsim4.0-branch3/source/gridsim/turbo/AvailabilityProfile.java branches/gridsim4.0-branch3/source/gridsim/turbo/CBParallelSpaceShared.java branches/gridsim4.0-branch3/source/gridsim/turbo/EBParallelSpaceShared.java branches/gridsim4.0-branch3/source/gridsim/turbo/PERangeList.java branches/gridsim4.0-branch3/source/gridsim/turbo/ReservationRequester.java branches/gridsim4.0-branch3/source/gridsim/turbo/TResourceCharacteristics.java Modified: branches/gridsim4.0-branch3/source/gridsim/turbo/ARParallelSpaceShared.java =================================================================== --- branches/gridsim4.0-branch3/source/gridsim/turbo/ARParallelSpaceShared.java 2008-02-08 03:25:23 UTC (rev 91) +++ branches/gridsim4.0-branch3/source/gridsim/turbo/ARParallelSpaceShared.java 2008-02-10 06:04:30 UTC (rev 92) @@ -156,9 +156,6 @@ // the last time when the schedule update was called private double lastScheduleUpdate_; - - // last time when a reservation started - private double lastReservationStart_; // last time the expiration of reservations was checked private double lastCheckExpiryTime_; @@ -452,8 +449,8 @@ super.sendARMessage(response); // then send this into itself to check for expired reservations - int roundUpTime = (int) (expTime - currentTime) + 1; - super.sendInternalEvent(roundUpTime, EXPIRY_TIME); + super.sendInternalEvent(expTime - currentTime, + EXPIRY_TIME); //-------------- FOR DEBUGGING PURPOSES ONLY -------------- @@ -605,8 +602,8 @@ sRes.setStatus(Reservation.STATUS_COMMITTED); // then send this into itself to start the reservation - int roundUpTime = (int) (sRes.getStartTime() - currentTime) + 1; - super.sendInternalEvent(roundUpTime, START_RESERVATION); + super.sendInternalEvent(sRes.getStartTime() - currentTime, + START_RESERVATION); } // sends the response message with no error @@ -614,7 +611,8 @@ //-------------- FOR DEBUGGING PURPOSES ONLY -------------- - GridSim.notifyListeners(this.get_id(), AllocationAction.ITEM_STATUS_CHANGED, true, sRes); + GridSim.notifyListeners(this.get_id(), + AllocationAction.ITEM_STATUS_CHANGED, true, sRes); //---------------------------------------------------------- } @@ -912,8 +910,11 @@ double currentTime = GridSim.clock(); switch(ev.get_tag()) { - // time to check the finish time of a Gridlet + // time to update the schedule, finish gridlets, + // finish reservations, start reservations and start gridlets case GRIDLET_FINISHED: + case START_RESERVATION: + case FINISH_RESERVATION: if(currentTime > lastScheduleUpdate_) { updateSchedule(); } @@ -928,22 +929,6 @@ lastCheckExpiryTime_ = currentTime; break; - // time to start the reservation - case START_RESERVATION: - if(currentTime > lastReservationStart_) { - startReservation(); - } - lastReservationStart_ = currentTime; - break; - - // time to start the reservation - case FINISH_RESERVATION: - if(currentTime > lastScheduleUpdate_) { - finishReservation(); - } - lastScheduleUpdate_ = currentTime; - break; - default: System.out.println(super.get_name() + ".processEvent():" + "could not handle the event with tag #" + ev.get_tag()); @@ -970,7 +955,6 @@ expiryTable_ = new LinkedHashMap<Integer, SSReservation>(); orderStartTime_ = new OrderGridletByStartTime(); lastScheduleUpdate_ = -1; - lastReservationStart_ = -1; lastCheckExpiryTime_ = -1; ratingPE_ = 0; } @@ -1214,8 +1198,7 @@ // then send this event to itself to update the queues after // this gridlet's completion time - int roundUpTime = (int)(executionTime + 1); - super.sendInternalEvent(roundUpTime, GRIDLET_FINISHED); + super.sendInternalEvent(executionTime, GRIDLET_FINISHED); return true; } @@ -1552,18 +1535,20 @@ * gridlets in the waiting list that should start execution. It also * removes old entries from the availability profile. */ - private void updateSchedule(){ + private void updateSchedule() { + int itemsFinished = 0; double currentTime = GridSim.clock(); - int gridletFinished = 0; - int gridletStarted = 0; - boolean reserved; + int itemsStarted = 0; + + // finishes the advance reservations first + itemsFinished = finishReservation(currentTime); + boolean reserved; // remove all Gridlets that have already completed from // the queue of running Gridlets PERangeList releasedRanges = new PERangeList(); - LinkedList<SSGridlet> grlsCompleted = new LinkedList<SSGridlet>(); - + // iterates the list to check what has finished Iterator<SSGridlet> iter = runningGridlets_.iterator(); while (iter.hasNext()) { @@ -1577,41 +1562,44 @@ if(!reserved) { releasedRanges.addAll(gridlet.getPERangeList().clone()); } - grlsCompleted.add(gridlet); gridletFinish(gridlet, Gridlet.SUCCESS); iter.remove(); - gridletFinished++; - } - } + itemsFinished++; + } + } + resource_.setPEsAvailable(releasedRanges); + + if(PERangeList.containsOverlappingRanges(resource_.getFreePERanges())) { + System.out.println("Overlap! Ranges = " + resource_.getFreePERanges()); + System.exit(1); + } - resource_.setPEsAvailable(releasedRanges); - + itemsStarted = startReservation(currentTime); + // remove past entries from the availability profile cleanAvailabilityProfile(currentTime); - if (gridletFinished > 0) { - // Start the execution of Gridlets that are queued and whose - // potential start execution time is smaller than current time - gridletStarted = startQueuedGridlets(); - } - + // Start the execution of Gridlets that are queued and whose + // potential start execution time is smaller than current time + itemsStarted += startQueuedGridlets(); + //---------------- USED FOR DEBUGGING PURPOSES ONLY -------------------- // If a gridlet has started execution or one has finished, // then inform the listeners - if(gridletStarted > 0 || gridletFinished > 0){ - GridSim.notifyListeners(this.get_id(), AllocationAction.ITEM_COMPLETED, - true, grlsCompleted); + if(itemsStarted > 0 || itemsFinished > 0){ + GridSim.notifyListeners(this.get_id(), AllocationAction.SCHEDULE_CHANGED, true); } } /** * This method is called to start a reservation and consequently update * the availability profile. + * @refTime the reservations whose start time is smaller + * or equals to refTime will be started */ - private void startReservation() { + private int startReservation(double refTime) { - double currentTime = GridSim.clock(); LinkedList<SSReservation> startedReservations = new LinkedList<SSReservation>(); PERangeList allocatedRanges = new PERangeList(); int numStartedRes = 0; @@ -1620,7 +1608,7 @@ while(iterRes.hasNext()) { SSReservation sRes = iterRes.next(); - if(sRes.getStartTime() <= currentTime && + if(sRes.getStartTime() <= refTime && sRes.getStatus() == Reservation.STATUS_COMMITTED) { // Start the reservation and update the ranges of @@ -1630,16 +1618,13 @@ allocatedRanges.addAll(sRes.getPERangeList().clone()); startedReservations.add(sRes); - int roundUpTime = (int)(sRes.getFinishTime()-currentTime)+1; - super.sendInternalEvent(roundUpTime, FINISH_RESERVATION); + super.sendInternalEvent(sRes.getFinishTime()-refTime, + FINISH_RESERVATION); numStartedRes++; } } - // remove past entries from the availability profile - cleanAvailabilityProfile(currentTime); - // if any reservation has been started, then update // the list of PEs available at the moment and start // the gridlets in the queue that can be started @@ -1653,12 +1638,6 @@ // notify the listeners GridSim.notifyListeners(this.get_id(), AllocationAction.ITEM_STATUS_CHANGED, true, startedReservations); - - //------------------------------------------------------------------ - - startQueuedGridlets(); - - //-------------- USED FOR DEBUGGING PURPOSES ONLY ------------------ // If a gridlet has started execution or one has finished, // then inform the listeners @@ -1666,16 +1645,19 @@ //------------------------------------------------------------------ } + + return numStartedRes; } /** * This method is called to finish a reservation and consequently update * the availability profile. - * @param reservation the reservation to be finished + * @param refTime the time reference to check what reservations should + * be finished. All reservations whose finish time is smaller or + * equals to refTime will be completed + * @return the number of reservations completed */ - private void finishReservation() { - - double currentTime = GridSim.clock(); + private int finishReservation(double refTime) { int reservationFinished = 0; // remove all reservations that have already completed @@ -1684,7 +1666,7 @@ Iterator<SSReservation> iterRes = reservTable_.values().iterator(); while(iterRes.hasNext()) { SSReservation sRes = iterRes.next(); - if(sRes.getFinishTime() <= currentTime) { + if(sRes.getFinishTime() <= refTime) { // Finish the reservation and include ranges in the // list of ranges to be released sRes.setStatus(Reservation.STATUS_FINISHED); @@ -1694,16 +1676,11 @@ expiryTable_.put(sRes.getID(), sRes); } } - - // remove past entries from the availability profile - cleanAvailabilityProfile(currentTime); // returns the ranges to the list of current available ranges resource_.setPEsAvailable(releasedRanges); - - if(reservationFinished > 0) { - startQueuedGridlets(); + if(reservationFinished > 0) { //------------- USED FOR DEBUGGING PURPOSES ONLY ------------------ @@ -1713,6 +1690,8 @@ //----------------------------------------------------------------- } + + return reservationFinished; } /** @@ -1726,6 +1705,13 @@ Iterator<AvailabilityProfileEntry> iterProfile = availProfile_.iterator(); while(iterProfile.hasNext()) { AvailabilityProfileEntry entry = iterProfile.next(); + +// if(PERangeList.containsOverlappingRanges(entry.getPERanges())) { +// System.out.println(" Profile entry at time " + entry.getTime() + +// " contains overlapping ranges. Ranges = " + entry.getPERanges()); +// System.exit(0); +// } + if(entry.getTime() <= referenceTime){ iterProfile.remove(); } @@ -1766,11 +1752,12 @@ // change Gridlet status gridlet.setStatus(Gridlet.INEXEC); - int roundUpTime = (int)(gridlet.getFinishTime()-currentTime)+1; - super.sendInternalEvent(roundUpTime, GRIDLET_FINISHED); + super.sendInternalEvent(gridlet.getFinishTime()-currentTime, + GRIDLET_FINISHED); } } - resource_.setPEsBusy(allocatedRanges); + + resource_.setPEsBusy(allocatedRanges); return gridletStarted++; } @@ -1969,6 +1956,9 @@ } } + if(intersectList == null || intersectList.getNumPE() < reqPE) + return null; + anchorIndex = availProfile_.indexOf(anchorEntry); tailIndex = availProfile_.indexOf(tailEntry); @@ -2033,20 +2023,8 @@ intersectList = null; int length = availProfile_.size(); - double entryTime; - - Iterator<AvailabilityProfileEntry> iterProfile = availProfile_.iterator(); - while(iterProfile.hasNext()) { - AvailabilityProfileEntry entry = iterProfile.next(); - entryTime = entry.getTime(); - if(entryTime > startTime) { - break; - } - else { - anchorEntry = entry; - tailEntry = entry; - } - } + + anchorEntry = tailEntry = availProfile_.getPrecedingEntry(startTime); // if the entry is null, then it means that the reservation is // before the first entry of the profile, so the intersection list @@ -2125,12 +2103,12 @@ // to represent its completion time. This reduces the number of // entries in the availability profile boolean addEntryAfterTail = true; - int updTo = tailIndex; if(tailIndex == -1) { // Creates a new entry to be added to the profile newEntryAfterTail = new AvailabilityProfileEntry(finishTime); newEntryAfterTail.setPERangeList(resource_.getFreePERanges().clone()); + tailIndex++; } else { // get the tail entry (that is, the closest entry @@ -2140,7 +2118,6 @@ if (tailEntry.getTime() == finishTime) { addEntryAfterTail = false; - updTo--; tailEntry.increaseGridlet(); } // If a new entry is required, then add it to the profile @@ -2153,11 +2130,16 @@ // Creates a new entry to be added to the profile newEntryAfterTail = new AvailabilityProfileEntry(finishTime); newEntryAfterTail.setPERangeList(listTail); + tailIndex++; } } + + if(addEntryAfterTail) { + availProfile_.add(tailIndex, newEntryAfterTail); + } // Update entries of the profile - for(int index=0; index<=updTo; index++) { + for(int index=0; index<tailIndex; index++) { AvailabilityProfileEntry entry = availProfile_.get(index); if(entry.getTime() < startTime){ continue; @@ -2167,12 +2149,9 @@ entry.setPERangeList(uptList); } - if(addEntryAfterTail) { - availProfile_.add(tailIndex + 1, newEntryAfterTail); - } - // subtract the selected ranges from the currently free ranges resource_.setPEsBusy(selected); + } /** @@ -2295,7 +2274,7 @@ availProfile_.add(tailInsertPos, newEntryAfterTail); } } - + /** * This method returns a list that corresponds to the free time slots * in the scheduling queue managed by this scheduler or @@ -2307,7 +2286,7 @@ * entries that correspond to the availability profile between the times * specified by the requester. */ - private AvailabilityInfo getAvailabilityInfo(double startTime, int duration) { + protected AvailabilityInfo getAvailabilityInfo(double startTime, int duration) { AvailabilityInfo list = new AvailabilityInfo(); int anchorIndex = -1; Modified: branches/gridsim4.0-branch3/source/gridsim/turbo/AvailabilityInfo.java =================================================================== --- branches/gridsim4.0-branch3/source/gridsim/turbo/AvailabilityInfo.java 2008-02-08 03:25:23 UTC (rev 91) +++ branches/gridsim4.0-branch3/source/gridsim/turbo/AvailabilityInfo.java 2008-02-10 06:04:30 UTC (rev 92) @@ -8,7 +8,6 @@ package gridsim.turbo; import java.util.ArrayList; -import java.util.Collection; import java.util.Collections; import java.util.Iterator; @@ -28,11 +27,9 @@ * @see ARParallelSpaceShared#handleQueryAvailability(ARMessage) */ -public class AvailabilityInfo { +public class AvailabilityInfo extends ArrayList<AvailabilityInfoEntry> { private static final long serialVersionUID = -3951650752024908016L; - - private ArrayList<AvailabilityInfoEntry> list_; private double startTime_; private double finishTime_; @@ -42,7 +39,7 @@ * Default constructor. */ public AvailabilityInfo() { - list_ = new ArrayList<AvailabilityInfoEntry>(); + super(); startTime_ = UNKNOWN; finishTime_ = UNKNOWN; } @@ -60,7 +57,7 @@ * Returns the end time of this list. * @return the end time */ - public double getEndTime() { + public double getFinishTime() { return finishTime_; } @@ -81,145 +78,21 @@ } /** - * Adds the specified element to this list. - * @param entry the entry to be added to this list - * @return <tt>true - */ - public boolean add(AvailabilityInfoEntry entry) { - if(entry == null) { - return false; - } - else { - list_.add(entry); - } - return true; - } - - /** * Sorts the entries of this availability info object. */ public void sort() { - Collections.sort(list_); + Collections.sort(this); } /** - * Adds all of the elements in the specified Collection to this list, - * The behaviour of this operation is undefined if the specified - * Collection is modified while the operation is in progress. - * (This implies that the behaviour of this call is undefined if the - * specified Collection is this list, and this list is nonempty.) - * @param collection the collection to be included in this list - * @return <tt>true<tt> if the collection has been added successfully - * or <tt>false</tt> otherwise. - */ - public boolean addAll(Collection<? extends AvailabilityInfoEntry> collection) { - boolean result = true; - - // adds the collection to the list and sets the start - // and finish time again - if(collection != null && !collection.isEmpty()) { - list_.addAll(collection); - } - return result; - } - - /** - * Removes all elements from the list. - */ - public void clear() { - list_.clear(); - } - - /** - * Returns a shallow copy of this list. - * (The elements themselves are not copied.) - */ - public Object clone() { - return list_.clone(); - } - - /** - * Returns <tt>true</tt> if this list contains the specified element. - * @param entry the entry whose presence in this List is to be tested. - * @return <tt>true</tt> if the specified element is present; - * <tt>false</tt> otherwise. - */ - public boolean contains(Object entry) { - return list_.contains(entry); - } - - /** - * Returns the element at the specified position in this list. - * @param index the index of the element to return - * @return the element at the specified position in this list. - */ - public AvailabilityInfoEntry get(int index) { - return list_.get(index); - } - - /** - * Searches for the first occurence of the given argument, - * testing for equality using the equals method. - * @param entry the entry whose index is to be returned - * @return the index of the first occurrence of the argument - * in this list; returns <tt>-1</tt> if the object is not found. - */ - public int indexOf(Object entry) { - return list_.indexOf(entry); - } - - /** - * Tests if this list has no elements. - * @return <tt>true</tt> if the list has no elements. - */ - public boolean isEmpty() { - return list_.isEmpty(); - } - - /** - * Returns an iterator over the elements in this list in proper sequence. - * @return the iterator. - */ - public Iterator<AvailabilityInfoEntry> iterator() { - return list_.iterator(); - } - - /** - * Removes the element at a given index - * @param index the index of the element to be removed - * @return the removed element. - */ - public AvailabilityInfoEntry remove(int index) { - return list_.remove(index); - } - - /** - * Removes a given element from the list. - * @param entry the entry to be removed - * @return <tt>true</tt> if the collection contained the - * specified entry. - */ - public boolean remove(Object entry) { - return list_.remove(entry); - } - - /** - * Returns the size of this list. - * @return the size of this list - */ - public int size() { - return list_.size(); - } - - /** * Returns the entry whose time is closest to the <tt>time</tt> given but * smaller, or whose time is equals to <tt>time</tt> * @param time the time to be used to search for the entry * @return the entry whose time is closest to the <tt>time</tt> given but * smaller, or whose time is equals to <tt>time</tt> */ - private AvailabilityInfoEntry getPrecedingEntry(double time) { - Iterator<AvailabilityInfoEntry> it = list_.iterator(); + protected AvailabilityInfoEntry getPrecedingEntry(double time) { + Iterator<AvailabilityInfoEntry> it = super.iterator(); AvailabilityInfoEntry preceding = null; while(it.hasNext()) { @@ -273,32 +146,33 @@ double potStartTime = -1; // keep the potential start time of the request double potFinishTime = -1; // store the gridlet's expected finish time - int length = list_.size(); + int length = super.size(); anchorEntry = getPrecedingEntry(readyTime); - int firstAnchorIndex = list_.indexOf(anchorEntry); + int firstAnchorIndex = super.indexOf(anchorEntry); if(firstAnchorIndex == -1) firstAnchorIndex = 0; for(int j=firstAnchorIndex; j<length; j++) { - AvailabilityInfoEntry entry = list_.get(j); - anchorIndex = list_.indexOf(entry); + AvailabilityInfoEntry entry = super.get(j); + anchorIndex = super.indexOf(entry); - // sets the start time as the time of the entry - if(entry.getTime() < readyTime) - potStartTime = readyTime; - else - potStartTime = entry.getTime(); - - // calculates when the finish time will be if - // the gridlet is put at this position - potFinishTime = potStartTime + duration; - // scan the profile until an entry with enough PEs is found if(entry.getNumPE() < reqPE) { continue; } else { + + // sets the start time as the time of the entry + if(entry.getTime() < readyTime) + potStartTime = readyTime; + else + potStartTime = entry.getTime(); + + // calculates when the finish time will be if + // the gridlet is put at this position + potFinishTime = potStartTime + duration; + // if an entry with enough PEs is found, then scan the list // from that point onwards analysing the intersection of // the ranges available in the entries until the @@ -309,7 +183,7 @@ // the anchor until the end of the profile or until // the entries are further than the expected completion time for(int i=anchorIndex+1; i<length; i++){ - AvailabilityInfoEntry nextEntry = list_.get(i); + AvailabilityInfoEntry nextEntry = super.get(i); if(nextEntry.getTime() > potFinishTime){ break; } @@ -341,17 +215,184 @@ return potStartTime; } + + /** + * This method checks whether a given request with hard deadline + * can be scheduled or not. The method verifies whether there are enough + * processing elements at the start time to serve the request and + * whether enough elements will be available over the request's duration. + * @param startTime the start time of the request. + * @param duration the duration of the request. + * @param reqPE the number of processing elements required. + * @return <tt>true</tt> if the request can be scheduled, + * or <tt>false</tt> otherwise. + */ + public boolean canSchedule(double startTime, int duration, int reqPE) { + + // calculate the reservation's finish time + double finishTime = startTime + duration; + + // a pointer to the anchor entry (described above) + AvailabilityInfoEntry anchorEntry = null; + // the list of selected ranges + PERangeList intersectList = null; + + intersectList = null; + int length = super.size(); + double entryTime; + + int anchorIndex = -1; + + Iterator<AvailabilityInfoEntry> it = super.iterator(); + while(it.hasNext()) { + AvailabilityInfoEntry entry = it.next(); + entryTime = entry.getTime(); + if(entryTime > startTime) { + break; + } + else { + anchorEntry = entry; + } + } + + intersectList = (anchorEntry != null ) ? + anchorEntry.getAvailRanges().clone() : null; + + if(intersectList == null || intersectList.getNumPE() < reqPE) { + // there are not enough PEs available to serve the + // advance reservation request, then returns null + return false; + } + + anchorIndex = super.indexOf(anchorEntry); + + // Look for the intersection of available ranges from + // the anchor until the end of the profile or until + // the entries are further than the expected completion time + for(int i=anchorIndex+1; i<length; i++) { + AvailabilityInfoEntry nextEntry = super.get(i); + if(nextEntry.getTime() > finishTime){ + break; + } + else { + // if the finish time is equals to the entry time, so there + // is no need to check the intersection + if(nextEntry.getTime() < finishTime) { + intersectList = PERangeList.intersection(intersectList, + nextEntry.getAvailRanges()); + } + } + + if(intersectList == null || intersectList.getNumPE() < reqPE) { + // there are not enough PEs available to serve the + // advance reservation request, then returns null + return false; + } + } + + return true; + } + /** + * This method checks whether a given request with hard deadline + * can be scheduled or not. The method verifies whether there are enough + * processing elements during ready time until the deadline for the + * specified duration. + * @param readyTime the start time of the request. + * @param deadline the deadline of the request + * @param duration the duration of the request. + * @param reqPE the number of processing elements required. + * @return <tt>true</tt> if the request can be scheduled, + * or <tt>false</tt> otherwise. + */ + public boolean canSchedule(double readyTime, double deadline, + int duration, int reqPE) { + + if(duration < deadline - readyTime) { + System.out.println("AvailabilityInfo.canSchedule(): Duration cannot " + + "be smaller than (deadline - readyTime)."); + return false; + } + else if(deadline < readyTime) { + System.out.println("AvailabilityInfo.canSchedule(): Deadline cannot " + + "be smaller than readyTime."); + return false; + } + + // the list of selected ranges + PERangeList intersectList = null; + int length = super.size(); + double entryTime; + + int anchorIndex = -1; + + Iterator<AvailabilityInfoEntry> it = super.iterator(); + while(it.hasNext()) { + AvailabilityInfoEntry entry = it.next(); + entryTime = entry.getTime(); + if(entryTime < readyTime) { + continue; + } + + // calculate the reservation's finish time + double finishTime = entryTime + duration; + if(finishTime > deadline) { + return false; + } + + if(entry.getNumPE() < reqPE) { + continue; + } + else { + anchorIndex = super.indexOf(entry); + intersectList = entry.getAvailRanges().clone(); + + // Look for the intersection of available ranges from + // the anchor until the end of the profile or until + // the entries are further than the expected completion time + for(int i=anchorIndex+1; i<length; i++) { + AvailabilityInfoEntry nextEntry = super.get(i); + if(nextEntry.getTime() > finishTime){ + break; + } + else { + // if the finish time is equals to the entry time, so there + // is no need to check the intersection + if(nextEntry.getTime() < finishTime) { + intersectList = PERangeList.intersection(intersectList, + nextEntry.getAvailRanges()); + } + } + + if(intersectList == null || intersectList.getNumPE() < reqPE) { + // there are not enough PEs available to serve the + // advance reservation request, then returns null + break; + } + } + } + } + + if(intersectList == null || intersectList.getNumPE() < reqPE) { + // there are not enough PEs available to serve the + // advance reservation request, then returns null + return false; + } + + return true; + } + + /** * Creates a string representation of the list * @return a string representation */ public String toString() { String result = "Availability={\n"; - for(AvailabilityInfoEntry entry : list_){ + for(AvailabilityInfoEntry entry : this){ result += entry + "\n"; } result += "}"; return result; } -} +} \ No newline at end of file Modified: branches/gridsim4.0-branch3/source/gridsim/turbo/AvailabilityInfoEntry.java =================================================================== --- branches/gridsim4.0-branch3/source/gridsim/turbo/AvailabilityInfoEntry.java 2008-02-08 03:25:23 UTC (rev 91) +++ branches/gridsim4.0-branch3/source/gridsim/turbo/AvailabilityInfoEntry.java 2008-02-10 06:04:30 UTC (rev 92) @@ -29,6 +29,10 @@ private double time_; private PERangeList availRanges_; + // number of gridlets that rely on this entry + // to mark their completion time or anchor point + private int numGridlets_ = 1; + /** * Creates a new instance of {@link AvailabilityInfoEntry} * @param time the time associated with this entry @@ -85,6 +89,34 @@ public void setAvailRanges(PERangeList availRanges) { availRanges_ = availRanges; } + + /** + * Increases the number of Gridlets that rely on this entry to mark + * their expected completion time or their anchor point + */ + public void increaseGridlet(){ + numGridlets_++; + } + + /** + * Decreases the number of Gridlets that rely on this entry to mark + * their expected completion time or their anchor point + */ + public void decreaseGridlet(){ + numGridlets_--; + } + + /** + * Adds the ranges provided to the list of ranges available + * @param list the list to be added + * @return <tt>true</tt> if the ranges changed as result of this call + */ + public boolean addRanges(PERangeList list) { + if(availRanges_ == null) + availRanges_ = new PERangeList(); + + return availRanges_.addAll(list); + } /** * Compares this object with the specified object for order. @@ -126,4 +158,17 @@ return "{time="+ time_ + "; " + ( (availRanges_!=null) ? availRanges_ : "{[]}") + "}"; } + + /** + * Returns a clone of this entry. The ranges are cloned, but the time + * and the number of requests relying on this entry are not. + * @param time the time for the new entry + * @return the new entry with the number of requests set to default. + */ + public AvailabilityInfoEntry clone(double time) { + AvailabilityInfoEntry entry = new AvailabilityInfoEntry(time); + entry.availRanges_ = availRanges_ == null ? null : availRanges_.clone(); + entry.numGridlets_ = 1; + return entry; + } } Modified: branches/gridsim4.0-branch3/source/gridsim/turbo/AvailabilityProfile.java =================================================================== --- branches/gridsim4.0-branch3/source/gridsim/turbo/AvailabilityProfile.java 2008-02-08 03:25:23 UTC (rev 91) +++ branches/gridsim4.0-branch3/source/gridsim/turbo/AvailabilityProfile.java 2008-02-10 06:04:30 UTC (rev 92) @@ -9,6 +9,7 @@ package gridsim.turbo; import java.util.ArrayList; +import java.util.Iterator; /** * This class represents the profile containing the ranges of PEs @@ -43,6 +44,28 @@ } /** + * Returns the entry whose time is closest to the <tt>time</tt> given but + * smaller, or whose time is equals to <tt>time</tt> + * @param time the time to be used to search for the entry + * @return the entry whose time is closest to the <tt>time</tt> given but + * smaller, or whose time is equals to <tt>time</tt>; <tt>null</tt> if + * not found. + */ + protected AvailabilityProfileEntry getPrecedingEntry(double time) { + Iterator<AvailabilityProfileEntry> it = super.iterator(); + AvailabilityProfileEntry preceding = null; + + while(it.hasNext()) { + AvailabilityProfileEntry entry = it.next(); + if(entry.getTime() > time) + break; + + preceding = entry; + } + return preceding; + } + + /** * Creates an string representation of the profile * @return an string representation */ Modified: branches/gridsim4.0-branch3/source/gridsim/turbo/CBParallelSpaceShared.java =================================================================== --- branches/gridsim4.0-branch3/source/gridsim/turbo/CBParallelSpaceShared.java 2008-02-08 03:25:23 UTC (rev 91) +++ branches/gridsim4.0-branch3/source/gridsim/turbo/CBParallelSpaceShared.java 2008-02-10 06:04:30 UTC (rev 92) @@ -157,7 +157,7 @@ /** * Handles internal events that come to this entity. */ - public void body(){ + public void body() { // get the resource characteristics object to be used resource_ = getTResourceCharacteristics(); @@ -514,8 +514,7 @@ // then send this event to itself to update the queues after // this gridlet's completion time - int roundUpTime = (int)(executionTime + 1); - super.sendInternalEvent(roundUpTime); + super.sendInternalEvent(executionTime); return true; } @@ -616,7 +615,6 @@ break; } else { - tailEntry = entry; // Sep. 29, 2007 - Changed by Marcos // if the finish time is equals to the entry time, so there // is no need to check the intersection @@ -626,6 +624,7 @@ if(intersectList == null || intersectList.getNumPE() < reqPE) break; } + tailEntry = entry; } tailIndex = availProfile_.indexOf(tailEntry); } @@ -653,7 +652,8 @@ * @param finishTime the finish time of the Gridlet */ private void allocateImmediatePERanges(int tailIndex, - PERangeList selected, double startTime, double finishTime) { + PERangeList selected, + double startTime, double finishTime) { AvailabilityProfileEntry newEntryAfterTail = null; @@ -664,12 +664,12 @@ // to represent its completion time. This reduces the number of // entries in the availability profile boolean addEntryAfterTail = true; - int updTo = tailIndex; if(tailIndex == -1) { // Creates a new entry to be added to the profile newEntryAfterTail = new AvailabilityProfileEntry(finishTime); newEntryAfterTail.setPERangeList(resource_.getFreePERanges().clone()); + tailIndex++; } else { // get the tail entry (that is, the closest entry to the finish time @@ -677,7 +677,6 @@ if (tailEntry.getTime() == finishTime) { addEntryAfterTail = false; - updTo--; tailEntry.increaseGridlet(); } // If a new entry is required, then add it to the profile @@ -689,12 +688,17 @@ // Creates a new entry to be added to the profile newEntryAfterTail = new AvailabilityProfileEntry(finishTime); - newEntryAfterTail.setPERangeList(listTail); + newEntryAfterTail.setPERangeList(listTail); + tailIndex++; } } + if(addEntryAfterTail) { + availProfile_.add(tailIndex, newEntryAfterTail); + } + // Update entries of the profile - for(int index=0; index<=updTo; index++) { + for(int index=0; index<tailIndex; index++) { AvailabilityProfileEntry entry = availProfile_.get(index); if(entry.getTime() < startTime){ continue; @@ -703,10 +707,6 @@ PERangeList.difference(entry.getPERanges(), selected); entry.setPERangeList(uptList); } - - if(addEntryAfterTail) { - availProfile_.add(tailIndex + 1, newEntryAfterTail); - } // subtract the selected ranges from the currently free ranges resource_.setPEsBusy(selected); @@ -751,24 +751,23 @@ Iterator<AvailabilityProfileEntry> iterProfile = availProfile_.iterator(); while(iterProfile.hasNext()) { - AvailabilityProfileEntry entry = iterProfile.next(); - anchorEntry = entry; - anchorIndex = availProfile_.indexOf(anchorEntry); - tailEntry = entry; - - // sets the start time as the time of the entry - potStartTime = entry.getTime(); - // calculates when the finish time will be if - // the gridlet is put at this position - potFinishTime = potStartTime + duration; - // scan the profile until an entry with enough PEs is found if(entry.getNumPE() < reqPE) { continue; } else { + anchorEntry = entry; + anchorIndex = availProfile_.indexOf(anchorEntry); + tailEntry = entry; + + // sets the start time as the time of the entry + potStartTime = entry.getTime(); + // calculates when the finish time will be if + // the gridlet is put at this position + potFinishTime = potStartTime + duration; + // if an entry with enough PEs is found, then scan the profile // from that point onwards analysing the intersection of // the ranges available in the entries until the @@ -783,7 +782,7 @@ if(nextEntry.getTime() > potFinishTime){ break; } - else{ + else { // Sep. 29, 2007 - Changed by Marcos // if the finish time is equals to the entry time, so there // is no need to check the intersection @@ -804,6 +803,9 @@ } } + if(intersectList == null || intersectList.getNumPE() < reqPE) + return null; + anchorIndex = availProfile_.indexOf(anchorEntry); tailIndex = availProfile_.indexOf(tailEntry); @@ -831,7 +833,6 @@ double finishTime) { AvailabilityProfileEntry newEntryAfterTail = null; - AvailabilityProfileEntry newEntryAfterAnchor = null; // if the time of the entry at (tailIndex) is equals to // the gridlet finish time, then a new entry in the profile @@ -840,18 +841,7 @@ // to represent its completion time. This reduces the number of // entries in the availability profile boolean addEntryAfterTail = true; - - // if the time of the entry at (anchor) is equals to - // the gridlet finish time, then a new entry in the profile - // is not needed. In this case, the entry at (anchorIndex) - // is updated to show that one more gridlet relies on the entry - // to represent its completion time. This reduces the number of - // entries in the availability profile. - boolean addEntryAfterAnchor = false; - - int updFrom = anchorIndex; - int updTo = tailIndex; - + AvailabilityProfileEntry tailEntry = availProfile_.get(tailIndex); AvailabilityProfileEntry anchorEntry = availProfile_.get(anchorIndex); // increment the counter to denote that one more gridlet uses this entry @@ -859,31 +849,26 @@ if (tailEntry.getTime() == finishTime) { addEntryAfterTail = false; - updTo--; tailEntry.increaseGridlet(); } - // If a new entry is required, then created it to be added to the profile else { // Creates a new entry to be added to the profile newEntryAfterTail = new AvailabilityProfileEntry(finishTime); newEntryAfterTail.setPERangeList(tailEntry.getPERanges().clone()); + tailIndex++; } + + if(addEntryAfterTail) { + availProfile_.add(tailIndex, newEntryAfterTail); + } // Update entries of the profile - for(int index=updFrom; index<=updTo; index++){ + for(int index=anchorIndex; index<tailIndex; index++){ AvailabilityProfileEntry entry = availProfile_.get(index); PERangeList uptList = PERangeList.difference(entry.getPERanges(), selected); entry.setPERangeList(uptList); } - - if(addEntryAfterAnchor) { - availProfile_.add(anchorIndex + 1, newEntryAfterAnchor); - } - - if(addEntryAfterTail) { - availProfile_.add(tailIndex + 1, newEntryAfterTail); - } } /** @@ -901,7 +886,6 @@ // remove all Gridlets that have already completed from // the queue of running Gridlets PERangeList releasedRanges = new PERangeList(); - LinkedList<SSGridlet> grlsCompleted = new LinkedList<SSGridlet>(); // iterates the list to check what has finished Iterator<SSGridlet> iter = runningGridlets_.iterator(); @@ -913,7 +897,6 @@ if(gridlet.getFinishTime() <= currentTime) { // Update the list of ranges released releasedRanges.addAll(gridlet.getPERangeList().clone()); - grlsCompleted.add(gridlet); gridletFinish(gridlet, Gridlet.SUCCESS); iter.remove(); gridletFinished++; @@ -950,20 +933,18 @@ // change Gridlet status gridlet.setStatus(Gridlet.INEXEC); - int roundUpTime = (int)(gridlet.getFinishTime()-currentTime)+1; - super.sendInternalEvent(roundUpTime); + super.sendInternalEvent(gridlet.getFinishTime()-currentTime); } } resource_.setPEsBusy(allocatedRanges); } - + //---------------- USED FOR DEBUGGING PURPOSES ONLY -------------------- // If a gridlet has started execution or one has finished, // then inform the listeners if(gridletStarted > 0 || gridletFinished > 0){ - GridSim.notifyListeners(this.get_id(), AllocationAction.ITEM_COMPLETED, - true, grlsCompleted); + GridSim.notifyListeners(this.get_id(), AllocationAction.SCHEDULE_CHANGED, true); } //---------------------------------------------------------------------- } Modified: branches/gridsim4.0-branch3/source/gridsim/turbo/EBParallelSpaceShared.java =================================================================== --- branches/gridsim4.0-branch3/source/gridsim/turbo/EBParallelSpaceShared.java 2008-02-08 03:25:23 UTC (rev 91) +++ branches/gridsim4.0-branch3/source/gridsim/turbo/EBParallelSpaceShared.java 2008-02-10 06:04:30 UTC (rev 92) @@ -468,8 +468,7 @@ // then send this event to itself to update the queues after // this gridlet's completion time - int roundUpTime = (int)(executionTime + 1); - super.sendInternalEvent(roundUpTime); + super.sendInternalEvent(executionTime); return true; } @@ -634,20 +633,22 @@ while(iterProfile.hasNext()) { AvailabilityProfileEntry entry = iterProfile.next(); - anchorEntry = entry; - anchorIndex = availProfile_.indexOf(anchorEntry); - - // sets the start time as the time of the entry - potStartTime = entry.getTime(); - // calculates when the finish time will be if - // the gridlet is put at this position - potFinishTime = potStartTime + duration; // scan the profile until an entry with enough PEs is found if(entry.getNumPE() < reqPE) { continue; } else { + + anchorEntry = entry; + anchorIndex = availProfile_.indexOf(anchorEntry); + + // sets the start time as the time of the entry + potStartTime = entry.getTime(); + // calculates when the finish time will be if + // the gridlet is put at this position + potFinishTime = potStartTime + duration; + // if an entry with enough PEs is found, then scan the profile // from that point onwards analysing the intersection of // the ranges available in the entries until the Modified: branches/gridsim4.0-branch3/source/gridsim/turbo/PERangeList.java =================================================================== --- branches/gridsim4.0-branch3/source/gridsim/turbo/PERangeList.java 2008-02-08 03:25:23 UTC (rev 91) +++ branches/gridsim4.0-branch3/source/gridsim/turbo/PERangeList.java 2008-02-10 06:04:30 UTC (rev 92) @@ -157,76 +157,6 @@ // ---------------------------- STATIC METHODS ------------------------ /** - * Returns the common range between two ranges of PEs - * @param rangea the first range - * @param rangeb the second range - * @return the common range of PEs - */ - public static PERange intersection(PERange rangea, PERange rangeb){ - if(rangea == null || rangeb == null) - return null; - - int starta = rangea.getBeginning(); - int startb = rangeb.getBeginning(); - int enda = rangea.getEnd(); - int endb = rangeb.getEnd(); - int starti = -1; - int endi = Integer.MAX_VALUE; - - while( !(starta > enda) && !(startb > endb) ){ - if(starta < startb){ - starta++; - } - else if(startb < starta){ - startb++; - } - else{ - if(starti < 0){ - starti = starta; - } - endi = starta; - starta++; - startb++; - } - } - - if(starti == -1 && endi == Integer.MAX_VALUE) - return null; - - return new PERange(starti, endi); - } - - /** - * Checks whether two ranges have common elements - * @param rangea the first range - * @param rangeb the second range - * @return <tt>true</tt> if the two ranges have an intersection - * or <tt>false</tt> otherwise. - */ - public static boolean intersect(PERange rangea, PERange rangeb){ - if(rangea == null || rangeb == null) - return false; - - int starta = rangea.getBeginning(); - int startb = rangeb.getBeginning(); - int enda = rangea.getEnd(); - int endb = rangeb.getEnd(); - - while( !(starta > enda) && !(startb > endb) ){ - if(starta < startb){ - starta++; - } - else if(startb < starta){ - startb++; - } - else{ - return true; - } - } - return false; - } - - /** * Identifies the intersections between lists of ranges * @param lista the first list * @param listb the second list @@ -271,13 +201,178 @@ } /** + * Returns the result of subtracting the sequences of the + * second list from the first one. + * @param lista the first list of ranges + * @param listb the second list of ranges + * @return the range corresponding to the difference + */ + public static PERangeList difference(PERangeList lista, PERangeList listb) { + + if(lista == null || lista.getNumPE() == 0) { + return null; + } + else if(listb == null){ + return lista.clone(); + } + + PERangeList difference = lista.clone(); + difference.mergePERanges(); + + PERangeList universe = listb; + universe.sortRanges(); + + boolean finished = false; + while(!finished){ + finished = true; + PERangeList diffRange = null; + look:{ + Iterator<PERange> iterDiff = difference.iterator(); + while(iterDiff.hasNext()) { + PERange rangeq = iterDiff.next(); + for(PERange rangeu : universe ){ + if(intersect(rangeq, rangeu)){ + finished = false; + diffRange = difference(rangeq, rangeu); + iterDiff.remove(); + break look; + } + } + } + } + if(diffRange != null){ + difference.addAll(diffRange); + difference.sortRanges(); + } + } + + if(difference == null || difference.size() == 0){ + return null; + } + else{ + difference.mergePERanges(); + return difference; + } + } + + /** + * Selects a range to be used by a Gridlet out of the list + * of free ranges provided. + * @param reqPE the number of PEs required. + * @param ranges the list of free ranges. + * @return the range to be allocated or <tt>null</tt> if no + * range suitable is found. + */ + public static PERangeList selectPERangeList(int reqPE, PERangeList ranges){ + PERangeList selected = new PERangeList(); + try{ + ranges.sortRanges(); + for(PERange range: ranges){ + if(range.getNumPE() >= reqPE){ + int beginning = range.getBeginning(); + int end = beginning + reqPE - 1; + selected.add(new PERange(beginning, end)); + break; + } + else{ + selected.add(range.clone()); + reqPE -= range.getNumPE(); + } + } + } + catch(Exception ex){ + ex.printStackTrace(); + selected = null; + } + + return selected; + } + + //TODO: The method below is not working properly. To fix it. + //TODO: As I am not using it at the moment, leave it as it is. + /** + * Returns the symmetric difference of two lists of ranges. + * The output sequence will contain all elements that are in the ranges + * of one list but are not in the ranges of the other. + * @param lista the first list of range + * @param listb the second list of range + * @return the range corresponding to the symmetric difference + */ + public static PERangeList symmetricDifference(PERangeList lista, PERangeList listb){ + if(lista == null || listb == null) + return null; + + PERangeList query = lista; + PERangeList universe = listb; + + for(PERange rangeq : query){ + boolean intersected = false; + PERangeList tempDiff = new PERangeList(); + Iterator<PERange> iterUni = universe.iterator(); + while( !intersected || iterUni.hasNext()){ + PERange rangeu = iterUni.next(); + if(intersect(rangeq, rangeu)){ + PERangeList diffRange = symmetricDifference(rangeq, rangeu); + if(diffRange != null){ + tempDiff.addAll(diffRange); + } + intersected = true; + } + else{ + tempDiff.add(rangeu); + } + } + if(!intersected){ + tempDiff.add(rangeq); + } + universe = tempDiff.clone(); + } + + if(universe == null || universe.size() == 0){ + return null; + } + else{ + universe.mergePERanges(); + return universe; + } + } + + /** + * Method that returns true if there are overlaps between the + * ranges in this list. Note that this method is used for debugging purposes + * as there should not be overlaps in any list used thoughout the simulation. + * @param list the list to be analysed. + * @return <tt>true</tt> if there are overlaps; <tt>false</tt> otherwise. + */ + public static boolean containsOverlappingRanges(PERangeList list){ + if(list == null || list.getNumPE() == 0) { + return false; + } + + boolean intersect = false; + for(PERange rq : list) { + for(PERange ru : list) { + if(rq != ru) { + intersect = PERangeList.intersect(rq, ru); + if(intersect) + return true; + } + } + } + + return false; + } + + // ---------------------------- PRIVATE METHODS ------------------------ + + /** * Returns the list of ranges resulting from subtracting the second * range from the first one. * @param rangea the first range * @param rangeb the second range * @return the range corresponding to the difference */ - public static PERangeList difference(PERange rangea, PERange rangeb){ + private static PERangeList difference(PERange rangea, PERange rangeb){ if(rangea == null || rangeb == null) return null; @@ -342,58 +437,73 @@ } /** - * Returns the result of subtracting the sequences of the - * second list from the first one. - * @param lista the first list of ranges - * @param listb the second list of ranges - * @return the range corresponding to the difference + * Returns the common range between two ranges of PEs + * @param rangea the first range + * @param rangeb the second range + * @return the common range of PEs */ - public static PERangeList difference(PERangeList lista, PERangeList listb) { - - if(lista == null || lista.getNumPE() == 0) { + private static PERange intersection(PERange rangea, PERange rangeb){ + if(rangea == null || rangeb == null) return null; - } - else if(listb == null){ - return lista.clone(); - } - PERangeList difference = lista.clone(); - difference.mergePERanges(); + int starta = rangea.getBeginning(); + int startb = rangeb.getBeginning(); + int enda = rangea.getEnd(); + int endb = rangeb.getEnd(); + int starti = -1; + int endi = Integer.MAX_VALUE; - PERangeList universe = listb; - universe.sortRanges(); - - boolean finished = false; - while(!finished){ - finished = true; - PERangeList diffRange = null; - look:{ - Iterator<PERange> iterDiff = difference.iterator(); - while(iterDiff.hasNext()) { - PERange rangeq = iterDiff.next(); - for(PERange rangeu : universe ){ - if(intersect(rangeq, rangeu)){ - finished = false; - diffRange = difference(rangeq, rangeu); - iterDiff.remove(); - break look; - } - } - } + while( !(starta > enda) && !(startb > endb) ){ + if(starta < startb){ + starta++; } - if(diffRange != null){ - difference.addAll(diffRange); - difference.sortRanges(); - } + else if(startb < starta){ + startb++; + } + else{ + if(starti < 0){ + starti = starta; + } + endi = starta; + starta++; + startb++; + } } + + if(starti == -1 && endi == Integer.MAX_VALUE) + return null; - if(difference == null || difference.size() == 0){ - return null; + return new PERange(starti, endi); + } + + /** + * Checks whether two ranges have common elements + * @param rangea the first range + * @param rangeb the second range + * @return <tt>true</tt> if the two ranges have an intersection + * or <tt>false</tt> otherwise. + */ + private static boolean intersect(PERange rangea, PERange rangeb){ + if(rangea == null || rangeb == null) + return false; + + int starta = rangea.getBeginning(); + int startb = rangeb.getBeginning(); + int enda = rangea.getEnd(); + int endb = rangeb.getEnd(); + + while( !(starta > enda) && !(startb > endb) ){ + if(starta < startb){ + starta++; + } + else if(startb < starta){ + startb++; + } + else{ + return true; + } } - else{ - difference.mergePERanges(); - return difference; - } + return false; } /** @@ -403,7 +513,7 @@ * @param rangeb the second range * @return the range corresponding to the symmetric difference */ - public static PERangeList symmetricDifference(PERange rangea, PERange rangeb){ + private static PERangeList symmetricDifference(PERange rangea, PERange rangeb){ if(rangea == null || rangeb == null) return null; @@ -474,55 +584,6 @@ return difference.size() == 0 ? null : difference; } - - //TODO: The method below is not working properly. To fix it. - //TODO: As I am not using it at the moment, leave it as it is. - /** - * Returns the symmetric difference of two lists of ranges. - * The output sequence will contain all elements that are in the ranges - * of one list but are not in the ranges of the other. - * @param lista the first list of range - * @param listb the second list of range - * @return the range corresponding to the symmetric difference - */ - public static PERangeList symmetricDifference(PERangeList lista, PERangeList listb){ - if(lista == null || listb == null) - return null; - - PERangeList query = lista; - PERangeList universe = listb; - - for(PERange rangeq : query){ - boolean intersected = false; - PERangeList tempDiff = new PERangeList(); - Iterator<PERange> iterUni = universe.iterator(); - while( !intersected || iterUni.hasNext()){ - PERange rangeu = iterUni.next(); - if(intersect(rangeq, rangeu)){ - PERangeList diffRange = symmetricDifference(rangeq, rangeu); - if(diffRange != null){ - tempDiff.addAll(diffRange); - } - intersected = true; - } - else{ - tempDiff.add(rangeu); - } - } - if(!intersected){ - tempDiff.add(rangeq); - } - universe = tempDiff.clone(); - } - - if(universe == null || universe.size() == 0){ - return null; - } - else{ - universe.mergePERanges(); - return universe; - } - } // FOR DEBUGGING PURPOSES ONLY... // public static void main(String args[]){ @@ -540,4 +601,4 @@ // // System.out.println("Consolidated# " + list); // } -} +} \ No newline at end of file Modified: branches/gridsim4.0-branch3/source/gridsim/turbo/ReservationRequester.java =================================================================== --- branches/gridsim4.0-branch3/source/gridsim/turbo/ReservationRequester.java 2008-02-08 03:25:23 UTC (rev 91) +++ branches/gridsim4.0-branch3/source/gridsim/turbo/ReservationRequester.java 2008-02-10 06:04:30 UTC (rev 92) @@ -357,7 +357,9 @@ // gets the error code. If the error code is EC_NO_ERROR // it means that the reservation has been successful. // Otherwise, print the error message... [truncated message content] |
From: <mar...@us...> - 2008-02-08 03:25:17
|
Revision: 91 http://gridsim.svn.sourceforge.net/gridsim/?rev=91&view=rev Author: marcos_dias Date: 2008-02-07 19:25:23 -0800 (Thu, 07 Feb 2008) Log Message: ----------- This update allows the user to pause the simulation at a given simulation time. If the user sets the simulation to run until 50000 seconds and clicks the run button, the simulation will run continuously until 50000 and stop at the first even whose time is >= to 50000. Modified Paths: -------------- branches/gridsim4.0-branch3/source/eduni/simjava/Sim_system.java branches/gridsim4.0-branch3/source/gridsim/GridSim.java branches/gridsim4.0-branch3/source/gridsim/gui/DefaultGridSimVisualizer.java branches/gridsim4.0-branch3/source/gridsim/gui/ResourceWindow.java branches/gridsim4.0-branch3/source/gridsim/turbo/ARMessage.java Modified: branches/gridsim4.0-branch3/source/eduni/simjava/Sim_system.java =================================================================== --- branches/gridsim4.0-branch3/source/eduni/simjava/Sim_system.java 2008-02-08 01:57:22 UTC (rev 90) +++ branches/gridsim4.0-branch3/source/eduni/simjava/Sim_system.java 2008-02-08 03:25:23 UTC (rev 91) @@ -77,6 +77,7 @@ // ADDED BY MARCOS - 2007-09-07 private static boolean paused = false; + private static double pauseAt = Double.MAX_VALUE; private static Object syncObj = new Object(); /** @@ -534,7 +535,12 @@ // ADDED BY MARCOS TO ALLOW THE // SIMULATION TO BE PAUSED + synchronized(syncObj){ + + if(clock >= pauseAt) + paused = true; + while(paused){ try { syncObj.wait(); @@ -710,6 +716,23 @@ return paused; } } + + /** + * This method is called if one wants to pause the simulation + * at a given time + * @time the time at which the simulation has to be paused + * @return <tt>true</tt>if the simulation has been paused + * or <tt>false</tt> otherwise. + */ + public static synchronized boolean pauseSimulation(double time) { + synchronized(syncObj){ + if(time <= clock) + return false; + else + pauseAt = time; + } + return true; + } /** * This method is called if one wants to resume the simulation @@ -720,6 +743,10 @@ public static synchronized boolean resumeSimulation() { synchronized(syncObj){ paused = false; + + if(pauseAt <= clock) + pauseAt = Double.MAX_VALUE; + syncObj.notify(); return !paused; } Modified: branches/gridsim4.0-branch3/source/gridsim/GridSim.java =================================================================== --- branches/gridsim4.0-branch3/source/gridsim/GridSim.java 2008-02-08 01:57:22 UTC (rev 90) +++ branches/gridsim4.0-branch3/source/gridsim/GridSim.java 2008-02-08 03:25:23 UTC (rev 91) @@ -825,6 +825,17 @@ } /** + * Pauses the simulation at a given simulation time. This method + * should be used for debugging purposes only + * @param time the time when the simulation should be paused + * @return <tt>true</tt> if the simulation can be paused or + * <tt>false</tt> otherwise. + */ + public static boolean pauseSimulation(double time){ + return Sim_system.pauseSimulation(time); + } + + /** * Resumes the simulation. This method should be used for * debugging purposes only * @return <tt>true</tt> if the simulation has been resumed or Modified: branches/gridsim4.0-branch3/source/gridsim/gui/DefaultGridSimVisualizer.java =================================================================== --- branches/gridsim4.0-branch3/source/gridsim/gui/DefaultGridSimVisualizer.java 2008-02-08 01:57:22 UTC (rev 90) +++ branches/gridsim4.0-branch3/source/gridsim/gui/DefaultGridSimVisualizer.java 2008-02-08 03:25:23 UTC (rev 91) @@ -26,13 +26,16 @@ import javax.swing.BorderFactory; import javax.swing.JButton; import javax.swing.JFrame; +import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; +import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextArea; +import javax.swing.JTextField; import javax.swing.border.Border; import javax.swing.border.EtchedBorder; import javax.swing.border.TitledBorder; @@ -64,12 +67,16 @@ GridSimVisualizer { private static final long serialVersionUID = 2059324063853260682L; - public static final int WINDOW_WIDTH = 400; + public static final int WINDOW_WIDTH = 450; public static final int WINDOW_HEIGHT = 350; private JButton btStep_; private JButton btRun_; private JButton btSlowMotion_; + + private JButton btChangePause_; + private JTextField tfRunUntil_; + private JList jlResource_; private JTextArea jlResourceInfo_; @@ -121,17 +128,16 @@ super.setTitle("GridSim Turbo Alpha 0.1 Visualizer"); JPanel mainPanel = new JPanel(new GridLayout(0, 1)); -// JPanel simulationPanel = new JPanel(new GridLayout(0, 3)); - JPanel simulationPanel = new JPanel(new GridLayout(0, 2)); + JPanel simulationPanel = new JPanel(new GridLayout(0, 3)); Border simulationBorder = BorderFactory.createTitledBorder( BorderFactory.createEtchedBorder(EtchedBorder.RAISED), "Simulation"); simulationPanel.setBorder(simulationBorder); - - JPanel executionPanel = new JPanel(new GridLayout(3,0)); + + JPanel executionPanel = new JPanel(new GridLayout(3,1)); executionPanel.setBorder(new TitledBorder("Execution")); - JPanel pausePanel = new JPanel(new GridLayout(3,0)); + JPanel pausePanel = new JPanel(new GridLayout(3,1)); pausePanel.setBorder(new TitledBorder("Pause Condition")); btStep_ = new JButton("Step by Step"); @@ -142,10 +148,21 @@ btRun_.addActionListener(this); btSlowMotion_.addActionListener(this); + JLabel lbRunUntil = new JLabel(" Pause at (Seconds):"); + lbRunUntil.setAlignmentY(JTextField.CENTER_ALIGNMENT); + + tfRunUntil_ = new JTextField(10); + btChangePause_ = new JButton("Change"); executionPanel.add(btStep_); + + pausePanel.add(lbRunUntil); + pausePanel.add(tfRunUntil_); + pausePanel.add(btChangePause_); + + btChangePause_.addActionListener(this); + executionPanel.add(btSlowMotion_); executionPanel.add(btRun_); - executionPanel.add(btSlowMotion_); - + ArrayList<String> resourceNames = new ArrayList<String>(); for(GridResource resource : resources_) { resourceNames.add(resource.get_name()); @@ -162,7 +179,7 @@ resourcePanel.add(scrollResourcePanel); simulationPanel.add(executionPanel); -// simulationPanel.add(pausePanel); + simulationPanel.add(pausePanel); simulationPanel.add(resourcePanel); jlResourceInfo_ = new JTextArea(); @@ -234,7 +251,30 @@ public void actionPerformed(ActionEvent e){ String cmd = e.getActionCommand(); - if(e.getSource() == btStep_){ + if(e.getSource() == btChangePause_) { + double newPause; + boolean success = true; + try { + newPause = Double.parseDouble(tfRunUntil_.getText()); + if(newPause >= GridSim.clock()) + GridSim.pauseSimulation(newPause); + else + success = false; + } + catch (NumberFormatException nfe) { + success = false; + } + if(!success) { + String message = "The value informed to pause the simulation " + + "is invalid.\nThe current simulation time is " + GridSim.clock() + "."; + + JOptionPane.showMessageDialog(this, message, + "Error While Setting the Time", + JOptionPane.ERROR_MESSAGE); + + } + } + else if(e.getSource() == btStep_){ GridSim.enableStepByStepMode(); GridSim.disableSlowMotionMode(); Modified: branches/gridsim4.0-branch3/source/gridsim/gui/ResourceWindow.java =================================================================== --- branches/gridsim4.0-branch3/source/gridsim/gui/ResourceWindow.java 2008-02-08 01:57:22 UTC (rev 90) +++ branches/gridsim4.0-branch3/source/gridsim/gui/ResourceWindow.java 2008-02-08 03:25:23 UTC (rev 91) @@ -109,6 +109,7 @@ private JRadioButtonMenuItem btHour_; private boolean drawID_ = true; private boolean autoScroll_ = true; + private boolean animate_ = true; private JButton btSetSdWindowSize_; private JTextField fdSdWindowSize_; @@ -329,7 +330,7 @@ sliderX_ = new JSlider(10, 100, 10); sliderY_ = new JSlider(10, 100, 10); - ChangeListener graphResizer = new ChangeListener(){ + ChangeListener graphResizer = new ChangeListener() { synchronized public void stateChanged(ChangeEvent e) { pnGraph_.repaint(); } @@ -453,13 +454,33 @@ updateResourceWindow(); } }); - + menuCommand.add(mnScroll); + + JMenu mnAnimation = new JMenu("Animation"); + JCheckBoxMenuItem miAnimation = new JCheckBoxMenuItem("Animate this Window"); + miAnimation.setSelected(true); + mnAnimation.add(miAnimation); + + miAnimation.addItemListener(new ItemListener(){ + public void itemStateChanged(ItemEvent e){ + if (e.getStateChange() == ItemEvent.DESELECTED){ + animate_ = false; + } + else if (e.getStateChange() == ItemEvent.SELECTED){ + animate_ = true; + } + updateResourceWindow(); + } + }); + + menuCommand.add(mnAnimation); + menuBar.add(menuCommand); setJMenuBar(menuBar); } - private void updateResourceWindow(){ + private void updateResourceWindow() { pnGraph_.repaint(); if(slidingWindowSize_ != Double.MAX_VALUE) { @@ -555,6 +576,9 @@ } protected synchronized void paintComponent(Graphics g2) { + if(!animate_) + return; + super.paintComponent(g2); Graphics2D g2D = (Graphics2D)g2; g2D.setFont(graphFont_); Modified: branches/gridsim4.0-branch3/source/gridsim/turbo/ARMessage.java =================================================================== --- branches/gridsim4.0-branch3/source/gridsim/turbo/ARMessage.java 2008-02-08 01:57:22 UTC (rev 90) +++ branches/gridsim4.0-branch3/source/gridsim/turbo/ARMessage.java 2008-02-08 03:25:23 UTC (rev 91) @@ -21,7 +21,6 @@ */ public class ARMessage { - private int srcId_; // id of the entity that sent the message private int dstId_; // id of the entity that will receive the message private int msgId_; // a unique id for the message This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mar...@us...> - 2008-02-08 01:57:19
|
Revision: 90 http://gridsim.svn.sourceforge.net/gridsim/?rev=90&view=rev Author: marcos_dias Date: 2008-02-07 17:57:22 -0800 (Thu, 07 Feb 2008) Log Message: ----------- Small changes in the GUI. The user can now define the size for the sliding window (i.e. the size of the portion shown by the scheduling graph. In this case, the graph is not automatically adjuested to fit the window. Modified Paths: -------------- branches/gridsim4.0-branch3/source/gridsim/gui/DefaultGridSimVisualizer.java branches/gridsim4.0-branch3/source/gridsim/gui/ResourceWindow.java Modified: branches/gridsim4.0-branch3/source/gridsim/gui/DefaultGridSimVisualizer.java =================================================================== --- branches/gridsim4.0-branch3/source/gridsim/gui/DefaultGridSimVisualizer.java 2008-02-07 10:53:15 UTC (rev 89) +++ branches/gridsim4.0-branch3/source/gridsim/gui/DefaultGridSimVisualizer.java 2008-02-08 01:57:22 UTC (rev 90) @@ -121,6 +121,7 @@ super.setTitle("GridSim Turbo Alpha 0.1 Visualizer"); JPanel mainPanel = new JPanel(new GridLayout(0, 1)); +// JPanel simulationPanel = new JPanel(new GridLayout(0, 3)); JPanel simulationPanel = new JPanel(new GridLayout(0, 2)); Border simulationBorder = BorderFactory.createTitledBorder( @@ -129,6 +130,9 @@ JPanel executionPanel = new JPanel(new GridLayout(3,0)); executionPanel.setBorder(new TitledBorder("Execution")); + + JPanel pausePanel = new JPanel(new GridLayout(3,0)); + pausePanel.setBorder(new TitledBorder("Pause Condition")); btStep_ = new JButton("Step by Step"); btRun_ = new JButton("Run"); @@ -143,7 +147,7 @@ executionPanel.add(btSlowMotion_); ArrayList<String> resourceNames = new ArrayList<String>(); - for(GridResource resource : resources_){ + for(GridResource resource : resources_) { resourceNames.add(resource.get_name()); } @@ -158,6 +162,7 @@ resourcePanel.add(scrollResourcePanel); simulationPanel.add(executionPanel); +// simulationPanel.add(pausePanel); simulationPanel.add(resourcePanel); jlResourceInfo_ = new JTextArea(); Modified: branches/gridsim4.0-branch3/source/gridsim/gui/ResourceWindow.java =================================================================== --- branches/gridsim4.0-branch3/source/gridsim/gui/ResourceWindow.java 2008-02-07 10:53:15 UTC (rev 89) +++ branches/gridsim4.0-branch3/source/gridsim/gui/ResourceWindow.java 2008-02-08 01:57:22 UTC (rev 90) @@ -25,6 +25,7 @@ import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.GridLayout; +import java.awt.Rectangle; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ComponentAdapter; @@ -41,15 +42,20 @@ import javax.swing.BorderFactory; import javax.swing.BoxLayout; import javax.swing.ButtonGroup; -import javax.swing.JCheckBox; +import javax.swing.JButton; +import javax.swing.JCheckBoxMenuItem; import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.JList; +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.JOptionPane; import javax.swing.JPanel; -import javax.swing.JRadioButton; +import javax.swing.JRadioButtonMenuItem; import javax.swing.JScrollPane; import javax.swing.JSlider; import javax.swing.JTextArea; +import javax.swing.JTextField; import javax.swing.SwingUtilities; import javax.swing.border.BevelBorder; import javax.swing.border.Border; @@ -98,12 +104,16 @@ // default control options included in the left side of the window private JSlider sliderX_; private JSlider sliderY_; - private JCheckBox cbShowID_; - private JRadioButton btSecond_; - private JRadioButton btMinute_; - private JRadioButton btHour_; + private JRadioButtonMenuItem btSecond_; + private JRadioButtonMenuItem btMinute_; + private JRadioButtonMenuItem btHour_; private boolean drawID_ = true; + private boolean autoScroll_ = true; + private JButton btSetSdWindowSize_; + private JTextField fdSdWindowSize_; + private double slidingWindowSize_ = Double.MAX_VALUE; + // the left panel itself, the scroller for the scheduling queue panel // and the panel where the jobs are drawn private JComponent pnLeft_; @@ -133,7 +143,7 @@ private Color[] colorsARInProgress; private static final int WINDOW_WIDTH = 900; - private static final int WINDOW_HEIGHT = 300; + private static final int WINDOW_HEIGHT = 350; private static final int SHIFT_X = 30; private static final int SHIFT_Y = 25; private static final int SHIFT_BOTTOM = 15; @@ -254,7 +264,32 @@ else if (e.getSource() == btHour_ && btHour_.isSelected()) { timeUnit_ = GridSimVisualizer.TIME_UNIT_HOUR; } + else if(e.getSource() == btSetSdWindowSize_) { + double newSize; boolean success = true; + try { + newSize = Double.parseDouble(fdSdWindowSize_.getText()); + if(newSize >= 60) + slidingWindowSize_ = newSize; + else + success = false; + } + catch (NumberFormatException nfe) { + success = false; + } + if(!success) { + String message = "The value informed for the size of the " + + "sliding window is invalid.\nThe " + + ((slidingWindowSize_ == Double.MAX_VALUE) ? "default" : "current") + + " value will be used instead.\n\n" + + "Note: the minimum size is 60 seconds."; + + JOptionPane.showMessageDialog(this, message, + "Error Setting the Sliding Window Size", + JOptionPane.ERROR_MESSAGE); + } + } + if(scheduledItems_.size() > 0) pnItem_.updatePanel(); @@ -273,7 +308,7 @@ // calculates the size of the two panels // to be added to the window int leftPanelWidth = (int)((super.getWidth()) * PROPORTION_LEFT_PANEL); - int panelsHeight = (int)((super.getHeight()) - 20); + int panelsHeight = (int)((super.getHeight()) - 40); int gridletPanelWidth = (int)((super.getWidth()) * PROPORTION_RIGHT_PANEL) - 10; int leftPanelXPos = 0; int gridletPanelXPos = leftPanelXPos + leftPanelWidth; @@ -289,25 +324,6 @@ instructionPanel.setLayout(new BoxLayout(instructionPanel, BoxLayout.X_AXIS)); instructionPanel.setBorder(raisedetched); - JPanel checkPanel = new JPanel(new GridLayout(1, 1)); - checkPanel.setBorder(new TitledBorder("Gridlet Info")); - - cbShowID_ = new JCheckBox("Show ID "); - cbShowID_.setSelected(true); - checkPanel.add(cbShowID_); - - cbShowID_.addItemListener(new ItemListener(){ - public void itemStateChanged(ItemEvent e){ - if (e.getStateChange() == ItemEvent.DESELECTED){ - drawID_ = false; - } - else if (e.getStateChange() == ItemEvent.SELECTED){ - drawID_ = true; - } - pnGraph_.repaint(); - } - }); - JPanel sliderPanel = new JPanel(new GridLayout(1, 2)); sliderPanel.setBorder(new TitledBorder("Scale X and Y Axes")); sliderX_ = new JSlider(10, 100, 10); @@ -324,35 +340,18 @@ sliderPanel.add(sliderX_); sliderPanel.add(sliderY_); - JPanel timePanel = new JPanel(new GridLayout(1, 3)); - timePanel.setBorder(new TitledBorder("Time unit")); + JPanel pnWindowProp = new JPanel(new GridLayout(1, 2)); + pnWindowProp.setBorder(new TitledBorder("Sliding Window Size (Sec.):")); - btSecond_ = new JRadioButton("Second"); - btSecond_.setActionCommand("time_second"); - btSecond_.setSelected(true); - - btMinute_ = new JRadioButton("Minute"); - btMinute_.setActionCommand("time_minutes"); - - btHour_ = new JRadioButton("Hour"); - btHour_.setActionCommand("time_hour"); - - ButtonGroup timeButtonGroup = new ButtonGroup(); - timeButtonGroup.add(btSecond_); - timeButtonGroup.add(btMinute_); - timeButtonGroup.add(btHour_); + fdSdWindowSize_ = new JTextField(8); + pnWindowProp.add(fdSdWindowSize_); - btSecond_.addActionListener(this); - btMinute_.addActionListener(this); - btHour_.addActionListener(this); + btSetSdWindowSize_ = new JButton("Change"); + btSetSdWindowSize_.addActionListener(this); + pnWindowProp.add(btSetSdWindowSize_); - timePanel.add(btSecond_); - timePanel.add(btMinute_); - timePanel.add(btHour_); - - instructionPanel.add(checkPanel); instructionPanel.add(sliderPanel); - instructionPanel.add(timePanel); + instructionPanel.add(pnWindowProp); //Set up the drawing area. pnGraph_ = new GraphPanel(); @@ -379,12 +378,100 @@ this.getContentPane().add(pnItem_); this.getContentPane().add(pnColor_); + createMenuBar(); + pnItem_.setMinimumSize(new Dimension( (int)(WINDOW_WIDTH/2.7), (int)(super.getMaximumSize().height))); } + /** + * Creates the menu bar of the main window + */ + private void createMenuBar() { + JMenuBar menuBar = new JMenuBar(); + JMenu menuCommand = new JMenu("Options"); + + JMenu mnGridlet = new JMenu("Gridlet"); + JCheckBoxMenuItem miShowGridID = new JCheckBoxMenuItem("Show ID"); + miShowGridID.setSelected(true); + mnGridlet.add(miShowGridID); + + miShowGridID.addItemListener(new ItemListener(){ + public void itemStateChanged(ItemEvent e){ + if (e.getStateChange() == ItemEvent.DESELECTED){ + drawID_ = false; + } + else if (e.getStateChange() == ItemEvent.SELECTED){ + drawID_ = true; + } + pnGraph_.repaint(); + } + }); + + menuCommand.add(mnGridlet); + + JMenu mnTime = new JMenu("Time Unit"); + btSecond_ = new JRadioButtonMenuItem("Second"); + btSecond_.setActionCommand("time_second"); + btSecond_.setSelected(true); + + btMinute_ = new JRadioButtonMenuItem("Minute"); + btMinute_.setActionCommand("time_minutes"); + + btHour_ = new JRadioButtonMenuItem("Hour"); + btHour_.setActionCommand("time_hour"); + + ButtonGroup timeButtonGroup = new ButtonGroup(); + timeButtonGroup.add(btSecond_); + timeButtonGroup.add(btMinute_); + timeButtonGroup.add(btHour_); + + btSecond_.addActionListener(this); + btMinute_.addActionListener(this); + btHour_.addActionListener(this); + + mnTime.add(btSecond_); + mnTime.add(btMinute_); + mnTime.add(btHour_); + + menuCommand.add(mnTime); + + JMenu mnScroll = new JMenu("Scrolling"); + + JCheckBoxMenuItem miAutoScroll = new JCheckBoxMenuItem("Auto Scroll to End of Queue"); + miAutoScroll.setSelected(true); + mnScroll.add(miAutoScroll); + + miAutoScroll.addItemListener(new ItemListener(){ + public void itemStateChanged(ItemEvent e){ + if (e.getStateChange() == ItemEvent.DESELECTED){ + autoScroll_ = false; + } + else if (e.getStateChange() == ItemEvent.SELECTED){ + autoScroll_ = true; + } + updateResourceWindow(); + } + }); + + menuCommand.add(mnScroll); + menuBar.add(menuCommand); + setJMenuBar(menuBar); + } + private void updateResourceWindow(){ pnGraph_.repaint(); + + if(slidingWindowSize_ != Double.MAX_VALUE) { + int max = sclGraph_.getHorizontalScrollBar().getMaximum(); + if(autoScroll_) { + Rectangle visRect = sclGraph_.getVisibleRect(); + Rectangle rect = new Rectangle(max - visRect.width, + 0, visRect.width, sclGraph_.getHeight()); + sclGraph_.getHorizontalScrollBar().setValue(max - visRect.width); + sclGraph_.scrollRectToVisible(rect); + } + } } /** @@ -413,7 +500,7 @@ // calculates the size of the two panels // to be added to the window int leftPanelWidth = (int)((ResourceWindow.this.getWidth()) * PROPORTION_LEFT_PANEL); - int panelsHeight = (int)((ResourceWindow.this.getHeight()) - 20); + int panelsHeight = (int)((ResourceWindow.this.getHeight()) - 40); int gridletPanelWidth = (int)((ResourceWindow.this.getWidth()) * PROPORTION_RIGHT_PANEL) - 10; int leftPanelXPos = 0; int gridletPanelXPos = leftPanelXPos + leftPanelWidth; @@ -475,7 +562,15 @@ double timeSpan = settings_.getTimeSpan(); panelHeight_ = pnLeft_.getHeight() - 100 - SHIFT_Y - SHIFT_BOTTOM; - panelWidth_ = pnLeft_.getWidth() - 50 - 2 * SHIFT_X; + int minWidth = pnLeft_.getWidth() - 50 - 2 * SHIFT_X; + panelWidth_ = minWidth; + + double sdWindowSize = ResourceWindow.this.slidingWindowSize_; + if(sdWindowSize != Double.MAX_VALUE) + panelWidth_ = (int)( minWidth * (settings_.getTimeSpan() / sdWindowSize)); + + if(panelWidth_ < minWidth) + panelWidth_ = minWidth; scaleY_ = panelHeight_ / (float) numPE_; scaleX_ = panelWidth_ / (float) (timeSpan); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <xu...@us...> - 2008-02-07 10:53:13
|
Revision: 89 http://gridsim.svn.sourceforge.net/gridsim/?rev=89&view=rev Author: xulio Date: 2008-02-07 02:53:15 -0800 (Thu, 07 Feb 2008) Log Message: ----------- First Parcial Version Added Paths: ----------- branches/gridsim-4.1-parallel/source/gridsim/exceptions/ branches/gridsim-4.1-parallel/source/gridsim/exceptions/SimulationOrderException.java branches/gridsim-4.1-parallel/source/gridsim/exceptions/SimulationParameterException.java Added: branches/gridsim-4.1-parallel/source/gridsim/exceptions/SimulationOrderException.java =================================================================== --- branches/gridsim-4.1-parallel/source/gridsim/exceptions/SimulationOrderException.java (rev 0) +++ branches/gridsim-4.1-parallel/source/gridsim/exceptions/SimulationOrderException.java 2008-02-07 10:53:15 UTC (rev 89) @@ -0,0 +1,34 @@ +/* + * Title: GridSim Toolkit + * Description: GridSim (Grid Simulation) Toolkit for Modeling and Simulation + * of Parallel and Distributed Systems such as Clusters and Grids + * Licence: GPL - http://www.gnu.org/copyleft/gpl.html + * + */ + +package gridsim.exceptions; + +import gridsim.ParameterException; + +/** + * This exception is thrown when a method with a prerequisite is called before + * that the prerequisite is realized. + * + * @author Xulio López + * @since GridSim 4.2 + */ +public class SimulationOrderException extends ParameterException { + + /** + * Eclipse autogenerated serial version UID + */ + private static final long serialVersionUID = -1257052338586906917L; + + /** + * Constructs an SimulationOrderException with the incomplete prerequisite. + */ + public SimulationOrderException(String prerequisite) { + super("The prerequisite[" + prerequisite + "] is not ready"); + } + +} Added: branches/gridsim-4.1-parallel/source/gridsim/exceptions/SimulationParameterException.java =================================================================== --- branches/gridsim-4.1-parallel/source/gridsim/exceptions/SimulationParameterException.java (rev 0) +++ branches/gridsim-4.1-parallel/source/gridsim/exceptions/SimulationParameterException.java 2008-02-07 10:53:15 UTC (rev 89) @@ -0,0 +1,35 @@ +/* + * Title: GridSim Toolkit + * Description: GridSim (Grid Simulation) Toolkit for Modeling and Simulation + * of Parallel and Distributed Systems such as Clusters and Grids + * Licence: GPL - http://www.gnu.org/copyleft/gpl.html + */ +package gridsim.exceptions; + +import gridsim.ParameterException; + +/** + * This exception is thrown when an invalid value is is used as parameter in a + * simulation. + * + * @author Xulio López + * + */ +public class SimulationParameterException extends ParameterException { + + /** + * Eclipse autogenerated serial version UID + */ + private static final long serialVersionUID = 6884571047904598758L; + + /** + * Constructs an SimulationParameterException with the invalid parameter. + * + * @param parameter + * with the invalid value + */ + public SimulationParameterException(String parameter) { + super("Invalid value for parameter " + parameter); + } + +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <xu...@us...> - 2008-02-07 10:47:47
|
Revision: 88 http://gridsim.svn.sourceforge.net/gridsim/?rev=88&view=rev Author: xulio Date: 2008-02-07 02:47:50 -0800 (Thu, 07 Feb 2008) Log Message: ----------- First Parcial Version Added Paths: ----------- branches/gridsim-4.1-parallel/source/es/ branches/gridsim-4.1-parallel/source/es/usc/ branches/gridsim-4.1-parallel/source/es/usc/ac/ branches/gridsim-4.1-parallel/source/es/usc/ac/gridsim/ branches/gridsim-4.1-parallel/source/es/usc/ac/gridsim/extensions/ branches/gridsim-4.1-parallel/source/es/usc/ac/gridsim/extensions/failsimulator/ branches/gridsim-4.1-parallel/source/es/usc/ac/gridsim/extensions/failsimulator/FailMachine.java branches/gridsim-4.1-parallel/source/es/usc/ac/gridsim/extensions/failsimulator/FailMachineList.java branches/gridsim-4.1-parallel/source/es/usc/ac/gridsim/extensions/failsimulator/FailurableAllocPolicy.java branches/gridsim-4.1-parallel/source/es/usc/ac/gridsim/extensions/failsimulator/FailureSource.java branches/gridsim-4.1-parallel/source/es/usc/ac/gridsim/extensions/failsimulator/FaultAwareGridlet.java branches/gridsim-4.1-parallel/source/es/usc/ac/gridsim/extensions/failsimulator/GridFailurableResource.java branches/gridsim-4.1-parallel/source/es/usc/ac/gridsim/extensions/failsimulator/GridFailure.java branches/gridsim-4.1-parallel/source/es/usc/ac/gridsim/extensions/failsimulator/GridFailureEvent.java branches/gridsim-4.1-parallel/source/es/usc/ac/gridsim/extensions/failsimulator/GridResourceFailureScheme.java branches/gridsim-4.1-parallel/source/es/usc/ac/gridsim/extensions/failsimulator/MarkovFailureSchemeSpecification.java branches/gridsim-4.1-parallel/source/es/usc/ac/gridsim/extensions/failsimulator/MarkovGridResourceFailureScheme.java branches/gridsim-4.1-parallel/source/es/usc/ac/gridsim/extensions/failsimulator/SimpleGridResourceFailureSchema.java branches/gridsim-4.1-parallel/source/es/usc/ac/gridsim/extensions/failsimulator/allocs/ branches/gridsim-4.1-parallel/source/es/usc/ac/gridsim/extensions/failsimulator/allocs/BackFillingAlloc.java branches/gridsim-4.1-parallel/source/es/usc/ac/gridsim/extensions/failsimulator/allocs/BackFillingL1Alloc.java branches/gridsim-4.1-parallel/source/es/usc/ac/gridsim/extensions/failsimulator/allocs/EASYBackFillingAlloc.java branches/gridsim-4.1-parallel/source/es/usc/ac/gridsim/extensions/failsimulator/allocs/FIFOAlloc.java branches/gridsim-4.1-parallel/source/es/usc/ac/gridsim/extensions/failsimulator/allocs/FirstFitAlloc.java branches/gridsim-4.1-parallel/source/es/usc/ac/gridsim/extensions/failsimulator/parallel/ branches/gridsim-4.1-parallel/source/es/usc/ac/gridsim/extensions/failsimulator/parallel/FailurableParallelAlllocPolicy.java branches/gridsim-4.1-parallel/source/es/usc/ac/gridsim/extensions/failsimulator/parallel/GridFailurableParallelResource.java branches/gridsim-4.1-parallel/source/gridsim/parallel/ branches/gridsim-4.1-parallel/source/gridsim/parallel/GridParallelResource.java branches/gridsim-4.1-parallel/source/gridsim/parallel/InternalNetworkModel.java branches/gridsim-4.1-parallel/source/gridsim/parallel/PTPModel/ branches/gridsim-4.1-parallel/source/gridsim/parallel/PTPModel/PTPParallelGridlet.java branches/gridsim-4.1-parallel/source/gridsim/parallel/PTPModel/PTPParallelTask.java branches/gridsim-4.1-parallel/source/gridsim/parallel/PTPModel/ResPTPParallelGridlet.java branches/gridsim-4.1-parallel/source/gridsim/parallel/PTPModel/ResPTPParallelTask.java branches/gridsim-4.1-parallel/source/gridsim/parallel/PTPModel/communications/ branches/gridsim-4.1-parallel/source/gridsim/parallel/PTPModel/communications/CollectiveTaskCommunication.java branches/gridsim-4.1-parallel/source/gridsim/parallel/PTPModel/communications/ResCollectiveTaskCommunication.java branches/gridsim-4.1-parallel/source/gridsim/parallel/PTPModel/communications/ResTaskCommunication.java branches/gridsim-4.1-parallel/source/gridsim/parallel/PTPModel/communications/TaskCommunication.java branches/gridsim-4.1-parallel/source/gridsim/parallel/ParallelAllocPolicy.java branches/gridsim-4.1-parallel/source/gridsim/parallel/ParallelGridlet.java branches/gridsim-4.1-parallel/source/gridsim/parallel/ParallelResourceCharacteristics.java branches/gridsim-4.1-parallel/source/gridsim/parallel/ParallelTask.java branches/gridsim-4.1-parallel/source/gridsim/parallel/PerformanceModeledGridlet.java branches/gridsim-4.1-parallel/source/gridsim/parallel/ResParallelGridlet.java branches/gridsim-4.1-parallel/source/gridsim/parallel/ResParallelTask.java branches/gridsim-4.1-parallel/source/gridsim/parallel/innacuracy/ branches/gridsim-4.1-parallel/source/gridsim/parallel/innacuracy/InaccuracyModel.java branches/gridsim-4.1-parallel/source/gridsim/parallel/innacuracy/NullInacuraccyModel.java branches/gridsim-4.1-parallel/source/gridsim/parallel/scheduler/ branches/gridsim-4.1-parallel/source/gridsim/parallel/scheduler/GridWorkflowScheduler.java branches/gridsim-4.1-parallel/source/gridsim/parallel/scheduler/UserWorkflow.java branches/gridsim-4.1-parallel/source/gridsim/parallel/scheduler/WorkFlowElement.java Added: branches/gridsim-4.1-parallel/source/es/usc/ac/gridsim/extensions/failsimulator/FailMachine.java =================================================================== --- branches/gridsim-4.1-parallel/source/es/usc/ac/gridsim/extensions/failsimulator/FailMachine.java (rev 0) +++ branches/gridsim-4.1-parallel/source/es/usc/ac/gridsim/extensions/failsimulator/FailMachine.java 2008-02-07 10:47:50 UTC (rev 88) @@ -0,0 +1,76 @@ +package es.usc.ac.gridsim.extensions.failsimulator; + +import gridsim.Machine; +import gridsim.PEList; + +/** + * This class adds to Machine a availability state. + * + * If the machine is not available, the number of Free and Busy PE is zero. + * + * + * @author Xulio Lopez + * + */ +public class FailMachine extends Machine { + private boolean avaliable = true; + + /** + * Allocates a new FailMachine object + * + * @param id + * the machine ID + * @param list + * list of PEs + */ + public FailMachine(int id, PEList list) { + super(id, list); + } + + /** + * Gets the number of Free PE for this Machine (if the machine is + * not available, this will be zero) + * + * @return number of free PE + */ + public int getNumFreePE() { + if (avaliable) + return super.getNumFreePE(); + else + return 0; + } + + /** + * Gets the number of Busy PE for this Machine (if the machine is + * not available, this will be zero) + * + * @return number of PE + */ + public int getNumBusyPE() { + if (avaliable) + return super.getNumBusyPE(); + else + return 0; + } + + /** + * Returns true if the machine is available, false in another case + * @return available state of the machine + */ + public boolean isAvaliable() { + return avaliable; + } + + /** + * Set the machine to true if it is available, false in another case + * @param available Available state of the machine + */ + public void setAvaliable(boolean avaliable) { + this.avaliable = avaliable; + } + + /* + * TODO Implements setStatusPE and getPEList ? + */ + +} Added: branches/gridsim-4.1-parallel/source/es/usc/ac/gridsim/extensions/failsimulator/FailMachineList.java =================================================================== --- branches/gridsim-4.1-parallel/source/es/usc/ac/gridsim/extensions/failsimulator/FailMachineList.java (rev 0) +++ branches/gridsim-4.1-parallel/source/es/usc/ac/gridsim/extensions/failsimulator/FailMachineList.java 2008-02-07 10:47:50 UTC (rev 88) @@ -0,0 +1,52 @@ +package es.usc.ac.gridsim.extensions.failsimulator; + +import gridsim.MachineList; + +import java.util.Iterator; + +public class FailMachineList extends MachineList { + + /** + * This class extends MachineList to support FailMachines. If FaimMachines + * are used with a MachineList (not a FailMachineList), the value of + * {@link MachineList#getNumBusyPE()} will be incorrect. + */ + + /** + * + */ + private static final long serialVersionUID = -5222520374108245681L; + + /** + * Gets the total number of no available PEs for all Machines + * + * @return number of PEs + * @pre $none + * @post $result >= 0 + */ + public int getNumFailPE() { + int failed = 0; + FailMachine obj = null; + + Iterator it = super.iterator(); + while (it.hasNext()) { + obj = (FailMachine) it.next(); + if (!obj.isAvaliable()) + failed += obj.getNumPE(); + } + + return failed; + } + + /** + * Gets the total number of <tt>BUSY</tt> PEs for all Machines + * + * @return number of PEs + * @pre $none + * @post $result >= 0 + */ + public int getNumBusyPE() { + return this.getNumPE() - this.getNumFreePE() - this.getNumFailPE(); + } + +} Added: branches/gridsim-4.1-parallel/source/es/usc/ac/gridsim/extensions/failsimulator/FailurableAllocPolicy.java =================================================================== --- branches/gridsim-4.1-parallel/source/es/usc/ac/gridsim/extensions/failsimulator/FailurableAllocPolicy.java (rev 0) +++ branches/gridsim-4.1-parallel/source/es/usc/ac/gridsim/extensions/failsimulator/FailurableAllocPolicy.java 2008-02-07 10:47:50 UTC (rev 88) @@ -0,0 +1,57 @@ +package es.usc.ac.gridsim.extensions.failsimulator; + +//FIXME Search a way to force to implement AllocPolicy too +/** + * This Interface must be implemented by AllocPolicies adapted to failure + * simulation. + * + * Only policies with this interface are allowed in a GridFailurableResource. + * + * Implement this interface should allow to response to a internal error in a + * GridResoruce {@link #setInternalError(boolean, boolean, boolean)} and a fail + * in a machine {@link #processMachineStatusChange(boolean, int)} + * + * @see GridFailurableResource + */ +public interface FailurableAllocPolicy { + + /** + * This method is called when a GridResource has a failure status change. + * + * Usually, If a error happens, the gridlet execution has to been modified + * (canceled or rescheduled in the local queue), and it could only modify + * execution gridlet or also queued ones. + * + * @param status + * the availability status + * @param cancel + * True if the gridlet must be canceled by a error, false if they + * must be rescheduled + * @param onlyExecution + * True if only the gridlets in execution must be canceled or + * rescheduled, false if also queued gridlet are affected. + */ + void setInternalError(boolean status, boolean cancel, boolean onlyExecution); + + /** + * This method is called if a machine of the local GridResource changes its + * available state. + * + * If a error happens, the gridlets executed in that machine should be + * canceled or rescheduled. + * + * @param status + * False to set the status to unavailable, true to set the status + * to available. + * @param machineID + * Internal ID of the machine + */ + void processMachineStatusChange(boolean status, int machineID); + + /** + * Returns if the state is available or not. + * + * @return true if a the state is no available, false in another case. + */ + public boolean hasInternalError(); +} Added: branches/gridsim-4.1-parallel/source/es/usc/ac/gridsim/extensions/failsimulator/FailureSource.java =================================================================== --- branches/gridsim-4.1-parallel/source/es/usc/ac/gridsim/extensions/failsimulator/FailureSource.java (rev 0) +++ branches/gridsim-4.1-parallel/source/es/usc/ac/gridsim/extensions/failsimulator/FailureSource.java 2008-02-07 10:47:50 UTC (rev 88) @@ -0,0 +1,78 @@ +package es.usc.ac.gridsim.extensions.failsimulator; + +import eduni.simjava.Sim_entity; +import eduni.simjava.Sim_port; +import eduni.simjava.Sim_system; + +/** + * Provides a source to generate failures to a GridResource following a + * GridResourceFailureScheme. + * + * @author Xulio Lopez + * + */ +public class FailureSource extends Sim_entity { + + private GridResourceFailureScheme failures; + private Sim_port failurePort; + private boolean shutdown; + + /** + * Allocates a FailureSource that follows the provided + * GridResourceFailureScheme + * + * @param name + * @param failures + * the GridResourceFailureScheme that determines its behaviour + */ + public FailureSource(String name, GridResourceFailureScheme failures) { + // TODO Auto-generated constructor stub + super(name); + this.failures = failures; + this.failurePort = new Sim_port("fail_out-" + this.get_id()); + super.add_port(failurePort); + } + + /** + * Main method that throws the failures inside of the simulation. + */ + public void body() { + double renewal; + while (Sim_system.running() && failures != null & !shutdown) { + System.out.println("Adding new failures"); + for (GridFailureEvent failure : failures) + // TODO Check this. Necessary both? + if (failure.getMachineID() < 0) + sim_schedule(failurePort, failure.getDelay(), failure + .getEventCode()); + else + sim_schedule(failurePort, failure.getDelay(), failure + .getEventCode(), failure.getMachineID()); + renewal = failures.getRenewalInterval(); + if (renewal <= 0.0) + break; + // sim_schedule(this.get_id(),renewal,GridSimTags.INSIGNIFICANT); + // this.sim_get_next(ev); + // The next solution is better + sim_pause(renewal); + System.out.println("All data processed: " + Sim_system.clock()); + if (Sim_system.running() & !shutdown) { + failures = failures.renewalScheme(); + if (failures != null) + System.out.println("New scheme generated"); + } + + } + System.out.println("The system is " + Sim_system.running() + " with " + + ((failures != null) ? "some" : "any") + " failures"); + + } + + /** + * Stops the generation of failures by this FailureSource. + */ + public void terminate() { + shutdown = true; + } + +} Added: branches/gridsim-4.1-parallel/source/es/usc/ac/gridsim/extensions/failsimulator/FaultAwareGridlet.java =================================================================== --- branches/gridsim-4.1-parallel/source/es/usc/ac/gridsim/extensions/failsimulator/FaultAwareGridlet.java (rev 0) +++ branches/gridsim-4.1-parallel/source/es/usc/ac/gridsim/extensions/failsimulator/FaultAwareGridlet.java 2008-02-07 10:47:50 UTC (rev 88) @@ -0,0 +1,35 @@ +package es.usc.ac.gridsim.extensions.failsimulator; + +/** + * A gridlet that records logs of the influence of failures in its execution. + * + * + * @author Xulio Lopez + * + */ +public interface FaultAwareGridlet { + /** + * Stores information of the failure influence + * + * @param stops + * Number of stops due to failures + * @param lostTime + * Computation time or or communication time lost due to failures + */ + public void setReescheduledStats(int stops, double lostTime); + + /** + * Provides information of the number of reeschedulings due to failures + * + * @return Number of reeschedulings + */ + public int getNumberOfFailureReeschedulings(); + + /** + * Provides information of the lost time in canceled executions or lost + * communications + * + * @return lost time + */ + public double getLostTime(); +} Added: branches/gridsim-4.1-parallel/source/es/usc/ac/gridsim/extensions/failsimulator/GridFailurableResource.java =================================================================== --- branches/gridsim-4.1-parallel/source/es/usc/ac/gridsim/extensions/failsimulator/GridFailurableResource.java (rev 0) +++ branches/gridsim-4.1-parallel/source/es/usc/ac/gridsim/extensions/failsimulator/GridFailurableResource.java 2008-02-07 10:47:50 UTC (rev 88) @@ -0,0 +1,178 @@ +package es.usc.ac.gridsim.extensions.failsimulator; + +import eduni.simjava.Sim_event; +import eduni.simjava.Sim_port; +import eduni.simjava.Sim_system; +import gridsim.AllocPolicy; +import gridsim.GridResource; +import gridsim.Machine; +import gridsim.ResourceCalendar; +import gridsim.ResourceCharacteristics; +import gridsim.net.Link; + +import java.util.HashMap; +import java.util.Map; + +public class GridFailurableResource extends GridResource { + private FailureSource failureSource; + + private boolean terminateFailureIOEntitiesFlag_; + + private boolean available,cancelOnFailure; + + private FailurableAllocPolicy fPolicy; + + public GridFailurableResource(String name, double baud_rate, + ResourceCharacteristics resource, ResourceCalendar calendar, + GridResourceFailureScheme failures, boolean cancelOnFailure, + FailurableAllocPolicy policy) throws Exception { + super(name, baud_rate, resource, calendar, (AllocPolicy) policy); + this.cancelOnFailure = cancelOnFailure; + failures.initialize(this.getMachineMapState(), true); + failureSource = generteFailureSource(failures); + fPolicy = policy; + } + + /** + * Allocates a new GridParallelResource object. Sets as default AllocPolicy + * the SpaceParallelShared + * + * @param name + * the name to be associated with this entity (as required by + * Sim_entity class from simjava package) + * @param link + * the link that will be used to connect this GridResource to + * another Entity or Router. + * @param resource + * an object of ResourceCharacteristics + * @param calendar + * an object of ResourceCalendar + * @param internalNet + * a internal network model + * @param policy + * a scheduling policy for this Grid resource. + * + * @throws Exception + * //TODO explain and concrete exception + * @see GridResource(String, double, ResourceCharacteristics, + * ResourceCalendar) + */ + + public GridFailurableResource(String name, Link link, + ResourceCharacteristics resource, ResourceCalendar calendar, + GridResourceFailureScheme failures, boolean cancelOnFailure, + FailurableAllocPolicy policy) throws Exception { + super(name, link, resource, calendar, (AllocPolicy) policy); + failures.initialize(this.getMachineMapState(), true); + failureSource = generteFailureSource(failures); + this.cancelOnFailure = cancelOnFailure; + fPolicy = policy; + } + + /* + * public GridFailurableParallelResource(String name, double baud_rate, + * ParallelResourceCharacteristics resource, ResourceCalendar calendar, + * MarkovFailureSchemeSpecification specification, boolean cancelOnFailure) + * throws Exception { super(name, baud_rate, resource, calendar, new + * FailSpaceParallelShared(name,"ParallelScheduler",resource.getInternalNetworkModel(),cancelOnFailure)); + * GridResourceFailureScheme failures=new + * MarkovGridResourceFailureScheme(specification,this.getMachineMapState(),true); + * failureSource=generteFailureSource(failures); + * fPolicy=(FailurableParallelAlllocPolicy) this.policy_; } public + * GridFailurableParallelResource(String name, Link link, + * ParallelResourceCharacteristics resource, ResourceCalendar calendar, + * MarkovFailureSchemeSpecification specification, boolean cancelOnFailure) + * throws Exception { super(name, link, resource, calendar, new + * FailSpaceParallelShared(name,"ParallelScheduler",resource.getInternalNetworkModel(),cancelOnFailure)); + * GridResourceFailureScheme failures=new + * MarkovGridResourceFailureScheme(specification,this.getMachineMapState(),true); + * failureSource=generteFailureSource(failures); + * fPolicy=(FailurableParallelAlllocPolicy) this.policy_; } + */ + + private FailureSource generteFailureSource( + GridResourceFailureScheme failures) { + + add_port(new Sim_port("fail_in-" + this.get_id())); + // FIXME Where does the port have to be created? + FailureSource source = new FailureSource(this.get_name() + + "_FailureSource", failures); + Sim_system.link_ports(this.get_name(), "fail_in-" + this.get_id(), + source.get_name(), "fail_out-" + source.get_id()); + return source; + } + + public Map<Integer, Boolean> getMachineMapState() { + Map<Integer, Boolean> machines = new HashMap<Integer, Boolean>(); + for (Object omachine : this.resource_.getMachineList()) + if (omachine instanceof FailMachine) { + FailMachine machine = (FailMachine) omachine; + machines.put(machine.getMachineID(), machine.isAvaliable()); + } + return machines; + } + + public void preprocessEvent(@SuppressWarnings("unused") + Sim_event ev) { + // FIXME To avoid normal behaviour + } + + public void processOtherEvent(Sim_event ev) { + // FIXME Set a GridResourceLevel? Save logs. + if (ev.type() == GridFailureEvent.GRID_MACHINE_FAILURE_EVENT) { + setMachineAvaliability(false, (Integer) ev.get_data()); + } else if (ev.type() == GridFailureEvent.GRID_MACHINE_RECOVER_EVENT) { + setMachineAvaliability(true, (Integer) ev.get_data()); + } else if (ev.type() == GridFailureEvent.GRID_RESOURCE_FRONTEND_FAILURE_EVENT) { + available = false; + } else if (ev.type() == GridFailureEvent.GRID_RESOURCE_FRONTEND_RECOVER_EVENT) { + available = true; + } else if (ev.type() == GridFailureEvent.GRID_RESOURCE_TOTAL_FAILURE_EVENT) { + available = false; + fPolicy.setInternalError(true, true, true); + } else if (ev.type() == GridFailureEvent.GRID_RESOURCE_TOTAL_RECOVER_EVENT) { + available = true; + fPolicy.setInternalError(false, true, true); + } else + super.processOtherEvent(ev); + + } + + public boolean isAvailable() { + return available; + } + + public void body() { + super.body(); + terminateIOEntities(); + } + + protected void terminateIOEntities() { + // If it is Networked entity and Not yet terminated, then terminate. + if (!terminateFailureIOEntitiesFlag_) { + failureSource.terminate(); +/* + // Send END_OF_SIMULATION to Failure Input entity + send("fail-in-" + this.get_id(), 0.0, GridSimTags.END_OF_SIMULATION); + + // Send END_OF_SIMULATION to Failure Output entity + send("fail-out-" + failureSource.get_id(), 0.0, + GridSimTags.END_OF_SIMULATION); +*/ + terminateFailureIOEntitiesFlag_ = true; + } + super.terminateIOEntities(); + } + + protected boolean setMachineAvaliability(boolean status, int machineID) { + //boolean result; + Machine mac = resource_.getMachineList().getMachine(machineID); + if (mac instanceof FailMachine) { + ((FailMachine) mac).setAvaliable(status); + fPolicy.processMachineStatusChange(status, machineID); + return true; + } else + return false; + } + +} Added: branches/gridsim-4.1-parallel/source/es/usc/ac/gridsim/extensions/failsimulator/GridFailure.java =================================================================== --- branches/gridsim-4.1-parallel/source/es/usc/ac/gridsim/extensions/failsimulator/GridFailure.java (rev 0) +++ branches/gridsim-4.1-parallel/source/es/usc/ac/gridsim/extensions/failsimulator/GridFailure.java 2008-02-07 10:47:50 UTC (rev 88) @@ -0,0 +1,31 @@ +package es.usc.ac.gridsim.extensions.failsimulator; + +/** + * + * @author Xulio Lopez + * + */ +public class GridFailure { + private double delay,length; + private int machineID; + + public GridFailure(double delay,double length,int machineID) { + super(); + this.delay=delay; + this.length=length; + this.machineID=machineID; + } + + public int hashCode(){ + return (int)delay; + } + + public int getMachineID(){return machineID;} + public double getDelay(){return delay;} + public double getLength(){return length;} + + public final static double UNRECOVERABLE_FAILURE=-1.0; + + public final static int GENERAL_FAILURE=-1000; + +} Added: branches/gridsim-4.1-parallel/source/es/usc/ac/gridsim/extensions/failsimulator/GridFailureEvent.java =================================================================== --- branches/gridsim-4.1-parallel/source/es/usc/ac/gridsim/extensions/failsimulator/GridFailureEvent.java (rev 0) +++ branches/gridsim-4.1-parallel/source/es/usc/ac/gridsim/extensions/failsimulator/GridFailureEvent.java 2008-02-07 10:47:50 UTC (rev 88) @@ -0,0 +1,53 @@ +package es.usc.ac.gridsim.extensions.failsimulator; + +public class GridFailureEvent { + + private double delay; + private int machineID,eventCode; + private boolean fail; + + public GridFailureEvent(double delay,int machineID,boolean fail) { + this.delay=delay; + this.machineID=machineID; + this.eventCode=(fail?GRID_MACHINE_FAILURE_EVENT:GRID_MACHINE_RECOVER_EVENT); + this.fail=fail; + } + public GridFailureEvent(double delay,boolean fail,int type) { + this.delay=delay; + this.machineID=GENERAL_FAILURE; + this.eventCode=FAILURE_BASE+type+(fail?FAILURE:RECOVER); + this.fail=fail; + } + + public int hashCode(){ + return (int)delay; + } + + public int getMachineID(){return machineID;} + public double getDelay(){return delay;} + public int getEventCode(){ + return eventCode; + } + + public final static int GENERAL_FAILURE=-10000; + + private static int FAILURE_BASE=3000; + private static int FAILURE=0; + private static int RECOVER=1; + public final static int GRID_RESOURCE_TOTAL=3; + public final static int GRID_RESOURCE_INTERNAL=5; + public final static int GRID_RESOURCE_FRONTEND=7; + public final static int GRID_MACHINE_FAILURE_EVENT=FAILURE_BASE+1; + public final static int GRID_MACHINE_RECOVER_EVENT=FAILURE_BASE+2; + public final static int GRID_RESOURCE_TOTAL_FAILURE_EVENT=FAILURE_BASE+GRID_RESOURCE_TOTAL+FAILURE; + public final static int GRID_RESOURCE_TOTAL_RECOVER_EVENT=FAILURE_BASE+GRID_RESOURCE_TOTAL+RECOVER; + public final static int GRID_RESOURCE_INTERNAL_FAILURE_EVENT=FAILURE_BASE+GRID_RESOURCE_INTERNAL+FAILURE; + public final static int GRID_RESOURCE_INTERNAL_RECOVER_EVENT=FAILURE_BASE+GRID_RESOURCE_INTERNAL+RECOVER; + public final static int GRID_RESOURCE_FRONTEND_FAILURE_EVENT=FAILURE_BASE+GRID_RESOURCE_FRONTEND+FAILURE; + public final static int GRID_RESOURCE_FRONTEND_RECOVER_EVENT=FAILURE_BASE+GRID_RESOURCE_FRONTEND+RECOVER; + + public String toString(){ + return new String("Machine:"+machineID+"\tDelay: "+delay+'\t'+(fail?"FAIL":"RECOVER")); + } +} + Added: branches/gridsim-4.1-parallel/source/es/usc/ac/gridsim/extensions/failsimulator/GridResourceFailureScheme.java =================================================================== --- branches/gridsim-4.1-parallel/source/es/usc/ac/gridsim/extensions/failsimulator/GridResourceFailureScheme.java (rev 0) +++ branches/gridsim-4.1-parallel/source/es/usc/ac/gridsim/extensions/failsimulator/GridResourceFailureScheme.java 2008-02-07 10:47:50 UTC (rev 88) @@ -0,0 +1,18 @@ +package es.usc.ac.gridsim.extensions.failsimulator; + +import java.util.Map; + +//FIXME Remove this class or use a LinkedList. Must I Use a interfaze? +public abstract class GridResourceFailureScheme implements Iterable<GridFailureEvent>{ + protected double renewalInterval; + + + public double getRenewalInterval(){ + return renewalInterval; + } + + public abstract GridResourceFailureScheme renewalScheme(); + + public abstract void initialize(Map<Integer, Boolean> resource, boolean resourceState); + +} Added: branches/gridsim-4.1-parallel/source/es/usc/ac/gridsim/extensions/failsimulator/MarkovFailureSchemeSpecification.java =================================================================== --- branches/gridsim-4.1-parallel/source/es/usc/ac/gridsim/extensions/failsimulator/MarkovFailureSchemeSpecification.java (rev 0) +++ branches/gridsim-4.1-parallel/source/es/usc/ac/gridsim/extensions/failsimulator/MarkovFailureSchemeSpecification.java 2008-02-07 10:47:50 UTC (rev 88) @@ -0,0 +1,26 @@ +package es.usc.ac.gridsim.extensions.failsimulator; + + +public class MarkovFailureSchemeSpecification { + public final double renewalInterval; + public final double machineFail; + public final double machineRestore; + public final double resourceFail; + public final double resourceRestore; + public final RenewalMethod method; + + public MarkovFailureSchemeSpecification(double renewalInterval, + double machineFail, double machineRestore, double resourceFail, + double resourceRestore, RenewalMethod method){ + this.renewalInterval=renewalInterval; + this.machineFail=1-machineFail; + this.machineRestore=1-machineRestore; + this.resourceFail=1-resourceFail; + this.resourceRestore=1-resourceRestore; + this.method=method; + } + + public enum RenewalMethod { + cyclic, recalculate,regenerate, none + } +} Added: branches/gridsim-4.1-parallel/source/es/usc/ac/gridsim/extensions/failsimulator/MarkovGridResourceFailureScheme.java =================================================================== --- branches/gridsim-4.1-parallel/source/es/usc/ac/gridsim/extensions/failsimulator/MarkovGridResourceFailureScheme.java (rev 0) +++ branches/gridsim-4.1-parallel/source/es/usc/ac/gridsim/extensions/failsimulator/MarkovGridResourceFailureScheme.java 2008-02-07 10:47:50 UTC (rev 88) @@ -0,0 +1,136 @@ +package es.usc.ac.gridsim.extensions.failsimulator; + +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; +import java.util.Random; +import java.util.Set; +import java.util.Map.Entry; + +public class MarkovGridResourceFailureScheme extends GridResourceFailureScheme { + Set<GridFailureEvent> failures; + //private double machineFail, machineRestore, resourceFail, resourceRestore; + //private MarkovFailureSchemeSpecification.RenewalMethod method; + private MarkovFailureSchemeSpecification specification; + private Map<Integer,Boolean> resource; + private boolean resourceState; + + /** + * Statistacal model of failures of a GridResource + * @param renewalInterval fails are generated for this interval + * @param machineFail probability of fail of a avalible machine + * @param machineRestore probability of restore of a unavaliable machine + * @param resourceFail probability of fail of a avalible resource + * @param resourceRestore probability of restore of a unavaliable resource + * @param method strategy to genrate fail after the renewal interval + * @param resource descriptions of states of machines of a gridresource + * + */ + public MarkovGridResourceFailureScheme(MarkovFailureSchemeSpecification specification) + //double renewalInterval,double machineFail, double machineRestore, double resourceFail,double resourceRestore, MarkovFailureSchemeSpecification.RenewalMethod method, + { + this.renewalInterval = specification.renewalInterval; + //TODO check values +/* this.machineFail=machineFail; + this.machineRestore=machineRestore; + this.resourceFail=resourceFail; + this.resourceRestore=resourceRestore; + + this.method=method;*/ + this.specification=specification; + } + + + public void initialize(Map<Integer,Boolean> resource,boolean resourceState){ + this.resource=resource; + this.resourceState=resourceState; + + failures=simulate(); + + } + + + @Override + public GridResourceFailureScheme renewalScheme() { + switch (specification.method) { + case cyclic: + return this; + case regenerate: + GridResourceFailureScheme grfs=new MarkovGridResourceFailureScheme(specification); + grfs.initialize(resource,resourceState); + return grfs; + case recalculate: + failures=simulate(); + return this; + default: + return null; + } + } + + public Iterator<GridFailureEvent> iterator() { + if(failures!=null) return failures.iterator(); + //TODO Return a null or a empty one? + return null; + } + + + + private Set<GridFailureEvent> simulate(){ + System.out.println("New Simulation "); + Set<GridFailureEvent> sfailures=new HashSet<GridFailureEvent>(); + for(Entry<Integer,Boolean> machine:resource.entrySet()) + machine.setValue(simulateMachine(machine.getKey(),machine.getValue(),specification.machineFail,specification.machineRestore,sfailures)); + resourceState=simulateResource(GridFailure.GENERAL_FAILURE,resourceState,specification.resourceFail,specification.resourceRestore,sfailures); + return sfailures; + } + + private boolean simulateMachine(int id,boolean state,double fail, double restore,Set<GridFailureEvent> failures){ + Random random=new Random(); + System.out.println("Simulating mac "+id); + double delay=0.0; + //TODO Don't recalculate all times this. + double[] logProp=new double[]{Math.log(fail),Math.log(restore)}; +// int code=(id<0)?0:1; + //If machine is avaliable, will take the fail posibility, and restore one in other case + if((state?fail:restore)==1.0) return false; + if((state?fail:restore)==0.0) delay+=1.0; + else delay=Math.ceil(Math.log(1-random.nextDouble())/(state?logProp[0]:logProp[1])); + while(delay<renewalInterval){ + GridFailureEvent event=new GridFailureEvent(delay,id,state); + System.out.println(event); + failures.add(event); + state=!state; + if((state?fail:restore)==1.0) return false; + if((state?fail:restore)==0.0) delay+=1.0; + else delay+=Math.ceil(Math.log(1-random.nextDouble())/(state?logProp[0]:logProp[1])); + } + return true; + } + + //FIXME Add parameters about the diferent states + private boolean simulateResource(int id,boolean state,double fail, double restore,Set<GridFailureEvent> failures){ + Random random=new Random(); + System.out.println("Simulating mac "+id); + double delay=0.0; + //TODO Don't recalculate all times this. + double[] logProp=new double[]{Math.log(fail),Math.log(restore)}; +// int code=(id<0)?0:1; + //If machine is avaliable, will take the fail posibility, and restore one in other case + if((state?fail:restore)==1.0) return state; + if((state?fail:restore)==0.0) delay+=1.0; + else delay=Math.ceil(Math.log(1-random.nextDouble())/(state?logProp[0]:logProp[1])); + while(delay<renewalInterval){ + GridFailureEvent event=new GridFailureEvent(delay,state,GridFailureEvent.GRID_RESOURCE_TOTAL); + System.out.println(event); + failures.add(event); + state=!state; + if((state?fail:restore)==1.0) return false; + if((state?fail:restore)==0.0) delay+=1.0; + else delay+=Math.ceil(Math.log(1-random.nextDouble())/(state?logProp[0]:logProp[1])); + } + return true; + } + +// private static int[][] failCodes=new int[][]{{GridFailureEvent.GRID_RESOURCE_FAILURE_EVENT,GridFailureEvent.GRID_RESOURCE_RECOVER_EVENT},{GridFailureEvent.GRID_MACHINE_FAILURE_EVENT,GridFailureEvent.GRID_MACHINE_RECOVER_EVENT}}; + +} Added: branches/gridsim-4.1-parallel/source/es/usc/ac/gridsim/extensions/failsimulator/SimpleGridResourceFailureSchema.java =================================================================== --- branches/gridsim-4.1-parallel/source/es/usc/ac/gridsim/extensions/failsimulator/SimpleGridResourceFailureSchema.java (rev 0) +++ branches/gridsim-4.1-parallel/source/es/usc/ac/gridsim/extensions/failsimulator/SimpleGridResourceFailureSchema.java 2008-02-07 10:47:50 UTC (rev 88) @@ -0,0 +1,59 @@ +package es.usc.ac.gridsim.extensions.failsimulator; + +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; + +public class SimpleGridResourceFailureSchema extends GridResourceFailureScheme { + + private HashSet<GridFailureEvent> failures = new HashSet<GridFailureEvent>(); + + //private double increaseTime = -1.0; + + private boolean cyclical, autoRenewal; + + public SimpleGridResourceFailureSchema(boolean cyclical, boolean autoInterval) { + this.autoRenewal = autoInterval; + this.cyclical = cyclical; + } + + @Override + public GridResourceFailureScheme renewalScheme() { + return ( cyclical ) ? this : null; + } + + public Iterator<GridFailureEvent> iterator() { + return failures.iterator(); + } + + public boolean add(GridFailureEvent failure) { + if (!failures.add(failure)) + return false; + if (autoRenewal && getRenewalInterval() < failure.getDelay()) + setRenewalInterval(failure.getDelay()); + return true; + } + + public boolean add(GridFailure failure) { + boolean result=true; + if(failure.getMachineID()==GridFailure.GENERAL_FAILURE){ + result&=add(new GridFailureEvent(failure.getDelay(),true,GridFailureEvent.GRID_RESOURCE_TOTAL)); + if(failure.getLength()>=0.0) result&=add(new GridFailureEvent(failure.getDelay()+failure.getLength(),false,GridFailureEvent.GRID_RESOURCE_TOTAL)); + }else{ + result&=add(new GridFailureEvent(failure.getDelay(),failure.getMachineID(),true)); + if(failure.getLength()>=0.0) result&=add(new GridFailureEvent(failure.getDelay()+failure.getLength(),failure.getMachineID(),false)); + } + return result; + } + + public void setRenewalInterval(double renewalInterval) { + this.renewalInterval = renewalInterval; + } + + + @Override + public void initialize(Map<Integer, Boolean> resource, boolean resourceState) { + // TODO Auto-generated method stub + //This method is not used + } +} Added: branches/gridsim-4.1-parallel/source/es/usc/ac/gridsim/extensions/failsimulator/allocs/BackFillingAlloc.java =================================================================== --- branches/gridsim-4.1-parallel/source/es/usc/ac/gridsim/extensions/failsimulator/allocs/BackFillingAlloc.java (rev 0) +++ branches/gridsim-4.1-parallel/source/es/usc/ac/gridsim/extensions/failsimulator/allocs/BackFillingAlloc.java 2008-02-07 10:47:50 UTC (rev 88) @@ -0,0 +1,260 @@ +/* + * Title: GridSim Toolkit + * Description: GridSim (Grid Simulation) Toolkit for Modeling and Simulation + * of Parallel and Distributed Systems such as Clusters and Grids + * Licence: GPL - http://www.gnu.org/copyleft/gpl.html + * + * $Id: BackFillingAlloc.java,v 1.1 2006/11/30 11:46:57 julio Exp $ + */ + +package es.usc.ac.gridsim.extensions.failsimulator.allocs; + +import java.util.Comparator; +import java.util.Iterator; +import java.util.SortedSet; +import java.util.TreeMap; +import java.util.TreeSet; +import java.util.Map.Entry; + + +import es.usc.ac.gridsim.extensions.failsimulator.parallel.FailurableParallelAlllocPolicy; +import gridsim.GridSim; +import gridsim.Gridlet; +import gridsim.Machine; +import gridsim.PE; +import gridsim.PEList; +import gridsim.parallel.InternalNetworkModel; +import gridsim.parallel.ResParallelGridlet; + +/** + * SpaceParallelShared class is an allocation policy for GridResource that + * behaves exactly like First Come First Serve (FCFS). This is a modification to + * SpaceShared that allows each Gridlet to be executed in more than one + * Processing Element (PE). Versioned to add support to parallel gridlets. + * + * @author Julio Lopez, based on SpaceShared by Manzur Murshed and Rajkumar + * Buyya + * @since GridSim Toolkit 4.0 + * @see gridsim.GridSim + * @see gridsim.ResourceCharacteristics + * @see gridsim.SpaceShare + * @invariant $none + */ +public class BackFillingAlloc extends FailurableParallelAlllocPolicy { + private SortedSet<ResParallelGridlet> sorteExecList; + boolean onlyExecutionFilling; + + + public BackFillingAlloc(String resourceName, String entityName, + InternalNetworkModel internalNet,boolean onlyExecutionFilling,boolean cancelOnFailures) throws Exception { + super(resourceName, entityName, internalNet,cancelOnFailures); + sorteExecList = new TreeSet<ResParallelGridlet>( + new Comparator<ResParallelGridlet>() { + public int compare(ResParallelGridlet o1, + ResParallelGridlet o2) { + if(o1.equals(o2)) return 0; + double estTime=((o1.getEstimatedTime() + o1 + .getExecStartTime()) - (o2.getEstimatedTime() + o2 + .getExecStartTime())); + return (estTime>0)?1:-1; + } + }); + this.onlyExecutionFilling=onlyExecutionFilling; + + } + + /** + * Allocates a Gridlet into a free PE and sets the Gridlet status into + * INEXEC and PE status into busy afterwards + * + * @param rgl + * a ResGridlet object + * @return <tt>true</tt> if there is an empty PE to process this Gridlet, + * <tt>false</tt> otherwise + * @pre rgl != null + * @post $none + */ + protected boolean allocatePEstoGridlet(ResParallelGridlet rpgl) { + // FIXME First basic implementation + // ResParallelGridlet rpgl = (ResParallelGridlet) rgl; + int tasks = rpgl.getNumPE(); + + int i = 0; + while (i < tasks) { + + // IDENTIFY MACHINE which has a free PE and add this Gridlet to it. + Machine myMachine = resource_.getMachineWithFreePE(); + + // If a Machine is empty then ignore the rest + if (myMachine == null) { + System.out.println("Fallou"); + return false; + // FIXME Esta salida no es valida + } + + // gets the list of PEs and find one empty PE + PEList MyPEList = myMachine.getPEList(); + while (MyPEList.getNumFreePE() > 0 && (i < tasks)) { + int freePEID = MyPEList.getFreePEID(); + rpgl.setMachineAndPEID(myMachine.getMachineID(), freePEID, + MyPEList.getMIPSRating(freePEID)); + i++; + // Set allocated PE to BUSY status + super.resource_.setStatusPE(PE.BUSY, myMachine.getMachineID(), + freePEID); + } + + // FIXME No sense set to a rgl, only fot a task + // rgl.setMachineAndPEID(myMachine.getMachineID(), freePE); + + } + + // ALLOCATE IMMEDIATELY + rpgl.setGridletStatus(Gridlet.INEXEC); // change Gridlet status + // add this Gridlet into execution list + sGridletInExecList.add(rpgl); + + // Identify Completion Time and Set Interrupt + // int rating = machineRating_[ rgl.getMachineID() ]; + double time = rpgl.getForecastFinishTime(); + // forecastFinishTime( rating , rgl.getRemainingGridletLength() ); + + double roundUpTime = Math.ceil(time+1); // rounding up + rpgl.setFinishTime(roundUpTime); + + // then send this into itself + super.sendInternalEvent(roundUpTime); + return true; + } + + /** + * Allocates the first Gridlet in the Queue list (if any) to execution list + * + * @pre $none + * @post $none + */ + protected void allocateQueueGridlet() { + // if there are many Gridlets in the QUEUE, then allocate a + // PE to the first Gridlet in the list since it follows FCFS + // (First Come First Serve) approach. Then removes the Gridlet from + // the Queue list + + // FIXME improve performance + + if (sGridletQueueList.size() > 0 + && sGridletInExecList.size() < super.totalPE_) { + ResParallelGridlet rgl; + + int free = super.resource_.getNumFreePE(); + + rgl = sGridletQueueList.peek(); + + while (rgl.getNumPE() <= free) { + // allocate the Gridlet into an empty PE slot and remove it + // from + // the queue list + boolean success = allocatePEstoGridlet(rgl); + if (success == true) { + sGridletQueueList.poll(); + // sGridletQueueList.remove(rgl); + } + // FIXME Update with another threads, is it better + free -= rgl.getNumPE(); + rgl = sGridletQueueList.peek(); + if (rgl == null) + return; + } + //This check is duplicated, but this is not 100% sure and is not computational expensive + if(free>0) backfillingLN(); + } + } + + protected void backfillingLN() { + + + // FIXME improve performance + int free = super.resource_.getNumFreePE(); + if (!(free > 0 & sGridletQueueList.size() > 0)) + return; + + int futureFree = free; + TreeMap<Double, Integer> timePE = new TreeMap<Double, Integer>(); + timePE.put(0d, free); + sorteExecList.clear(); + sorteExecList.addAll(sGridletInExecList); + Iterator<ResParallelGridlet> sIt = sorteExecList.iterator(); + ResParallelGridlet rgl; + double time; + while (sIt.hasNext()) { + rgl = sIt.next(); + futureFree += rgl.getNumPE(); + time = (rgl.getExecStartTime() + rgl.getEstimatedTime()) + - GridSim.clock()+1; + timePE.put(time, futureFree); + } + Iterator<ResParallelGridlet> it = sGridletQueueList.iterator(); + while (it.hasNext() && free > 0) { + rgl = it.next(); + //if(rgl.getNumPE()>free & onlyExecutionFilling) continue; + double starTime = -1d, endTime = -1; + boolean validating = false; + for (Entry<Double, Integer> mark : timePE.entrySet()) { + if (validating) { + if (((!onlyExecutionFilling)|(starTime == 0d))&(mark.getKey() >= endTime)) { + // if(!onlyExecutionFilling) break; + break; + //if(!(onlyExecutionFilling&&(starTime != 0d))) break; + //else System.err.println("Special rejection"); + } else if (mark.getValue() < rgl.getNumPE()) { + validating = false; + endTime = -1; + // break; + } + } else { + if (mark.getValue() >= rgl.getNumPE()) { + validating = true; + starTime = mark.getKey(); + endTime = starTime + rgl.getEstimatedTime(); + } + } + } + if (validating) { + for (Entry<Double, Integer> mark : timePE.subMap(starTime, + endTime).entrySet()) { + futureFree=mark.getValue() ; + mark.setValue(futureFree- rgl.getNumPE()); + } + if(!timePE.containsKey(endTime)) timePE.put(endTime,futureFree); + if (starTime == 0d) { + if(rgl.getNumPE()>free){ + System.err.println("Backfillin called before check completation. Gridlet "+rgl.getGridletID()+" bad allocated"); + continue; + } + // allocate the Gridlet into an empty PE slot and + // remove it from the queue list + boolean success = allocatePEstoGridlet(rgl); + if (success == true) { + sGridletQueueList.remove(rgl); + } + // FIXME Update with another threads, is it better + free -= rgl.getNumPE(); + } + } else { + // if(!onlyExecutionFilling) + System.err.println("Never would be reached this point"); + /* else + System.err.println("Rejected candidate");*/ + } + } + + } + + @Override + public String getPolicyName() { + if(onlyExecutionFilling) + return "ConservativeBackFillingExecution"; + else + return "ConservativeBackFillingPredictive"; + } + +} Added: branches/gridsim-4.1-parallel/source/es/usc/ac/gridsim/extensions/failsimulator/allocs/BackFillingL1Alloc.java =================================================================== --- branches/gridsim-4.1-parallel/source/es/usc/ac/gridsim/extensions/failsimulator/allocs/BackFillingL1Alloc.java (rev 0) +++ branches/gridsim-4.1-parallel/source/es/usc/ac/gridsim/extensions/failsimulator/allocs/BackFillingL1Alloc.java 2008-02-07 10:47:50 UTC (rev 88) @@ -0,0 +1,223 @@ +/* + * Title: GridSim Toolkit + * Description: GridSim (Grid Simulation) Toolkit for Modeling and Simulation + * of Parallel and Distributed Systems such as Clusters and Grids + * Licence: GPL - http://www.gnu.org/copyleft/gpl.html + * + * $Id: BackFillingL1Alloc.java,v 1.1 2006/11/30 11:46:57 julio Exp $ + */ + +package es.usc.ac.gridsim.extensions.failsimulator.allocs; + +import java.util.Comparator; +import java.util.Iterator; +import java.util.SortedSet; +import java.util.TreeSet; + +import gridsim.parallel.InternalNetworkModel; +import gridsim.parallel.ResParallelGridlet; +import es.usc.ac.gridsim.extensions.failsimulator.parallel.FailurableParallelAlllocPolicy; +import gridsim.GridSim; +import gridsim.Gridlet; +import gridsim.Machine; +import gridsim.PE; +import gridsim.PEList; + +/** + * SpaceParallelShared class is an allocation policy for GridResource that + * behaves exactly like First Come First Serve (FCFS). This is a modification to + * SpaceShared that allows each Gridlet to be executed in more than one + * Processing Element (PE). Versioned to add support to parallel gridlets. + * + * @author Julio Lopez, based on SpaceShared by Manzur Murshed and Rajkumar + * Buyya + * @since GridSim Toolkit 4.0 + * @see gridsim.GridSim + * @see gridsim.ResourceCharacteristics + * @see gridsim.SpaceShare + * @invariant $none + */ +public class BackFillingL1Alloc extends FailurableParallelAlllocPolicy { + private SortedSet<ResParallelGridlet> sorteExecList; + + public BackFillingL1Alloc(String resourceName, String entityName, + InternalNetworkModel internalNet,boolean cancelOnFailure) throws Exception { + super(resourceName, entityName, internalNet, cancelOnFailure); + sorteExecList = new TreeSet<ResParallelGridlet>( + new Comparator<ResParallelGridlet>() { + public int compare(ResParallelGridlet o1, + ResParallelGridlet o2) { + if(o1.equals(o2)) return 0; + double estTime=((o1.getEstimatedTime() + o1 + .getExecStartTime()) - (o2.getEstimatedTime() + o2 + .getExecStartTime())); + return (estTime>0)?1:-1; + } + }); + + } + + /** + * Allocates a Gridlet into a free PE and sets the Gridlet status into + * INEXEC and PE status into busy afterwards + * + * @param rgl + * a ResGridlet object + * @return <tt>true</tt> if there is an empty PE to process this Gridlet, + * <tt>false</tt> otherwise + * @pre rgl != null + * @post $none + */ + protected boolean allocatePEstoGridlet(ResParallelGridlet rpgl) { + // FIXME First basic implementation + // ResParallelGridlet rpgl = (ResParallelGridlet) rgl; + int tasks = rpgl.getNumPE(); + + int i = 0; + while (i < tasks) { + + // IDENTIFY MACHINE which has a free PE and add this Gridlet to it. + Machine myMachine = resource_.getMachineWithFreePE(); + + // If a Machine is empty then ignore the rest + if (myMachine == null) { + System.out.println("Fallou"); + return false; + // FIXME Esta salida no es valida + } + + // gets the list of PEs and find one empty PE + PEList MyPEList = myMachine.getPEList(); + while (MyPEList.getNumFreePE() > 0 && (i < tasks)) { + int freePEID = MyPEList.getFreePEID(); + rpgl.setMachineAndPEID(myMachine.getMachineID(), freePEID, + MyPEList.getMIPSRating(freePEID)); + i++; + // Set allocated PE to BUSY status + super.resource_.setStatusPE(PE.BUSY, myMachine.getMachineID(), + freePEID); + } + + // FIXME No sense set to a rgl, only fot a task + // rgl.setMachineAndPEID(myMachine.getMachineID(), freePE); + + } + + // ALLOCATE IMMEDIATELY + rpgl.setGridletStatus(Gridlet.INEXEC); // change Gridlet status + // add this Gridlet into execution list + sGridletInExecList.add(rpgl); + + // Identify Completion Time and Set Interrupt + // int rating = machineRating_[ rgl.getMachineID() ]; + double time = rpgl.getForecastFinishTime(); + // forecastFinishTime( rating , rgl.getRemainingGridletLength() ); + + double roundUpTime = Math.ceil(time); // rounding up + rpgl.setFinishTime(roundUpTime); + + // then send this into itself + super.sendInternalEvent(roundUpTime); + return true; + } + + /** + * Allocates the first Gridlet in the Queue list (if any) to execution list + * + * @pre $none + * @post $none + */ + protected void allocateQueueGridlet() { + // if there are many Gridlets in the QUEUE, then allocate a + // PE to the first Gridlet in the list since it follows FCFS + // (First Come First Serve) approach. Then removes the Gridlet from + // the Queue list + + // FIXME improve performance + + if (sGridletQueueList.size() > 0 + && sGridletInExecList.size() < super.totalPE_) { + ResParallelGridlet rgl; + + int free = super.resource_.getNumFreePE(); + + rgl = sGridletQueueList.peek(); + + while (rgl.getNumPE() <= free) { + // allocate the Gridlet into an empty PE slot and remove it + // from + // the queue list + boolean success = allocatePEstoGridlet(rgl); + if (success == true) { + sGridletQueueList.poll(); + // sGridletQueueList.remove(rgl); + } + // FIXME Update with another threads, is it better + free -= rgl.getNumPE(); + rgl = sGridletQueueList.peek(); + if (rgl == null) + return; + } + if(free>0) backfillingL1(); + } + } + + protected void backfillingL1() { + int free = super.resource_.getNumFreePE(); + if (!(free > 0 & sGridletQueueList.size() > 0)) + return; + ResParallelGridlet rgl; + rgl = sGridletQueueList.peek(); + double extraTime = rgl.getEstimatedTime(); + // BACKFILLING code + sorteExecList.clear(); + sorteExecList.addAll(sGridletInExecList); + Iterator<ResParallelGridlet> sIt = sorteExecList.iterator(); + int extraPE = free - rgl.getNumPE(); + while (extraPE < 0 && sIt.hasNext()) { + rgl = sIt.next(); + extraPE += rgl.getNumPE(); + } + double maxTime = rgl.getExecStartTime() + rgl.getEstimatedTime() + - GridSim.clock(); + Iterator<ResParallelGridlet> it = sGridletQueueList.iterator(); + while (it.hasNext() && free > 0) { + rgl = it.next(); + if (rgl.getNumPE() <= free) + if (rgl.getEstimatedTime() < maxTime) { + // allocate the Gridlet into an empty PE slot and + // remove it from the queue list + boolean success = allocatePEstoGridlet(rgl); + if (success == true) { + sGridletQueueList.remove(rgl); + } + // FIXME Update with another threads, is it better + free -= rgl.getNumPE(); + } else if (rgl.getEstimatedTime() < maxTime + extraTime + && rgl.getNumPE() <= extraPE) { + // allocate the Gridlet into an empty PE slot and + // remove it from the queue list + boolean success = allocatePEstoGridlet(rgl); + if (success == true) { + sGridletQueueList.remove(rgl); + } + // FIXME Update with another threads, is it better + free -= rgl.getNumPE(); + extraPE -= rgl.getNumPE(); + //System.err.println("Extra bacfilled with gridlet "+ rgl.getGridletID()); + } /*else { + // System.err.println("Not bacfilled with gridlet + // "+rgl.getGridletID()); + }*/ + // FIXME this solution is correct, but the performance can + // decrease. + } + + } + + @Override + public String getPolicyName() { + return "ConservativeBackFillingL1"; + } + +} Added: branches/gridsim-4.1-parallel/source/es/usc/ac/gridsim/extensions/failsimulator/allocs/EASYBackFillingAlloc.java =================================================================== --- branches/gridsim-4.1-parallel/source/es/usc/ac/gridsim/extensions/failsimulator/allocs/EASYBackFillingAlloc.java (rev 0) +++ branches/gridsim-4.1-parallel/source/es/usc/ac/gridsim/extensions/failsimulator/allocs/EASYBackFillingAlloc.java 2008-02-07 10:47:50 UTC (rev 88) @@ -0,0 +1,226 @@ +/* + * Title: GridSim Toolkit + * Description: GridSim (Grid Simulation) Toolkit for Modeling and Simulation + * of Parallel and Distributed Systems such as Clusters and Grids + * Licence: GPL - http://www.gnu.org/copyleft/gpl.html + * + * $Id: EASYBackFillingAlloc.java,v 1.1 2006/11/30 11:46:57 julio Exp $ + */ + +package es.usc.ac.gridsim.extensions.failsimulator.allocs; + +import java.util.Comparator; +import java.util.Iterator; +import java.util.SortedSet; +import java.util.TreeSet; + +import gridsim.parallel.InternalNetworkModel; +import gridsim.parallel.ResParallelGridlet; +import es.usc.ac.gridsim.extensions.failsimulator.parallel.FailurableParallelAlllocPolicy; +import gridsim.GridSim; +import gridsim.Gridlet; +import gridsim.Machine; +import gridsim.PE; +import gridsim.PEList; + +/** + * SpaceParallelShared class is an allocation policy for GridResource that + * behaves exactly like First Come First Serve (FCFS). This is a modification to + * SpaceShared that allows each Gridlet to be executed in more than one + * Processing Element (PE). Versioned to add support to parallel gridlets. + * + * @author Julio Lopez, based on SpaceShared by Manzur Murshed and Rajkumar + * Buyya + * @since GridSim Toolkit 4.0 + * @see gridsim.GridSim + * @see gridsim.ResourceCharacteristics + * @see gridsim.SpaceShare + * @invariant $none + */ +public class EASYBackFillingAlloc extends FailurableParallelAlllocPolicy { + private SortedSet<ResParallelGridlet> sorteExecList; + + public EASYBackFillingAlloc(String resourceName, String entityName, + InternalNetworkModel internalNet,boolean cancelOnFailure) throws Exception { + super(resourceName, entityName, internalNet,cancelOnFailure); + sorteExecList = new TreeSet<ResParallelGridlet>( + new Comparator<ResParallelGridlet>() { + public int compare(ResParallelGridlet o1, + ResParallelGridlet o2) { + if(o1.equals(o2)) return 0; + double estTime=((o1.getEstimatedTime() + o1 + .getExecStartTime()) - (o2.getEstimatedTime() + o2 + .getExecStartTime())); + return (estTime>0)?1:-1; + } + }); + + } + + /** + * Allocates a Gridlet into a free PE and sets the Gridlet status into + * INEXEC and PE status into busy afterwards + * + * @param rgl + * a ResGridlet object + * @return <tt>true</tt> if there is an empty PE to process this Gridlet, + * <tt>false</tt> otherwise + * @pre rgl != null + * @post $none + */ + protected boolean allocatePEstoGridlet(ResParallelGridlet rpgl) { + // FIXME First basic implementation + // ResParallelGridlet rpgl = (ResParallelGridlet) rgl; + int tasks = rpgl.getNumPE(); + + int i = 0; + while (i < tasks) { + + // IDENTIFY MACHINE which has a free PE and add this Gridlet to it. + Machine myMachine = resource_.getMachineWithFreePE(); + + // If a Machine is empty then ignore the rest + if (myMachine == null) { + System.out.println("Fallou"); + return false; + // FIXME Esta salida no es valida + } + + // gets the list of PEs and find one empty PE + PEList MyPEList = myMachine.getPEList(); + while (MyPEList.getNumFreePE() > 0 && (i < tasks)) { + int freePEID = MyPEList.getFreePEID(); + rpgl.setMachineAndPEID(myMachine.getMachineID(), freePEID, + MyPEList.getMIPSRating(freePEID)); + i++; + // Set allocated PE to BUSY status + super.resource_.setStatusPE(PE.BUSY, myMachine.getMachineID(), + freePEID); + } + + // FIXME No sense set to a rgl, only fot a task + // rgl.setMachineAndPEID(myMachine.getMachineID(), freePE); + + } + + // ALLOCATE IMMEDIATELY + rpgl.setGridletStatus(Gridlet.INEXEC); // change Gridlet status + // add this Gridlet into execution list + sGridletInExecList.add(rpgl); + + // Identify Completion Time and Set Interrupt + // int rating = machineRating_[ rgl.getMachineID() ]; + double time = rpgl.getForecastFinishTime(); + // forecastFinishTime( rating , rgl.getRemainingGridletLength() ); + + double roundUpTime = Math.ceil(time); // rounding up + rpgl.setFinishTime(roundUpTime); + + // then send this into itself + super.sendInternalEvent(roundUpTime); + return true; + } + + /** + * Allocates the first Gridlet in the Queue list (if any) to execution list + * + * @pre $none + * @post $none + */ + protected void allocateQueueGridlet() { + // if there are many Gridlets in the QUEUE, then allocate a + // PE to the first Gridlet in the list since it follows FCFS + // (First Come First Serve) approach. Then removes the Gridlet from + // the Queue list + + // FIXME improve performance + + if (sGridletQueueList.size() > 0 + && sGridletInExecList.size() < super.totalPE_) { + ResParallelGridlet rgl; + + int free = super.resource_.getNumFreePE(); + + rgl = sGridletQueueList.peek(); + + while (rgl.getNumPE() <= free) { + // allocate the Gridlet into an empty PE slot and remove it + // from + // the queue list + boolean success = allocatePEstoGridlet(rgl); + if (success == true) { + sGridletQueueList.poll(); + // sGridletQueueList.remove(rgl); + } + // FIXME Update with another threads, is it better + free -= rgl.getNumPE(); + rgl = sGridletQueueList.peek(); + if (rgl == null) + return; + } + if (free > 0) + easyBackfilling(); + // double extraTime = rgl.getEstimatedTime(); + // BACKFILLING code + // FIXME this solution is correct, but the performance can + // decrease. + + } + } + + private void easyBackfilling() { + int free = super.resource_.getNumFreePE(); + if (!(free > 0 & sGridletQueueList.size() > 0)) + return; + ResParallelGridlet rgl; + rgl = sGridletQueueList.peek(); + // TODO Auto-generated method stub + sorteExecList.clear(); + sorteExecList.addAll(sGridletInExecList); + Iterator<ResParallelGridlet> sIt = sorteExecList.iterator(); + int extraPE = free - rgl.getNumPE(); + while (extraPE < 0 && sIt.hasNext()) { + rgl = sIt.next(); + extraPE += rgl.getNumPE(); + } + double maxTime = rgl.getExecStartTime() + rgl.getEstimatedTime() + - GridSim.clock(); + Iterator<ResParallelGridlet> it = sGridletQueueList.iterator(); + while (it.hasNext() && free > 0) { + rgl = it.next(); + if (rgl.getNumPE() <= free) + if (rgl.getEstimatedTime() < maxTime) { + // allocate the Gridlet into an empty PE slot and + // remove it from the queue list + boolean success = allocatePEstoGridlet(rgl); + if (success == true) { + sGridletQueueList.remove(rgl); + } + // FIXME Update with another thre... [truncated message content] |
From: <mar...@us...> - 2008-02-05 02:43:50
|
Revision: 87 http://gridsim.svn.sourceforge.net/gridsim/?rev=87&view=rev Author: marcos_dias Date: 2008-02-04 18:43:51 -0800 (Mon, 04 Feb 2008) Log Message: ----------- Small changes in the provision of reservation options. Now the options are part of the reservation object. Modified Paths: -------------- branches/gridsim4.0-branch3/source/gridsim/turbo/ARMessage.java branches/gridsim4.0-branch3/source/gridsim/turbo/ARParallelSpaceShared.java branches/gridsim4.0-branch3/source/gridsim/turbo/Reservation.java branches/gridsim4.0-branch3/source/gridsim/turbo/ReservationRequester.java Modified: branches/gridsim4.0-branch3/source/gridsim/turbo/ARMessage.java =================================================================== --- branches/gridsim4.0-branch3/source/gridsim/turbo/ARMessage.java 2008-02-05 00:28:29 UTC (rev 86) +++ branches/gridsim4.0-branch3/source/gridsim/turbo/ARMessage.java 2008-02-05 02:43:51 UTC (rev 87) @@ -29,12 +29,6 @@ private int errorCode_; // an error code associated with the operation required private Reservation reservation_; // the negotiation this message is about - // If a Grid resource cannot make a reservation, it may provide options - // by informing the reservation requester when resource will be available to - // fulfil the reservation. This attribute contains the list of PEs - // available at a set of simulation times - private AvailabilityInfo resOptions_; - // the price associate with this message private double price_; @@ -76,6 +70,10 @@ /** Indicates that the operation requested could not be fulfilled */ public static final int EC_OPERATION_FAILURE = 1; + /** Indicates that the operation requested could not be fulfilled, + * but advance reservation options are provided */ + public static final int EC_OPERATION_FAILURE_BUT_OPTIONS = 2; + private static int lastUniqueID; static{ @@ -114,7 +112,6 @@ msgType_ = TYPE_UNKNOWN; errorCode_ = EC_NO_ERROR; reservation_ = null; - resOptions_ = null; } /** @@ -163,7 +160,6 @@ msgId_ = ARMessage.createUniqueID(); reservation_ = reservation; errorCode_ = EC_NO_ERROR; - resOptions_ = null; } /** @@ -384,22 +380,6 @@ } /** - * Gets the reservation options given by the Grid resource - * @return the reservation options - */ - public AvailabilityInfo getReservationOptions() { - return resOptions_; - } - - /** - * Sets the reservation options given by the Grid resource - * @param resOptions the reservation options object - */ - public void setReservationOptions(AvailabilityInfo resOptions) { - resOptions_ = resOptions; - } - - /** * Returns the size in bytes for this message. * <tt>NOTE:</tt> This is used to get network statistics * @return the size in bytes of this message Modified: branches/gridsim4.0-branch3/source/gridsim/turbo/ARParallelSpaceShared.java =================================================================== --- branches/gridsim4.0-branch3/source/gridsim/turbo/ARParallelSpaceShared.java 2008-02-05 00:28:29 UTC (rev 86) +++ branches/gridsim4.0-branch3/source/gridsim/turbo/ARParallelSpaceShared.java 2008-02-05 02:43:51 UTC (rev 87) @@ -649,7 +649,7 @@ AvailabilityInfo availability = getAvailabilityInfo(startTime, duration); // sets the options as the availability over the requested period - response.setReservationOptions(availability); + response.getReservation().setReservationOptions(availability); // Sends the response back to the user super.sendARMessage(response); Modified: branches/gridsim4.0-branch3/source/gridsim/turbo/Reservation.java =================================================================== --- branches/gridsim4.0-branch3/source/gridsim/turbo/Reservation.java 2008-02-05 00:28:29 UTC (rev 86) +++ branches/gridsim4.0-branch3/source/gridsim/turbo/Reservation.java 2008-02-05 02:43:51 UTC (rev 87) @@ -35,6 +35,12 @@ private int reservID_; // reservation ID private double submissionTime_; // the time of submission of this advance reservation + // If a Grid resource cannot make a reservation, it may provide options + // by informing the reservation requester when resource will be available to + // fulfil the reservation. This attribute contains the list of PEs + // available at a set of simulation times + private AvailabilityInfo resOptions_; + private static final int NOT_FOUND = -1; // constant private static int lastReservationId_ = 0; @@ -301,7 +307,23 @@ public int getID() { return reservID_; } + + /** + * Gets the reservation options given by the Grid resource + * @return the reservation options + */ + public AvailabilityInfo getReservationOptions() { + return resOptions_; + } + /** + * Sets the reservation options given by the Grid resource + * @param resOptions the reservation options object + */ + public void setReservationOptions(AvailabilityInfo resOptions) { + resOptions_ = resOptions; + } + /** * Returns a clone of this object * @return a cloned reservation object Modified: branches/gridsim4.0-branch3/source/gridsim/turbo/ReservationRequester.java =================================================================== --- branches/gridsim4.0-branch3/source/gridsim/turbo/ReservationRequester.java 2008-02-05 00:28:29 UTC (rev 86) +++ branches/gridsim4.0-branch3/source/gridsim/turbo/ReservationRequester.java 2008-02-05 02:43:51 UTC (rev 87) @@ -144,6 +144,9 @@ if(error == ARMessage.EC_NO_ERROR) { reservations_.put(reservation.getID(), reservation); } + else if(error == ARMessage.EC_OPERATION_FAILURE_BUT_OPTIONS) { + reservation = reply.getReservation(); + } else { System.out.println(super.get_name() + ": Reservation # " + reservation.getID() + " has not been accepted by "+ @@ -356,7 +359,7 @@ // Otherwise, print the error message int error = reply.getErrorCode(); if(error == ARMessage.EC_NO_ERROR) { - resOptions = reply.getReservationOptions(); + resOptions = reply.getReservation().getReservationOptions(); } else { System.out.println(super.get_name() + ": Resource # " + resID + This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mar...@us...> - 2008-02-05 00:28:26
|
Revision: 86 http://gridsim.svn.sourceforge.net/gridsim/?rev=86&view=rev Author: marcos_dias Date: 2008-02-04 16:28:29 -0800 (Mon, 04 Feb 2008) Log Message: ----------- Small changes in the Lublin99 workload model and the availability info send by resource providers. Modified Paths: -------------- branches/gridsim4.0-branch3/examples/examples/workload/parallel/LublinWorkloadExample01.java branches/gridsim4.0-branch3/source/gridsim/turbo/ARParallelSpaceShared.java branches/gridsim4.0-branch3/source/gridsim/turbo/AvailabilityInfo.java branches/gridsim4.0-branch3/source/gridsim/turbo/Lublin99Workload.java Modified: branches/gridsim4.0-branch3/examples/examples/workload/parallel/LublinWorkloadExample01.java =================================================================== --- branches/gridsim4.0-branch3/examples/examples/workload/parallel/LublinWorkloadExample01.java 2008-02-04 04:32:43 UTC (rev 85) +++ branches/gridsim4.0-branch3/examples/examples/workload/parallel/LublinWorkloadExample01.java 2008-02-05 00:28:29 UTC (rev 86) @@ -83,9 +83,9 @@ double uHi = Math.log(totalPE * totalMachine) / Math.log(2d); double uMed = uHi-2.5; - workload.setParallelJobProbabilities(Lublin99Workload.BATCH, - Lublin99Workload.ULOW_BATCH, uMed, uHi, - Lublin99Workload.UPROB_BATCH); + workload.setParallelJobProbabilities(Lublin99Workload.BATCH_JOBS, + workload.getParallelJobULow(Lublin99Workload.BATCH_JOBS), uMed, uHi, + workload.getParallelJobUProb(Lublin99Workload.BATCH_JOBS)); // sets the workload to create 1000 jobs workload.setNumJobs(1000); @@ -120,8 +120,7 @@ * @param totalPE total number of PEs for each Machine */ private static GridResource createGridResource(String name, int peRating, - int totalMachine, int totalPE) - { + int totalMachine, int totalPE) { ////////////////////////////////////////// // Here are the steps needed to create a Grid resource: Modified: branches/gridsim4.0-branch3/source/gridsim/turbo/ARParallelSpaceShared.java =================================================================== --- branches/gridsim4.0-branch3/source/gridsim/turbo/ARParallelSpaceShared.java 2008-02-04 04:32:43 UTC (rev 85) +++ branches/gridsim4.0-branch3/source/gridsim/turbo/ARParallelSpaceShared.java 2008-02-05 00:28:29 UTC (rev 86) @@ -9,7 +9,6 @@ import eduni.simjava.Sim_event; import eduni.simjava.Sim_system; -import gridsim.GridResource; import gridsim.GridSim; import gridsim.GridSimTags; import gridsim.Gridlet; Modified: branches/gridsim4.0-branch3/source/gridsim/turbo/AvailabilityInfo.java =================================================================== --- branches/gridsim4.0-branch3/source/gridsim/turbo/AvailabilityInfo.java 2008-02-04 04:32:43 UTC (rev 85) +++ branches/gridsim4.0-branch3/source/gridsim/turbo/AvailabilityInfo.java 2008-02-05 00:28:29 UTC (rev 86) @@ -212,6 +212,28 @@ } /** + * Returns the entry whose time is closest to the <tt>time</tt> given but + * smaller, or whose time is equals to <tt>time</tt> + * @param time the time to be used to search for the entry + * @return the entry whose time is closest to the <tt>time</tt> given but + * smaller, or whose time is equals to <tt>time</tt> + */ + private AvailabilityInfoEntry getPrecedingEntry(double time) { + Iterator<AvailabilityInfoEntry> it = list_.iterator(); + AvailabilityInfoEntry preceding = null; + + while(it.hasNext()) { + AvailabilityInfoEntry entry = it.next(); + if(entry.getTime() > time) + break; + + preceding = entry; + } + + return preceding; + } + + /** * Scans the entries in a list and returns the first time frame over * which a request with the characteristics provided can be scheduled * @param duration the duration of the request @@ -219,7 +241,28 @@ * @return the start time or <tt>-1</tt> if not found */ public double getPotentialStartTime(int duration, int reqPE) { + return getPotentialStartTime(0, duration, reqPE); + } + + /** + * Scans the entries in the availability info object returns the start + * time of the first time frame over which a request with the characteristics + * provided can be scheduled. + * @param readyTime the method will consider potential start times + * further in time than the value given by <tt>readyTime</tt>. + * @param duration the duration of the request + * @param reqPE the number of PEs required + * @return the start time or <tt>-1</tt> if not found. + */ + public double getPotentialStartTime(double readyTime, + int duration, int reqPE) { + if(readyTime < startTime_) + readyTime = startTime_; + + if(readyTime > finishTime_) + return UNKNOWN; + // the anchor index, the entry in the profile where // the request would be placed OR the closest entry to the // point where the anchor of the request would be placed @@ -228,27 +271,28 @@ // a pointer to the anchor entry (described above) AvailabilityInfoEntry anchorEntry = null; - // the list of selected ranges - PERangeList intersectList = null; - double potStartTime = -1; // keep the potential start time of the request double potFinishTime = -1; // store the gridlet's expected finish time - - intersectList = null; int length = list_.size(); - - Iterator<AvailabilityInfoEntry> iterProfile = list_.iterator(); - while(iterProfile.hasNext()) { + + anchorEntry = getPrecedingEntry(readyTime); + int firstAnchorIndex = list_.indexOf(anchorEntry); + if(firstAnchorIndex == -1) + firstAnchorIndex = 0; + + for(int j=firstAnchorIndex; j<length; j++) { + AvailabilityInfoEntry entry = list_.get(j); + anchorIndex = list_.indexOf(entry); - AvailabilityInfoEntry entry = iterProfile.next(); - anchorEntry = entry; - anchorIndex = list_.indexOf(anchorEntry); - // sets the start time as the time of the entry - potStartTime = entry.getTime(); - // calculates when the finish time will be if + if(entry.getTime() < readyTime) + potStartTime = readyTime; + else + potStartTime = entry.getTime(); + + // calculates when the finish time will be if // the gridlet is put at this position - potFinishTime = potStartTime + duration; + potFinishTime = potStartTime + duration; // scan the profile until an entry with enough PEs is found if(entry.getNumPE() < reqPE) { @@ -259,7 +303,7 @@ // from that point onwards analysing the intersection of // the ranges available in the entries until the // request expected completion time - intersectList = entry.getAvailRanges().clone(); + PERangeList intersectList = entry.getAvailRanges().clone(); // Look for the intersection of available ranges from // the anchor until the end of the profile or until @@ -274,7 +318,8 @@ // is no need to check the intersection if(nextEntry.getTime() < potFinishTime) { intersectList = PERangeList.intersection(intersectList, - nextEntry.getAvailRanges()); + nextEntry.getAvailRanges()); + if(intersectList == null || intersectList.getNumPE() < reqPE) { break; } Modified: branches/gridsim4.0-branch3/source/gridsim/turbo/Lublin99Workload.java =================================================================== --- branches/gridsim4.0-branch3/source/gridsim/turbo/Lublin99Workload.java 2008-02-04 04:32:43 UTC (rev 85) +++ branches/gridsim4.0-branch3/source/gridsim/turbo/Lublin99Workload.java 2008-02-05 00:28:29 UTC (rev 86) @@ -70,13 +70,11 @@ // Log PI for lgamma method private static final double LOGPI = 1.14472988584940017414; - protected final int INTERVAL = 10; // number of intervals + private final int INTERVAL = 10; // number of intervals + private static final int UNKNOWN = -1; // ------------ CONSTANTS USED BY THE WORKLOAD MODEL -------------- - // number of jobs generated by this entity - private static final int SIZE = 1000; - // no more than two days =exp(12) for runtime private static final int TOO_MUCH_TIME = 12; @@ -103,10 +101,10 @@ private static final double EPS = 1E-10; /** Represents interactive jobs */ - public static final int INTERACTIVE = 0; + public static final int INTERACTIVE_JOBS = 0; /** Represents batch jobs */ - public static final int BATCH = 1; + public static final int BATCH_JOBS = 1; // ------------------- MODEL DEFAULT PARAMETERS ----------------------- @@ -121,19 +119,19 @@ * UMed should be in [UHi-1.5 , UHi-3.5] * Uprob should be in [0.7 - 0.95] */ - public static final double SERIAL_PROB_BATCH = 0.2927; - public static final double POW2_PROB_BATCH = 0.6686; - public static final double ULOW_BATCH = 1.2f; // smallest parallel batch job has 2 nodes - public static final double UMED_BATCH = 5; - public static final double UHI_BATCH = 7; // biggest batch job has 128 nodes - public static final double UPROB_BATCH = 0.875; + private static final double SERIAL_PROB_BATCH = 0.2927; + private static final double POW2_PROB_BATCH = 0.6686; + private static final double ULOW_BATCH = 1.2f; // smallest parallel batch job has 2 nodes + private static final double UMED_BATCH = 5; + private static final double UHI_BATCH = 7; // biggest batch job has 128 nodes + private static final double UPROB_BATCH = 0.875; - public static final double SERIAL_PROB_ACTIVE = 0.1541; - public static final double POW2_PROB_ACTIVE = 0.625; - public static final double ULOW_ACTIVE = 1; // smallest interactive parallel job has 2 nodes - public static final double UMED_ACTIVE = 3; - public static final double UHI_ACTIVE = 5.5f; // biggest interactive job has 45 nodes - public static final double UPROB_ACTIVE = 0.705; + private static final double SERIAL_PROB_ACTIVE = 0.1541; + private static final double POW2_PROB_ACTIVE = 0.625; + private static final double ULOW_ACTIVE = 1; // smallest interactive parallel job has 2 nodes + private static final double UMED_ACTIVE = 3; + private static final double UHI_ACTIVE = 5.5f; // biggest interactive job has 45 nodes + private static final double UPROB_ACTIVE = 0.705; /* The parameters for the running time * The running time is computed using hyper-gamma distribution. @@ -143,19 +141,19 @@ * 'nodes' will be calculated in the program, here we defined the 'pa','pb' * parameters. */ - public static final double A1_BATCH = 6.57; - public static final double B1_BATCH = 0.823; - public static final double A2_BATCH = 639.1; - public static final double B2_BATCH = 0.0156; - public static final double PA_BATCH = -0.003; - public static final double PB_BATCH = 0.6986; + private static final double A1_BATCH = 6.57; + private static final double B1_BATCH = 0.823; + private static final double A2_BATCH = 639.1; + private static final double B2_BATCH = 0.0156; + private static final double PA_BATCH = -0.003; + private static final double PB_BATCH = 0.6986; - public static final double A1_ACTIVE = 3.8351; - public static final double B1_ACTIVE = 0.6605; - public static final double A2_ACTIVE = 7.073; - public static final double B2_ACTIVE = 0.6856; - public static final double PA_ACTIVE = -0.0118; - public static final double PB_ACTIVE = 0.9156; + private static final double A1_ACTIVE = 3.8351; + private static final double B1_ACTIVE = 0.6605; + private static final double A2_ACTIVE = 7.073; + private static final double B2_ACTIVE = 0.6856; + private static final double PA_ACTIVE = -0.0118; + private static final double PB_ACTIVE = 0.9156; /* The parameters for the inter-arrival time @@ -169,41 +167,41 @@ * a constant ,ARAR (Arrive-Rush-All-Ratio), to set the alpha parameter (the new * aarr) so it will represent the arrive-time at all hours of the day. */ - public static final double AARR_BATCH = 6.0415; - public static final double BARR_BATCH = 0.8531; - public static final double ANUM_BATCH = 6.1271; - public static final double BNUM_BATCH = 5.2740; - public static final double ARAR_BATCH = 1.0519; + private static final double AARR_BATCH = 6.0415; + private static final double BARR_BATCH = 0.8531; + private static final double ANUM_BATCH = 6.1271; + private static final double BNUM_BATCH = 5.2740; + private static final double ARAR_BATCH = 1.0519; - public static final double AARR_ACTIVE = 6.5510; - public static final double BARR_ACTIVE = 0.6621; - public static final double ANUM_ACTIVE = 8.9186; - public static final double BNUM_ACTIVE = 3.6680; - public static final double ARAR_ACTIVE = 0.9797; + private static final double AARR_ACTIVE = 6.5510; + private static final double BARR_ACTIVE = 0.6621; + private static final double ANUM_ACTIVE = 8.9186; + private static final double BNUM_ACTIVE = 3.6680; + private static final double ARAR_ACTIVE = 0.9797; /* * Here are the model's parameters for typeless data (no batch nor interactive) * We use those parameters when INCLUDE_JOBS_TYPE is off (0) */ - public static final double SERIAL_PROB = 0.244; - public static final double POW2_PROB = 0.576; - public static final double ULOW = 0.8f; // The smallest parallel job is 2 nodes - public static final double UMED = 4.5f; - public static final double UHI = 7f; // SYSTEM SIZE is 2^UHI == 128 - public static final double UPROB = 0.86; + private static final double SERIAL_PROB = 0.244; + private static final double POW2_PROB = 0.576; + private static final double ULOW = 0.8f; // The smallest parallel job is 2 nodes + private static final double UMED = 4.5f; + private static final double UHI = 7f; // SYSTEM SIZE is 2^UHI == 128 + private static final double UPROB = 0.86; - public static final double A1 = 4.2; - public static final double B1 = 0.94; - public static final double A2 = 312; - public static final double B2 = 0.03; - public static final double PA = -0.0054; - public static final double PB = 0.78; + private static final double A1 = 4.2; + private static final double B1 = 0.94; + private static final double A2 = 312; + private static final double B2 = 0.03; + private static final double PA = -0.0054; + private static final double PB = 0.78; - public static final double AARR = 10.2303; - public static final double BARR = 0.4871; - public static final double ANUM = 8.1737; - public static final double BNUM = 3.9631; - public static final double ARAR = 1.0225; + private static final double AARR = 10.2303; + private static final double BARR = 0.4871; + private static final double ANUM = 8.1737; + private static final double BNUM = 3.9631; + private static final double ARAR = 1.0225; // start the simulation at midnight (hour 0) private static final int START = 0; @@ -217,6 +215,9 @@ private double workloadDuration_; private int numJobs_; + // hour of the day when the simulation starts + private int start_; + private double[] a1, b1, a2, b2, pa, pb; private double[] aarr, barr, anum, bnum; private double[] serialProb, pow2Prob, uLow, uMed, uHi, uProb; @@ -443,6 +444,7 @@ random_ = new Random(seed); workloadDuration_ = Double.MAX_VALUE; numJobs_ = 1000; + start_ = START; a1 = new double[2]; b1 = new double[2]; a2 = new double[2]; b2 = new double[2]; @@ -457,60 +459,60 @@ // separate batch from interactive if (useJobType_) { - serialProb[BATCH] = SERIAL_PROB_BATCH; - pow2Prob[BATCH] = POW2_PROB_BATCH; - uLow[BATCH] = ULOW_BATCH; - uMed[BATCH] = UMED_BATCH; - uHi[BATCH] = UHI_BATCH; - uProb[BATCH] = UPROB_BATCH; + serialProb[BATCH_JOBS] = SERIAL_PROB_BATCH; + pow2Prob[BATCH_JOBS] = POW2_PROB_BATCH; + uLow[BATCH_JOBS] = ULOW_BATCH; + uMed[BATCH_JOBS] = UMED_BATCH; + uHi[BATCH_JOBS] = UHI_BATCH; + uProb[BATCH_JOBS] = UPROB_BATCH; - serialProb[INTERACTIVE] = SERIAL_PROB_ACTIVE; - pow2Prob[INTERACTIVE] = POW2_PROB_ACTIVE; - uLow[INTERACTIVE] = ULOW_ACTIVE; - uMed[INTERACTIVE] = UMED_ACTIVE; - uHi[INTERACTIVE] = UHI_ACTIVE; - uProb[INTERACTIVE] = UPROB_ACTIVE; + serialProb[INTERACTIVE_JOBS] = SERIAL_PROB_ACTIVE; + pow2Prob[INTERACTIVE_JOBS] = POW2_PROB_ACTIVE; + uLow[INTERACTIVE_JOBS] = ULOW_ACTIVE; + uMed[INTERACTIVE_JOBS] = UMED_ACTIVE; + uHi[INTERACTIVE_JOBS] = UHI_ACTIVE; + uProb[INTERACTIVE_JOBS] = UPROB_ACTIVE; - a1[BATCH] = A1_BATCH; b1[BATCH] = B1_BATCH; - a2[BATCH] = A2_BATCH; b2[BATCH] = B2_BATCH; - pa[BATCH] = PA_BATCH; pb[BATCH] = PB_BATCH; + a1[BATCH_JOBS] = A1_BATCH; b1[BATCH_JOBS] = B1_BATCH; + a2[BATCH_JOBS] = A2_BATCH; b2[BATCH_JOBS] = B2_BATCH; + pa[BATCH_JOBS] = PA_BATCH; pb[BATCH_JOBS] = PB_BATCH; - a1[INTERACTIVE] = A1_ACTIVE; b1[INTERACTIVE] = B1_ACTIVE; - a2[INTERACTIVE] = A2_ACTIVE; b2[INTERACTIVE] = B2_ACTIVE; - pa[INTERACTIVE] = PA_ACTIVE; pb[INTERACTIVE] = PB_ACTIVE; + a1[INTERACTIVE_JOBS] = A1_ACTIVE; b1[INTERACTIVE_JOBS] = B1_ACTIVE; + a2[INTERACTIVE_JOBS] = A2_ACTIVE; b2[INTERACTIVE_JOBS] = B2_ACTIVE; + pa[INTERACTIVE_JOBS] = PA_ACTIVE; pb[INTERACTIVE_JOBS] = PB_ACTIVE; - aarr[BATCH] = AARR_BATCH*ARAR_BATCH; barr[BATCH] = BARR_BATCH; - anum[BATCH] = ANUM_BATCH; bnum[BATCH] = BNUM_BATCH; + aarr[BATCH_JOBS] = AARR_BATCH*ARAR_BATCH; barr[BATCH_JOBS] = BARR_BATCH; + anum[BATCH_JOBS] = ANUM_BATCH; bnum[BATCH_JOBS] = BNUM_BATCH; - aarr[INTERACTIVE] = AARR_ACTIVE*ARAR_ACTIVE; - barr[INTERACTIVE] = BARR_ACTIVE; - anum[INTERACTIVE] = ANUM_ACTIVE; - bnum[INTERACTIVE] = BNUM_ACTIVE; + aarr[INTERACTIVE_JOBS] = AARR_ACTIVE*ARAR_ACTIVE; + barr[INTERACTIVE_JOBS] = BARR_ACTIVE; + anum[INTERACTIVE_JOBS] = ANUM_ACTIVE; + bnum[INTERACTIVE_JOBS] = BNUM_ACTIVE; } else { // whole sample -- make all batch jobs - serialProb[BATCH] = serialProb[INTERACTIVE] = SERIAL_PROB; - pow2Prob[BATCH] = pow2Prob[INTERACTIVE] = POW2_PROB; - uLow[BATCH] = uLow[INTERACTIVE] = ULOW ; - uMed[BATCH] = uMed[INTERACTIVE] = UMED ; - uHi[BATCH] = uHi[INTERACTIVE] = UHI ; - uProb[BATCH] = uProb[INTERACTIVE] = UPROB ; + serialProb[BATCH_JOBS] = serialProb[INTERACTIVE_JOBS] = SERIAL_PROB; + pow2Prob[BATCH_JOBS] = pow2Prob[INTERACTIVE_JOBS] = POW2_PROB; + uLow[BATCH_JOBS] = uLow[INTERACTIVE_JOBS] = ULOW ; + uMed[BATCH_JOBS] = uMed[INTERACTIVE_JOBS] = UMED ; + uHi[BATCH_JOBS] = uHi[INTERACTIVE_JOBS] = UHI ; + uProb[BATCH_JOBS] = uProb[INTERACTIVE_JOBS] = UPROB ; - a1[BATCH] = a1[INTERACTIVE] = A1; - b1[BATCH] = b1[INTERACTIVE] = B1; - a2[BATCH] = a2[INTERACTIVE] = A2; - b2[BATCH] = b2[INTERACTIVE] = B2; - pa[BATCH] = pa[INTERACTIVE] = PA; - pb[BATCH] = pb[INTERACTIVE] = PB; + a1[BATCH_JOBS] = a1[INTERACTIVE_JOBS] = A1; + b1[BATCH_JOBS] = b1[INTERACTIVE_JOBS] = B1; + a2[BATCH_JOBS] = a2[INTERACTIVE_JOBS] = A2; + b2[BATCH_JOBS] = b2[INTERACTIVE_JOBS] = B2; + pa[BATCH_JOBS] = pa[INTERACTIVE_JOBS] = PA; + pb[BATCH_JOBS] = pb[INTERACTIVE_JOBS] = PB; - aarr[BATCH] = aarr[INTERACTIVE] = AARR * ARAR; - barr[BATCH] = barr[INTERACTIVE] = BARR; - anum[BATCH] = anum[INTERACTIVE] = ANUM; - bnum[BATCH] = bnum[INTERACTIVE] = BNUM; + aarr[BATCH_JOBS] = aarr[INTERACTIVE_JOBS] = AARR * ARAR; + barr[BATCH_JOBS] = barr[INTERACTIVE_JOBS] = BARR; + anum[BATCH_JOBS] = anum[INTERACTIVE_JOBS] = ANUM; + bnum[BATCH_JOBS] = bnum[INTERACTIVE_JOBS] = BNUM; } if ( ! useJobType_ ) // make all jobs batch - timeFromBegin_[INTERACTIVE] = Long.MAX_VALUE; + timeFromBegin_[INTERACTIVE_JOBS] = Long.MAX_VALUE; } /** @@ -519,20 +521,34 @@ * @param prob the probability * @return <tt>true</tt> if the probability has been set, or * <tt>false</tt> otherwise. - * @see #INTERACTIVE - * @see #BATCH + * @see #INTERACTIVE_JOBS + * @see #BATCH_JOBS */ public boolean setSerialProbability(int jobType, double prob) { - if(jobType > BATCH || jobType < INTERACTIVE) + if(jobType > BATCH_JOBS || jobType < INTERACTIVE_JOBS) return false; if(useJobType_) serialProb[jobType] = prob; else - serialProb[INTERACTIVE] = serialProb[BATCH] = prob; + serialProb[INTERACTIVE_JOBS] = serialProb[BATCH_JOBS] = prob; return true; } + + /** + * Gets the probability for serial jobs + * @param jobType the type of jobs + * @returns prob the probability; <tt>-1</tt> if an error occurs. + * @see #INTERACTIVE_JOBS + * @see #BATCH_JOBS + */ + public double getSerialProbability(int jobType) { + if(jobType > BATCH_JOBS || jobType < INTERACTIVE_JOBS) + return UNKNOWN; + + return serialProb[jobType]; + } /** * Sets the probability for power of two jobs @@ -540,20 +556,34 @@ * @param prob the probability * @return <tt>true</tt> if the probability has been set, or * <tt>false</tt> otherwise. - * @see #INTERACTIVE - * @see #BATCH + * @see #INTERACTIVE_JOBS + * @see #BATCH_JOBS */ public boolean setPower2Probability(int jobType, double prob) { - if(jobType > BATCH || jobType < INTERACTIVE) + if(jobType > BATCH_JOBS || jobType < INTERACTIVE_JOBS) return false; if(useJobType_) pow2Prob[jobType] = prob; else - pow2Prob[INTERACTIVE] = pow2Prob[BATCH] = prob; + pow2Prob[INTERACTIVE_JOBS] = pow2Prob[BATCH_JOBS] = prob; return true; } + + /** + * Gets the probability for power of two jobs + * @param jobType the type of jobs + * @returns prob the probability; <tt>-1</tt> if an error occurs. + * @see #INTERACTIVE_JOBS + * @see #BATCH_JOBS + */ + public double getPower2Probability(int jobType) { + if(jobType > BATCH_JOBS || jobType < INTERACTIVE_JOBS) + return UNKNOWN; + + return pow2Prob[jobType]; + } /** * Sets the parameters for the two-stage-uniform @@ -565,13 +595,13 @@ * @param uHi is the log2 of the maximal size of a job in the system (system's size) * @param uProb should be in [0.7 - 0.95] * @return <tt>true</tt> if the probabilities have been set, or - * <tt>false</tt> otherwise.b2 - * @see #INTERACTIVE - * @see #BATCH + * <tt>false</tt> otherwise. + * @see #INTERACTIVE_JOBS + * @see #BATCH_JOBS */ public boolean setParallelJobProbabilities(int jobType, double uLow, double uMed, double uHi, double uProb) { - if(jobType > BATCH || jobType < INTERACTIVE) + if(jobType > BATCH_JOBS || jobType < INTERACTIVE_JOBS) return false; else if (uLow > uHi) return false; @@ -587,16 +617,74 @@ this.uProb[jobType] = uProb; } else { - this.uLow[INTERACTIVE] = this.uLow[BATCH] = uLow; - this.uMed[INTERACTIVE] = this.uMed[BATCH] = uMed; - this.uHi[INTERACTIVE] = this.uHi[BATCH] = uHi; - this.uProb[INTERACTIVE] = this.uProb[BATCH] = uProb; + this.uLow[INTERACTIVE_JOBS] = this.uLow[BATCH_JOBS] = uLow; + this.uMed[INTERACTIVE_JOBS] = this.uMed[BATCH_JOBS] = uMed; + this.uHi[INTERACTIVE_JOBS] = this.uHi[BATCH_JOBS] = uHi; + this.uProb[INTERACTIVE_JOBS] = this.uProb[BATCH_JOBS] = uProb; } return true; } - /** Sets the parameters for the running time + /** + * Gets the probability of the job being a parallel job + * @return the value of uProb; <tt>-1</tt> if an error occurs. + * @see #INTERACTIVE_JOBS + * @see #BATCH_JOBS + */ + public double getParallelJobUProb(int jobType) { + if(jobType > BATCH_JOBS || jobType < INTERACTIVE_JOBS) + return UNKNOWN; + + return uProb[jobType]; + } + + /** + * Gets the log2 of the maximal size of a job in the system (system's size) + * @param jobType the type of jobs + * @return the value of uHi; <tt>-1</tt> if an error occurs. + * @see #INTERACTIVE_JOBS + * @see #BATCH_JOBS + */ + public double getParallelJobUHi(int jobType) { + if(jobType > BATCH_JOBS || jobType < INTERACTIVE_JOBS) + return UNKNOWN; + + return uHi[jobType]; + } + + /** + * Gets the medium size of parallel jobs in the system. It is log2 of + * the size. + * @param jobType the type of jobs + * @return the value of uMed; <tt>-1</tt> if an error occurs. + * @see #INTERACTIVE_JOBS + * @see #BATCH_JOBS + */ + public double getParallelJobUMed(int jobType) { + if(jobType > BATCH_JOBS || jobType < INTERACTIVE_JOBS) + return UNKNOWN; + + return uMed[jobType]; + } + + /** + * Gets the the log2 of the minimal size of job in the system (you can add or + * subtract 0.2 to give less/more probability to the minimal size). + * @param jobType the type of jobs + * @return the value of uLow; <tt>-1</tt> if an error occurs. + * @see #INTERACTIVE_JOBS + * @see #BATCH_JOBS + */ + public double getParallelJobULow(int jobType) { + if(jobType > BATCH_JOBS || jobType < INTERACTIVE_JOBS) + return UNKNOWN; + + return uLow[jobType]; + } + + /** + * Sets the parameters for the running time * The running time is computed using hyper-gamma distribution. * The parameters a1,b1,a2,b2 are the parameters of the two gamma distributions * The p parameter of the hyper-gamma distribution is calculated as a straight @@ -615,7 +703,7 @@ public boolean setRunTimeParameters(int jobType, double a1, double a2, double b1, double b2, double pa, double pb) { - if(jobType > BATCH || jobType < INTERACTIVE) + if(jobType > BATCH_JOBS || jobType < INTERACTIVE_JOBS) return false; if(useJobType_) { @@ -624,17 +712,40 @@ this.pa[jobType] = pa; this.pb[jobType] = pb; } else { - this.a1[INTERACTIVE] = this.a1[BATCH] = a1; - this.b1[INTERACTIVE] = this.a1[BATCH] = b1; - this.a2[INTERACTIVE] = this.a1[BATCH] = a2; - this.b2[INTERACTIVE] = this.a1[BATCH] = b2; - this.pa[INTERACTIVE] = this.a1[BATCH] = pa; - this.pb[INTERACTIVE] = this.a1[BATCH] = pb; + this.a1[INTERACTIVE_JOBS] = this.a1[BATCH_JOBS] = a1; + this.b1[INTERACTIVE_JOBS] = this.a1[BATCH_JOBS] = b1; + this.a2[INTERACTIVE_JOBS] = this.a1[BATCH_JOBS] = a2; + this.b2[INTERACTIVE_JOBS] = this.a1[BATCH_JOBS] = b2; + this.pa[INTERACTIVE_JOBS] = this.a1[BATCH_JOBS] = pa; + this.pb[INTERACTIVE_JOBS] = this.a1[BATCH_JOBS] = pb; } return true; } + /** + * Gets the runtime parameters. That is, it returns the parameters + * used for the hyper-gamma distribution. For more detail on the + * parameters, please check the paper that describes the model. + * @param jobType the type of jobs + * @return an array where: <br> + * array[0] = a1 - hyper-gamma distribution parameter. <br> + * array[1] = a2 - hyper-gamma distribution parameter. <br> + * array[2] = b1 - hyper-gamma distribution parameter. <br> + * array[3] = b2 - hyper-gamma distribution parameter. <br> + * array[4] = pa - hyper-gamma distribution parameter. <br> + * array[5] = pb - hyper-gamma distribution parameter. <br> + * The method will return <tt>null</tt> if an error occurs. + */ + public double[] getRunTimeParameters(int jobType) { + if(jobType > BATCH_JOBS || jobType < INTERACTIVE_JOBS) + return null; + + return new double[] { this.a1[jobType], this.a2[jobType], + this.b1[jobType], this.b2[jobType], + this.pa[jobType], this.pb[jobType]}; + } + /** * Sets the parameters for the inter-arrival time * The inter-arriving time is calculated using two gamma distributions. @@ -644,12 +755,12 @@ * arrived at each time interval (bucket). * The inter-arrival time is calculated using both gammas * Since gamma(aarr,barr) represents the arrive-time at the rush time , we use - * a constant ,ARAR (Arrive-Rush-All-Ratio), to set the alpha parameter (the new + * a constant, ARAR (Arrive-Rush-All-Ratio), to set the alpha parameter (the new * aarr) so it will represent the arrive-time at all hours of the day. */ public boolean setInterArrivalTimeParameters(int jobType, double aarr, double barr, double anum, double bnum, double arar) { - if(jobType > BATCH || jobType < INTERACTIVE) + if(jobType > BATCH_JOBS || jobType < INTERACTIVE_JOBS) return false; if(useJobType_) { @@ -659,16 +770,44 @@ this.bnum[jobType] = bnum; } else { - this.aarr[INTERACTIVE] = this.aarr[BATCH] = aarr * arar; - this.barr[INTERACTIVE] = this.barr[BATCH] = barr; - this.anum[INTERACTIVE] = this.barr[BATCH] = anum; - this.bnum[INTERACTIVE] = this.barr[BATCH] = bnum; + this.aarr[INTERACTIVE_JOBS] = this.aarr[BATCH_JOBS] = aarr * arar; + this.barr[INTERACTIVE_JOBS] = this.barr[BATCH_JOBS] = barr; + this.anum[INTERACTIVE_JOBS] = this.barr[BATCH_JOBS] = anum; + this.bnum[INTERACTIVE_JOBS] = this.barr[BATCH_JOBS] = bnum; } return true; } /** + * Returns the parameters for the inter-arrival time + * The inter-arriving time is calculated using two gamma distributions. + * gamma(aarr,barr) represents the inter_arrival time for the rush hours. It is + * independent on the hour the job arrived at. + * The cdf of gamma(bnum,anum) represents the proportion of number of jobs which + * arrived at each time interval (bucket). + * The inter-arrival time is calculated using both gammas + * Since gamma(aarr,barr) represents the arrive-time at the rush time , we use + * a constant, ARAR (Arrive-Rush-All-Ratio), to set the alpha parameter (the new + * aarr) so it will represent the arrive-time at all hours of the day. + * @param jobType the type of jobs + * @return an array where: <br> + * array[0] = aarr - gamma distribution parameter. <br> + * array[1] = barr - gamma distribution parameter. <br> + * array[2] = anum - gamma distribution parameter. <br> + * array[3] = bnum - gamma distribution parameter. <br> + * The method will return <tt>null</tt> if an error occurs. + */ + public double[] getInterArrivalTimeParameters(int jobType) { + + if(jobType > BATCH_JOBS || jobType < INTERACTIVE_JOBS) + return null; + + return new double[] { this.aarr[jobType], this.barr[jobType], + this.anum[jobType], this.bnum[jobType]}; + } + + /** * Sets the maximum number of jobs to be generated by this workload model * @param numJobs the number of jobs * @returns <tt>true</tt> if the number of jobs has been set; @@ -699,6 +838,27 @@ } /** + * Gets the hour of the day when the simulation should start + * @return the start hour (between 0 and 23) + */ + public int getStartHour() { + return start_; + } + + /** + * Sets the hour of the day when the simulation should start + * @param start the start hour to set (between 0 and 23) + * @return <tt>true</tt> if set; <tt>false</tt> otherwise. + */ + public boolean setStartHour(int start) { + if(start < 0 || start > 23) + return false; + + start_ = start; + return false; + } + + /** * Sets a Gridlet file size (in byte) for sending to/from a resource. * @param size a Gridlet file size (in byte) * @return <tt>true</tt> if it is successful, <tt>false</tt> otherwise @@ -883,13 +1043,13 @@ */ private boolean createGridlets() { - int type = INTERACTIVE; + int type = INTERACTIVE_JOBS; int nodes; long arrTime; int runTime; arrivalInit(aarr, barr, anum, bnum, START, weights); for (int i=0; i<numJobs_; i++) { - long[] info = arrive(type, weights, aarr, barr); + long[] info = getNextArrival(type, weights, aarr, barr); type = (int)info[0]; arrTime = (long)info[1]; @@ -909,9 +1069,6 @@ return true; } - /*----------------------------------------------------------------------------*/ - /* CALC_NUMBER_OF_NODES (NUMBER OF NODES) */ - /* -------------------------------------------------------------------------- */ /* * we distinguish between serial jobs , power2 jobs and other. * for serial job (with probability SerialProb) the number of nodes is 1 @@ -936,12 +1093,8 @@ return (int)(Math.pow(2, par) + 0.5); // return round(2^par) } - /*----------------------------------------------------------------------------*/ - /* TIMES_FROM_NODES (RUNTIME) */ - /* -------------------------------------------------------------------------- */ - /* - * time_from_nodes returns a value of a random number from hyper_gamma - * distribution. + /* + * timeFromNodes returns a value of a random number from hyperGamma distribution. * The a1,b1,a2,b2 are the parameters of both gammas. * The 'p' parameter is calculated from the 'nodes' 'pa' and 'pb' arguments * using the formula: p = pa * nodes + pb. @@ -966,9 +1119,9 @@ return (long)Math.exp(hg); } - /* The arrive process. - * 'arrive' returns arrival time (from the beginning of the simulation) of - * the current job. + /* Initialises the variables for the arrival process. + * 'getNextArrival' returns arrival time (from the beginning of + * the simulation) of the current job. * The (gamma distribution) parameters 'aarr' and 'barr' represent the * inter-arrival time at rush hours. * The (gamma distribution) parameters 'anum' and 'bnum' represent the number @@ -980,7 +1133,7 @@ * TOO_MUCH_ARRIVE_TIME) then another value is chosen. * * The algorithm (briefly): - * A. Preparations (calculated only once in 'arrive_init()': + * A. Preparations (calculated only once in 'arrivalInit()': * 1. foreach time interval (bucket) calculate its proportion of the number * of arriving jobs (using 'anum' and 'bnum'). This value will be the * bucket's points. @@ -988,12 +1141,12 @@ * 3. divide the points in each bucket by the points mean ("normalize" the * points in all buckets) * B. randomly choosing a new arrival time for a job: - * 1. get a random value from distribution gamma(aarr , barr). + * 1. get a random value from distribution gamma(aarr, barr). * 2. calculate the points we have. * 3. accumulate inter-arrival time by passing buckets (while paying them * points for that) until we do not have enough points. * 4. handle reminders - add the new reminder and subtract the old reminder. - * 5. update the time variables ('current' and 'time_from_begin') + * 5. update the time variables ('current_' and 'timeFromBegin_') */ private void arrivalInit(double[] aarr, double[] barr, double[] anum, double[] bnum, int start_hour, double weights[][]) { @@ -1005,7 +1158,7 @@ for(int j=0; j<weights[i].length; j++) weights[i][j] = 0; - current_[BATCH] = current_[INTERACTIVE] = start_hour * BUCKETS / HOURS_IN_DAY; + current_[BATCH_JOBS] = current_[INTERACTIVE_JOBS] = start_hour * BUCKETS / HOURS_IN_DAY; /* * for both batch and interactive calculate the propotion of each bucket , @@ -1025,12 +1178,12 @@ for (int i=0 ; i<BUCKETS ; i++) weights[j][i] /= mean[j]; - calcNextArrival(BATCH ,weights,aarr,barr); - calcNextArrival(INTERACTIVE,weights,aarr,barr); + calcNextArrival(BATCH_JOBS ,weights,aarr,barr); + calcNextArrival(INTERACTIVE_JOBS,weights,aarr,barr); } /* - * 'calcNextArrival' calculates the next inter-arrival time according + * calcNextArrival calculates the next inter-arrival time according * to the current time of the day. * 'type' is the type of the next job -- interactive or batch * alpha and barr are the parameters of the gamma distribution of the @@ -1068,20 +1221,22 @@ current_[type] = bucket; } - /*----------------------------------------------------------------------------*/ - /* ARRIVE (ARRIVAL TIME AND TYPE) */ - /*----------------------------------------------------------------------------*/ - /* - * return the time for next job to arrive the system. - * returns also the type of the next job , which is the type that its - * next arrive time (time_from_begin) is closer to the start (smaller). - * notice that since calc_next_arrive changes time_from_begin[] we must save - * the time_from_begin in 'res' so we would be able to return it. - */ - private long[] arrive(int type, double[][] weights, double[] aarr, double[] barr) { + /* + * Return the time for next job to arrive the system. + * returns also the type of the next job , which is the type that its + * next arrive time (time_from_begin) is closer to the start (smaller). + * notice that since calc_next_arrive changes time_from_begin[] we must save + * the time_from_begin in 'res' so we would be able to return it. + * @returns an array where array[0] = type of the job, array[1] = arrival time + */ + private long[] getNextArrival(int type, double[][] weights, + double[] aarr, double[] barr) { + long res; - type = (timeFromBegin_[BATCH] < timeFromBegin_[INTERACTIVE]) ? BATCH : INTERACTIVE; + type = (timeFromBegin_[BATCH_JOBS] < timeFromBegin_[INTERACTIVE_JOBS]) ? + BATCH_JOBS : INTERACTIVE_JOBS; + res = timeFromBegin_[type]; // save the job's arrival time // randomly choose the next job's (of the same type) arrival time @@ -1102,11 +1257,12 @@ * @pre numProc > 0 * @post $none */ - protected void submitGridlet(int id, long submitTime, int runTime, int numProc) - { + protected void submitGridlet(int id, long submitTime, + int runTime, int numProc) { // create the gridlet int len = runTime * rating_; // calculate a job length for each PE - Gridlet gl = new Gridlet(id, len, size_, size_, GridSim.isTraceEnabled()); + Gridlet gl = new Gridlet(id, len, size_, + size_, GridSim.isTraceEnabled()); gl.setUserID( super.get_id() ); // set the owner ID gl.setNumPE(numProc); // set the requested num of proc @@ -1131,26 +1287,29 @@ // --- Methods required by the distributions used by the workload model --- + // --- Most of these methods were ported from C to Java, but the logic --- + // --- remains the same as in Lublin's workload model in C --- /* - * hyper_gamma returns a value of a random variable of mixture of two + * hyperGamma returns a value of a random variable of mixture of two * gammas. its parameters are those of the two gammas: a1,b1,a2,b2 and the * relation between the gammas (p = the probability of the first gamma). we * first randomly decide which gamma will be active ((a1,b1) or (a2,b2)). * then we randomly choose a number from the chosen gamma distribution. */ - double hyperGamma(double a1, double b1, double a2, double b2, double p) { + private double hyperGamma(double a1, double b1, double a2, + double b2, double p) { double a, b, hg, u = random_.nextDouble(); - if (u <= p) { /* gamma(a1,b1) */ + if (u <= p) { // gamma(a1,b1) a = a1; b = b1; - } else { /* gamma(a2,b2) */ + } else { // gamma(a2,b2) a = a2; b = b2; } - /* generate a value of a random variable from distribution gamma(a,b) */ + // generates a value of a random variable from distribution gamma(a,b) hg = gamrnd(a, b); return hg; } @@ -1177,7 +1336,7 @@ } /* - * gamrnd_int_alpha returns a value of a random variable of gamma(n,beta) + * gamrndIntAlpha returns a value of a random variable of gamma(n,beta) * distribution where n is integer(unsigned long actually). gamma(n,beta) == * beta*gamma(n,1) == beta* sum(1..n){gamma(1,1)} == beta* sum(1..n){exp(1)} == * beta* sum(1..n){-ln(uniform(0,1))} @@ -1185,28 +1344,27 @@ private double gamrndIntAlpha(long n, double beta) { double acc = 0; for (int i = 0; i < n; i++) - acc += Math.log(random_.nextDouble()); /* sum the exponential - * random variables - */ + acc += Math.log(random_.nextDouble()); // sum the exponential + // random variables return (-acc * beta); } /* - * gamrnd_alpha_smaller_1 returns a value of a random variable of + * gamrndAlphaSmaller1 returns a value of a random variable of * gamma(alpha,beta) where alpha is smaller than 1. This is done using the * Beta distribution. (alpha<1) ==> (1-alpha<1) ==> we can use * beta_less_1(alpha,1-alpha) gamma(alpha,beta) = exponential(beta) * * Beta(alpha,1-alpha) */ private double gamrndAlphaSmaller1(double alpha, double beta) { - double x = betarndLess1(alpha, 1 - alpha); /* beta random variable */ - double y = -Math.log(random_.nextDouble()); /* exponential random - * variable */ + double x = betarndLess1(alpha, 1 - alpha); // beta random variable + double y = -Math.log(random_.nextDouble()); // exponential random + // variable return (beta * x * y); } /* - * betarnd_less_1 returns a value of a random variable of beta(alpha,beta) + * betarndLess1 returns a value of a random variable of beta(alpha,beta) * distribution where both alpha and beta are smaller than 1 (and larger * than 0) */ @@ -1237,13 +1395,14 @@ return gser(x, alpha); } - /* x >= a+1 */ + // x >= a+1 return 1 - gcf(x, alpha); } - /*----------------------------------------------------------------------------*/ - /* GSER */ - /*----------------------------------------------------------------------------*/ + + /* + * Gser + */ private double gser(double x, double a) { int i; double sum, monom, aa = a; @@ -1255,14 +1414,15 @@ monom *= (x / aa); sum += monom; if (monom < sum * EPS) - return (sum * Math.exp(-x + a * Math.log(x) - lgamma(a))); + return (sum * Math.exp(-x + a * Math.log(x) - logGamma(a))); } - return -1; /* error did not converged */ + return -1; // error, did not converged } - /*----------------------------------------------------------------------------*/ - /* GCF */ - /*----------------------------------------------------------------------------*/ + + /* + * Returns the GCF + */ private double gcf(double x, double a) { int i; double gold = 0, g, a0 = 1, a1 = x, b0 = 0, b1 = 1, fac = 1, anf, ana; @@ -1278,11 +1438,11 @@ fac = 1 / a1; g = b1 * fac; if (Math.abs((g - gold) / g) < EPS) - return (g * Math.exp(-x + a * Math.log(x) - lgamma(a))); + return (g * Math.exp(-x + a * Math.log(x) - logGamma(a))); gold = g; } } - return 2; /* gamcdf will return -1 */ + return 2; // gamcdf will return -1 } /* @@ -1296,15 +1456,15 @@ double hi, double prob) { double a, b, tsu, u = random_.nextDouble(); - if (u <= prob) { /* uniform(low , med) */ + if (u <= prob) { // uniform(low , med) a = low; b = med; - } else { /* uniform(med , hi) */ + } else { // uniform(med , hi) a = med; b = hi; } - /* generate a value of a random variable from distribution uniform(a,b) */ + // generate a value of a random variable from distribution uniform(a,b) tsu = (random_.nextDouble() * (b - a)) + a; return tsu; } @@ -1316,7 +1476,7 @@ * Direct inquiries to 30 Frost Street, Cambridge, MA 02140 */ - static private double lgamma(double x) + static private double logGamma(double x) throws ArithmeticException { double p, q, w, z; @@ -1344,7 +1504,7 @@ if (x < -34.0) { q = -x; - w = lgamma(q); + w = logGamma(q); p = Math.floor(q); if (p == q) throw new ArithmeticException("lgamma: Overflow"); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mar...@us...> - 2008-02-04 04:32:39
|
Revision: 85 http://gridsim.svn.sourceforge.net/gridsim/?rev=85&view=rev Author: marcos_dias Date: 2008-02-03 20:32:43 -0800 (Sun, 03 Feb 2008) Log Message: ----------- This update includes a workload class that generates gridlets according to Lublin and Feitelson's workload model. The model is described in: Uri Lublin and Dror G. Feitelson, The Workload on Parallel Supercomputers: Modeling the Characteristics of Rigid Jobs. J. Parallel & Distributed Comput. 63(11), pp. 1105-1122, Nov 2003. This update also includes a short example on how to use the Lubin99Workload class. Added Paths: ----------- branches/gridsim4.0-branch3/examples/examples/workload/parallel/LublinWorkloadExample01.java branches/gridsim4.0-branch3/source/gridsim/turbo/Lublin99Workload.java Added: branches/gridsim4.0-branch3/examples/examples/workload/parallel/LublinWorkloadExample01.java =================================================================== --- branches/gridsim4.0-branch3/examples/examples/workload/parallel/LublinWorkloadExample01.java (rev 0) +++ branches/gridsim4.0-branch3/examples/examples/workload/parallel/LublinWorkloadExample01.java 2008-02-04 04:32:43 UTC (rev 85) @@ -0,0 +1,182 @@ + +package examples.workload.parallel; + +import gridsim.GridResource; +import gridsim.GridSim; +import gridsim.Machine; +import gridsim.MachineList; +import gridsim.turbo.Lublin99Workload; +import gridsim.turbo.TResourceCharacteristics; + +import java.util.ArrayList; +import java.util.Calendar; +import java.util.LinkedList; +import java.util.Random; + +/** + * Test Driver class for this example + */ +public class LublinWorkloadExample01 +{ + /** + * Creates main() to run this example + */ + public static void main(String[] args) + { + long startTime = System.currentTimeMillis(); + + try { + + ////////////////////////////////////////// + // Get the workload to be used The format should be: + // ASCII text, gzip or zip. + + ArrayList<GridResource> resources = new ArrayList<GridResource>(); + + ////////////////////////////////////////// + // Initialize the GridSim package. It should be called + // before creating any entities. We can't run this example without + // initializing GridSim first. We will get run-time exception + // error. + + // number of grid user entities + any Workload entities. + int num_user = 1; + Calendar calendar = Calendar.getInstance(); + boolean trace_flag = false; // mean trace GridSim events + + long seed = 1062348; + + // Initialize the GridSim package without any statistical + // functionalities. Hence, no GridSim_stat.txt file is created. + System.out.println("Initializing GridSim package"); + GridSim.init(num_user, calendar, trace_flag); + + ////////////////////////////////////////// + // Creates one or more GridResource entities + int totalResource = 1; // total number of Grid resources + int rating = 377; // rating of each PE in MIPS + int totalPE = 9; // total number of PEs for each Machine + int totalMachine = 128; // total number of Machines + int i = 0; + + String[] resArray = new String[totalResource]; + for (i = 0; i < totalResource; i++) { + String resName = "Res_" + i; + GridResource resource = createGridResource(resName, rating, totalMachine, totalPE); + resources.add(resource); + + // add a resource name into an array + resArray[i] = resName; + } + + ////////////////////////////////////////// + // Creates one Workload trace entity. + + int resID = 0; + Random r = new Random(); + resID = r.nextInt(totalResource); + Lublin99Workload workload = + new Lublin99Workload("Load_1", resArray[resID], rating, false, seed); + + // uHi is going to contain log2 of the maximum number of PEs that a + // parallel job can require + double uHi = Math.log(totalPE * totalMachine) / Math.log(2d); + double uMed = uHi-2.5; + + workload.setParallelJobProbabilities(Lublin99Workload.BATCH, + Lublin99Workload.ULOW_BATCH, uMed, uHi, + Lublin99Workload.UPROB_BATCH); + + // sets the workload to create 1000 jobs + workload.setNumJobs(1000); + + ////////////////////////////////////////// + // Starts the simulation in debug mode +// GridSim.startGridSimulation(true); + + // Start the simulation in normal mode + GridSim.startGridSimulation(); + + ////////////////////////////////////////// + // Final step: Prints the Gridlets when simulation is over + long finishTime = System.currentTimeMillis(); + System.out.println("The simulation took " + (finishTime - startTime) + " milliseconds"); + + // prints the Gridlets inside a Workload entity + // workload.printGridletList(trace_flag); + } + catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * Creates one Grid resource. A Grid resource contains one or more + * Machines. Similarly, a Machine contains one or more PEs (Processing + * Elements or CPUs). + * @param name a Grid Resource name + * @param peRating rating of each PE + * @param totalMachine total number of Machines + * @param totalPE total number of PEs for each Machine + */ + private static GridResource createGridResource(String name, int peRating, + int totalMachine, int totalPE) + { + + ////////////////////////////////////////// + // Here are the steps needed to create a Grid resource: + // 1. We need to create an object of MachineList to store one or more + // Machines + MachineList mList = new MachineList(); + + for (int i = 0; i < totalMachine; i++) + { + ////////////////////////////////////////// + // 4. Create one Machine with its id and list of PEs or CPUs + mList.add( new Machine(i, totalPE, peRating) ); + } + + ////////////////////////////////////////// + // 5. Create a ResourceCharacteristics object that stores the + // properties of a Grid resource: architecture, OS, list of + // Machines, allocation policy: time- or space-shared, time zone + // and its price (G$/PE time unit). + String arch = "Sun Ultra"; // system architecture + String os = "Solaris"; // operating system + double time_zone = 0.0; // time zone this resource located + double cost = 3.0; // the cost of using this resource + + TResourceCharacteristics resConfig = new TResourceCharacteristics( + arch, os, mList, TResourceCharacteristics.CB_PARALLEL_SPACE_SHARED, + time_zone, cost); + + ////////////////////////////////////////// + // 6. Finally, we need to create a GridResource object. + double baud_rate = 10000.0; // communication speed + long seed = 11L*13*17*19*23+1; + double peakLoad = 0.0; // the resource load during peak hour + double offPeakLoad = 0.0; // the resource load during off-peak hr + double holidayLoad = 0.0; // the resource load during holiday + + // incorporates weekends so the grid resource is on 7 days a week + LinkedList weekends = new LinkedList(); + weekends.add(new Integer(Calendar.SATURDAY)); + weekends.add(new Integer(Calendar.SUNDAY)); + + // incorporates holidays. However, no holidays are set in this example + LinkedList holidays = new LinkedList(); + GridResource gridRes = null; + try { + gridRes = new GridResource(name, baud_rate, seed, + resConfig, peakLoad, offPeakLoad, holidayLoad, weekends, + holidays); + } + catch (Exception e) { + e.printStackTrace(); + } + + System.out.println("Creates one Grid resource with name = " + name); + return gridRes; + } +} // end class + Added: branches/gridsim4.0-branch3/source/gridsim/turbo/Lublin99Workload.java =================================================================== --- branches/gridsim4.0-branch3/source/gridsim/turbo/Lublin99Workload.java (rev 0) +++ branches/gridsim4.0-branch3/source/gridsim/turbo/Lublin99Workload.java 2008-02-04 04:32:43 UTC (rev 85) @@ -0,0 +1,1422 @@ +/* + * Title: GridSim Toolkit + * Description: GridSim (Grid Simulation) Toolkit for Modeling and Simulation + * of Parallel and Distributed Systems such as Clusters and Grids + * Licence: GPL - http://www.gnu.org/copyleft/gpl.html + * + */ + +package gridsim.turbo; + +import eduni.simjava.*; +import gridsim.*; +import gridsim.net.*; +import java.util.*; + +/** + * The main purpose of this class is to create a realistic simulation + * environment where your jobs or Gridlets are competing with others. + * In other words, the grid resource might not be available at certain times. + * In addition, the arrival time of jobs are also captured in the workload model. + * <p> + * This class is responsible for creating jobs according to the workload model + * generator presented by Lublin and Feitelson and send Gridlets to only + * <tt>one</tt> destinated resource. <br> + * <b>NOTE:</b> + * <ul> + * <li> This class can be classified as <b>one grid user entity</b>. + * Hence, you need to incorporate this entity into <tt>numUser</tt> + * during {@link gridsim.GridSim#init(int, Calendar, boolean)} + * <li> If you need to use multiple trace files to submit Gridlets to + * same or different resources, then you need to create multiple + * instances of this class <tt>each with a unique entity name</tt>. + * <li> If you are running an experiment using the network extension, + * i.e. the gridsim.net package, then you need to use + * {@link #Lublin99Workload(String, double, double, int, String, String, int)} + * instead. + * <li> The default job file size for sending to and receiving from + * a resource is {@link gridsim.net.Link#DEFAULT_MTU}. + * However, you can specify + * the file size by using {@link #setGridletFileSize(int)}. + * <li> A job run time is only for 1 PE <tt>not</tt> the total number of + * allocated PEs. + * Therefore, a Gridlet length is also calculated for 1 PE.<br> + * For example, job #1 in the trace has a run time of 100 seconds + * for 2 processors. This means each processor runs + * job #1 for 100 seconds, if the processors have the same + * specification. + * </ul> + * <p> + * For more information on the workload model, please read the following paper: <br> + * Uri Lublin and Dror G. Feitelson, The Workload on Parallel Supercomputers: + * Modeling the Characteristics of Rigid Jobs. J. Parallel & Distributed Comput. 63(11), + * pp. 1105-1122, Nov 2003. + * <br> + * + * @see gridsim.GridSim#init(int, Calendar, boolean) + * @author Marcos Dias de Assuncao + * @since GridSim Turbo Alpha 0.1 + * @invariant $none + */ +public class Lublin99Workload extends GridSim { + + private String resName_; // resource name + private int resID_; // resource ID + private int rating_; // a PE rating + private int gridletID_; // gridletID + private int size_; // job size for sending it through a network + private ArrayList list_; // a list for getting all the Gridlets + private Random random_ = null; // the number generator to be used + + // Log PI for lgamma method + private static final double LOGPI = 1.14472988584940017414; + protected final int INTERVAL = 10; // number of intervals + + // ------------ CONSTANTS USED BY THE WORKLOAD MODEL -------------- + + // number of jobs generated by this entity + private static final int SIZE = 1000; + + // no more than two days =exp(12) for runtime + private static final int TOO_MUCH_TIME = 12; + + // no more than 5 days =exp(13) for arrivetime + private static final int TOO_MUCH_ARRIVE_TIME = 13; + + // number of buckets in one day -- 48 half hours + private static final int BUCKETS = 48; + + // we now define (calculate) how many seconds are in one hour,day,bucket + private static final int SECONDS_IN_HOUR = 3600; + private static final int SECONDS_IN_DAY = (24*SECONDS_IN_HOUR); + private static final int SECONDS_IN_BUCKET = (SECONDS_IN_DAY/BUCKETS); + private static final int HOURS_IN_DAY = 24; + + // The hours of the day are being moved cyclically. + // instead of [0,23] make the day [CYCLIC_DAY_START,(24+CYCLIC_DAY_START-1)] + private static final int CYCLIC_DAY_START = 11; + + // max iterations number for the iterative calculations + private static final int ITER_MAX = 1000; + + // small epsilon for the iterative algorithm's accuracy + private static final double EPS = 1E-10; + + /** Represents interactive jobs */ + public static final int INTERACTIVE = 0; + + /** Represents batch jobs */ + public static final int BATCH = 1; + + // ------------------- MODEL DEFAULT PARAMETERS ----------------------- + + /* The parameters for number of nodes: + * serial_prob is the proportion of the serial jobs + * pow2_prob is the proportion of the jobs with power 2 number of nodes + * ULow , UMed , UHi and Uprob are the parameters for the two-stage-uniform + * which is used to calculate the number of nodes for parallel jobs. + * ULow is the log2 of the minimal size of job in the system (you can add or + * subtract 0.2 to give less/more probability to the minimal size) . + * UHi is the log2 of the maximal size of a job in the system (system's size) + * UMed should be in [UHi-1.5 , UHi-3.5] + * Uprob should be in [0.7 - 0.95] + */ + public static final double SERIAL_PROB_BATCH = 0.2927; + public static final double POW2_PROB_BATCH = 0.6686; + public static final double ULOW_BATCH = 1.2f; // smallest parallel batch job has 2 nodes + public static final double UMED_BATCH = 5; + public static final double UHI_BATCH = 7; // biggest batch job has 128 nodes + public static final double UPROB_BATCH = 0.875; + + public static final double SERIAL_PROB_ACTIVE = 0.1541; + public static final double POW2_PROB_ACTIVE = 0.625; + public static final double ULOW_ACTIVE = 1; // smallest interactive parallel job has 2 nodes + public static final double UMED_ACTIVE = 3; + public static final double UHI_ACTIVE = 5.5f; // biggest interactive job has 45 nodes + public static final double UPROB_ACTIVE = 0.705; + + /* The parameters for the running time + * The running time is computed using hyper-gamma distribution. + * The parameters a1,b1,a2,b2 are the parameters of the two gamma distributions + * The p parameter of the hyper-gamma distribution is calculated as a straight + * (linear) line p = pa*nodes + pb. + * 'nodes' will be calculated in the program, here we defined the 'pa','pb' + * parameters. + */ + public static final double A1_BATCH = 6.57; + public static final double B1_BATCH = 0.823; + public static final double A2_BATCH = 639.1; + public static final double B2_BATCH = 0.0156; + public static final double PA_BATCH = -0.003; + public static final double PB_BATCH = 0.6986; + + public static final double A1_ACTIVE = 3.8351; + public static final double B1_ACTIVE = 0.6605; + public static final double A2_ACTIVE = 7.073; + public static final double B2_ACTIVE = 0.6856; + public static final double PA_ACTIVE = -0.0118; + public static final double PB_ACTIVE = 0.9156; + + + /* The parameters for the inter-arrival time + * The inter-arriving time is calculated using two gamma distributions. + * gamma(aarr,barr) represents the inter_arrival time for the rush hours. It is + * independent on the hour the job arrived at. + * The cdf of gamma(bnum,anum) represents the proportion of number of jobs which + * arrived at each time interval (bucket). + * The inter-arrival time is calculated using both gammas + * Since gamma(aarr,barr) represents the arrive-time at the rush time , we use + * a constant ,ARAR (Arrive-Rush-All-Ratio), to set the alpha parameter (the new + * aarr) so it will represent the arrive-time at all hours of the day. + */ + public static final double AARR_BATCH = 6.0415; + public static final double BARR_BATCH = 0.8531; + public static final double ANUM_BATCH = 6.1271; + public static final double BNUM_BATCH = 5.2740; + public static final double ARAR_BATCH = 1.0519; + + public static final double AARR_ACTIVE = 6.5510; + public static final double BARR_ACTIVE = 0.6621; + public static final double ANUM_ACTIVE = 8.9186; + public static final double BNUM_ACTIVE = 3.6680; + public static final double ARAR_ACTIVE = 0.9797; + + /* + * Here are the model's parameters for typeless data (no batch nor interactive) + * We use those parameters when INCLUDE_JOBS_TYPE is off (0) + */ + public static final double SERIAL_PROB = 0.244; + public static final double POW2_PROB = 0.576; + public static final double ULOW = 0.8f; // The smallest parallel job is 2 nodes + public static final double UMED = 4.5f; + public static final double UHI = 7f; // SYSTEM SIZE is 2^UHI == 128 + public static final double UPROB = 0.86; + + public static final double A1 = 4.2; + public static final double B1 = 0.94; + public static final double A2 = 312; + public static final double B2 = 0.03; + public static final double PA = -0.0054; + public static final double PB = 0.78; + + public static final double AARR = 10.2303; + public static final double BARR = 0.4871; + public static final double ANUM = 8.1737; + public static final double BNUM = 3.9631; + public static final double ARAR = 1.0225; + + // start the simulation at midnight (hour 0) + private static final int START = 0; + + // -------------- Variable dependent attributes -------------------- + + // The workload duration, that is, for how long the workload can + // go creating and submitting gridlets. numJobs keeps the number of + // jobs that this workload should generate. The workload will + // finish when it apporaches whichever of these values + private double workloadDuration_; + private int numJobs_; + + private double[] a1, b1, a2, b2, pa, pb; + private double[] aarr, barr, anum, bnum; + private double[] serialProb, pow2Prob, uLow, uMed, uHi, uProb; + + // the appropriate weight (points) for each + // time-interval used in the arrive function + double[][] weights = new double[2][BUCKETS]; + + /* useJobType us if we should differ between batch and interactive + * jobs or not. If the value is true, then we use both batch and interactive + * values for the parameters and the output sample includes both interactive + * and batch jobs. We choose the type of the job to be the type whose next + * job arrives to the system first (smaller next arrival time). + * If the value is false, then we use the "whole sample" parameters. The output + * sample includes jobs from the same type (arbitrarily we choose batch). + * We force the type to be interactive by setting the next arrival time of + * interactive jobs to be Long.MAX_VALUE -- always larger than the batchs's + * next arrival. */ + private boolean useJobType_ = true; + + /* current time interval (the bucket's number) */ + private int[] current_; + + /* the number of seconds from the beginning of the simulation*/ + private long[] timeFromBegin_; + + /** + * Create a new Workload object <b>without</b> using the network extension. + * This means this entity directly sends Gridlets to a destination resource + * without going through a wired network. <br> + * <tt>NOTE:</tt> + * You can not use this constructor in an experiment that uses a wired + * network topology. + * @param name this entity name + * @param resourceName the resource name + * @param rating the resource's PE rating + * @param useJobType useJobType us if we should differ between batch and interactive + * jobs or not. If the value is <tt>true</tt>, then we use both batch and interactive + * values for the parameters and the output sample includes both interactive + * and batch jobs. We choose the type of the job to be the type whose next + * job arrives to the system first (smaller next arrival time). + * If the value is <tt>false</tt>, then we use the "whole sample" parameters. The output + * sample includes jobs from the same type (arbitrarily we choose batch). + * We force the type to be interactive by setting the next arrival time of + * interactive jobs to be <tt>Long.MAX_VALUE</tt> -- always larger than the batchs's + * next arrival. + * @param seed seed used by the random number generator + * @throws Exception This happens when creating this entity before + * initialising GridSim package or this entity name is + * <tt>null</tt> or empty + * @throws ParameterException This happens for the following conditions: + * <ul> + * <li>the entity name is null or empty + * <li>the resource entity name is null or empty + * <li>the resource PE rating <= 0 + * </ul> + * @pre name != null + * @pre fileName != nullb2 + * @pre resourceName != null + * @pre rating > 0 + * @post $none + */ + public Lublin99Workload(String name, String resourceName, + int rating, boolean useJobType, long seed) + throws ParameterException, Exception { + super(name, GridSimTags.DEFAULT_BAUD_RATE); + + // check the input parameters first + String msg = name + "(): Error - "; + if (resourceName == null || resourceName.length() == 0) { + throw new ParameterException(msg + "invalid resource name."); + } + else if (rating <= 0) { + throw new ParameterException(msg+"resource PE rating must be > 0."); + } + + System.out.println(name + ": Creating a workload object ..."); + init(resourceName, rating, useJobType, seed); + } + + /** + * Create a new Workload object <b>with</b> the network extension. + * This means this entity directly sends Gridlets to a destination resourceb2 + * through a link. The link is automatically created by this constructor. + * + * @param name this entity name + * @param baudRate baud rate of this link (bits/s) + * @param propDelay Propagation delay of the Link in milliseconds + * @param MTU Maximum Transmission Unit of the Link in bytes. + * Packets which are larger than the MTU should be split + * up into MTU size units. + * For example, a 1024 byte packet trying to cross a 576 + * byte MTU link should get split into 2 packets of 576 + * bytes and 448 bytes. + * @param resourceName the resource name + * @param rating the resource's PE rating + * @param useJobType useJobType us if we should differ between batch and interactive + * jobs or not. If the value is <tt>true</tt>, then we use both batch and interactive + * values for the parameters and the output sample includes both interactive + * and batch jobs. We choose the type of the job to be the type whose next + * job arrives to the system first (smaller next arrival time). + * If the value is <tt>false</tt>, then we use the "whole sample" parameters. The output + * sample includes jobs from the same type (arbitrarily we choose batch). + * We force the type to be interactive by setting the next arrival time of + * interactive jobs to be <tt>Long.MAX_VALUE</tt> -- always larger than the batchs's + * next arrival. + * @param seed seed used by the random number generator + * @throws Exception This happens when creating this entity before + * initialising GridSim package or this entity name is + * <tt>null</tt> or empty + * @throws ParameterException This happens for the following conditions: + * <ul> + * <li>the entity name is null or empty + * <li> baudRate <= 0 + * <li> propDelay <= 0 + * <li> MTU <= 0 + * <li>the resource entity name is null or empty + * <li>the resource PE rating <= 0 + * </ul> + * @pre name != null + * @pre baudRate > 0 + * @pre propDelay > 0 + * @pre MTU > 0 + * @pre fileName != null + * @pre resourceName != null + * @pre rating > 0 + * @post $none + */ + public Lublin99Workload(String name, double baudRate, double propDelay, int MTU, + String resourceName, int rating, boolean useJobType, long seed) + throws ParameterException, Exception { + super( name, new SimpleLink(name+"_link", baudRate, propDelay, MTU) ); + + // check the input parameters first + String msg = name + "(): Error - "; + if (resourceName == null || resourceName.length() == 0) { + throw new ParameterException(msg + "invalid resource name."); + } + else if (rating <= 0) { + throw new ParameterException(msg+"resource PE rating must be > 0."); + } + + System.out.println(name + ": Creating a workload object ..."); + init(resourceName, rating, useJobType, seed); + } + + /** + * Create a new Workload object <b>with</b> the network extension. + * This means this entity directly sends Gridlets to a destination resource + * through a link. The link is automatically created by this constructor. + * + * @param name this entity name + * @param link the link that will be used to connect this Workload + * to another entity or a Router. + * @param resourceName the resource name + * @param rating the resource's PE rating + * @param useJobType useJobType us if we should differ between batch and interactive + * jobs or not. If the value is <tt>true</tt>, then we use both batch and interactive + * values for the parameters and the output sample includes both interactive + * and batch jobs. We choose the type of the job to be the type whose next + * job arrives to the system first (smaller next arrival time). + * If the value is <tt>false</tt>, then we use the "whole sample" parameters. The output + * sample includes jobs from the same type (arbitrarily we choose batch). + * We force the type to be interactive by setting the next arrival time of + * interactive jobs to be <tt>Long.MAX_VALUE</tt> -- always larger than the batchs's + * next arrival. + * @param seed seed used by the random number generator + * @throws Exception This happens when creating this entity before + * initialising GridSim package or this entity name is + * <tt>null</tt> or empty + * @throws ParameterException This happens for the following conditions: + * <ul> + * <li>the entity name is null or empty + * <li>the link is empty + * <li>the resource entity name is null or empty + * <li>the resource PE rating <= 0 + * </ul> + * @pre name != null + * @pre link != null + * @pre fileName != null + * @pre resourceName != null + * @pre rating > 0 + * @post $none + */ + public Lublin99Workload(String name, Link link, + String resourceName, int rating, boolean useJobType, long seed) + throws ParameterException, Exception { + super(name, link); + + // check the input parameters first + String msg = name + "(): Error - "; + if (resourceName == null || resourceName.length() == 0) { + throw new ParameterException(msg + "invalid resource name."); + } + else if (rating <= 0) { + throw new ParameterException(msg+"resource PE rating must be > 0."); + } + + System.out.println(name + ": Creating a workload object ..."); + init(resourceName, rating, useJobType, seed); + } + + /** + * Initialises all the attributes + * @param fileName trace file name + * @param resourceName resource entity name + * @param rating resource PE rating + * @param useJobType <tt>true</tt> whether the workload should generate + * both interactive and batch jobs; <tt>false</tt> if the workload + * should generate only batch jobs. + * @pre $none + * @post $none + */ + private void init(String resourceName, int rating, + boolean useJobType, long seed) { + + useJobType_ = useJobType; + resName_ = resourceName; + resID_ = GridSim.getEntityId(resName_); + rating_ = rating; + gridletID_ = 1; // starts at 1 to make it the same as in a trace file + list_ = null; + size_ = Link.DEFAULT_MTU; + random_ = new Random(seed); + workloadDuration_ = Double.MAX_VALUE; + numJobs_ = 1000; + + a1 = new double[2]; b1 = new double[2]; + a2 = new double[2]; b2 = new double[2]; + pa = new double[2]; pb = new double[2]; + aarr = new double[2]; barr = new double[2]; + anum = new double[2]; bnum = new double[2]; + serialProb = new double[2]; pow2Prob = new double[2]; + uLow = new double[2]; uMed = new double[2]; + uHi = new double[2]; uProb = new double[2]; + current_ = new int[2]; + timeFromBegin_ = new long[2]; + + // separate batch from interactive + if (useJobType_) { + serialProb[BATCH] = SERIAL_PROB_BATCH; + pow2Prob[BATCH] = POW2_PROB_BATCH; + uLow[BATCH] = ULOW_BATCH; + uMed[BATCH] = UMED_BATCH; + uHi[BATCH] = UHI_BATCH; + uProb[BATCH] = UPROB_BATCH; + + serialProb[INTERACTIVE] = SERIAL_PROB_ACTIVE; + pow2Prob[INTERACTIVE] = POW2_PROB_ACTIVE; + uLow[INTERACTIVE] = ULOW_ACTIVE; + uMed[INTERACTIVE] = UMED_ACTIVE; + uHi[INTERACTIVE] = UHI_ACTIVE; + uProb[INTERACTIVE] = UPROB_ACTIVE; + + a1[BATCH] = A1_BATCH; b1[BATCH] = B1_BATCH; + a2[BATCH] = A2_BATCH; b2[BATCH] = B2_BATCH; + pa[BATCH] = PA_BATCH; pb[BATCH] = PB_BATCH; + + a1[INTERACTIVE] = A1_ACTIVE; b1[INTERACTIVE] = B1_ACTIVE; + a2[INTERACTIVE] = A2_ACTIVE; b2[INTERACTIVE] = B2_ACTIVE; + pa[INTERACTIVE] = PA_ACTIVE; pb[INTERACTIVE] = PB_ACTIVE; + + aarr[BATCH] = AARR_BATCH*ARAR_BATCH; barr[BATCH] = BARR_BATCH; + anum[BATCH] = ANUM_BATCH; bnum[BATCH] = BNUM_BATCH; + + aarr[INTERACTIVE] = AARR_ACTIVE*ARAR_ACTIVE; + barr[INTERACTIVE] = BARR_ACTIVE; + anum[INTERACTIVE] = ANUM_ACTIVE; + bnum[INTERACTIVE] = BNUM_ACTIVE; + } + else { + // whole sample -- make all batch jobs + serialProb[BATCH] = serialProb[INTERACTIVE] = SERIAL_PROB; + pow2Prob[BATCH] = pow2Prob[INTERACTIVE] = POW2_PROB; + uLow[BATCH] = uLow[INTERACTIVE] = ULOW ; + uMed[BATCH] = uMed[INTERACTIVE] = UMED ; + uHi[BATCH] = uHi[INTERACTIVE] = UHI ; + uProb[BATCH] = uProb[INTERACTIVE] = UPROB ; + + a1[BATCH] = a1[INTERACTIVE] = A1; + b1[BATCH] = b1[INTERACTIVE] = B1; + a2[BATCH] = a2[INTERACTIVE] = A2; + b2[BATCH] = b2[INTERACTIVE] = B2; + pa[BATCH] = pa[INTERACTIVE] = PA; + pb[BATCH] = pb[INTERACTIVE] = PB; + + aarr[BATCH] = aarr[INTERACTIVE] = AARR * ARAR; + barr[BATCH] = barr[INTERACTIVE] = BARR; + anum[BATCH] = anum[INTERACTIVE] = ANUM; + bnum[BATCH] = bnum[INTERACTIVE] = BNUM; + } + + if ( ! useJobType_ ) // make all jobs batch + timeFromBegin_[INTERACTIVE] = Long.MAX_VALUE; + } + + /** + * Sets the probability for serial jobs + * @param jobType the type of jobs + * @param prob the probability + * @return <tt>true</tt> if the probability has been set, or + * <tt>false</tt> otherwise. + * @see #INTERACTIVE + * @see #BATCH + */ + public boolean setSerialProbability(int jobType, double prob) { + if(jobType > BATCH || jobType < INTERACTIVE) + return false; + + if(useJobType_) + serialProb[jobType] = prob; + else + serialProb[INTERACTIVE] = serialProb[BATCH] = prob; + + return true; + } + + /** + * Sets the probability for power of two jobs + * @param jobType the type of jobs + * @param prob the probability + * @return <tt>true</tt> if the probability has been set, or + * <tt>false</tt> otherwise. + * @see #INTERACTIVE + * @see #BATCH + */ + public boolean setPower2Probability(int jobType, double prob) { + if(jobType > BATCH || jobType < INTERACTIVE) + return false; + + if(useJobType_) + pow2Prob[jobType] = prob; + else + pow2Prob[INTERACTIVE] = pow2Prob[BATCH] = prob; + + return true; + } + + /** + * Sets the parameters for the two-stage-uniform + * which is used to calculate the number of nodes for parallel jobs. + * @param jobType the type of jobs + * @param uLow is the log2 of the minimal size of job in the system (you can add or + * subtract 0.2 to give less/more probability to the minimal size). + * @param uMed should be in [uHi-1.5 , uHi-3.5] + * @param uHi is the log2 of the maximal size of a job in the system (system's size) + * @param uProb should be in [0.7 - 0.95] + * @return <tt>true</tt> if the probabilities have been set, or + * <tt>false</tt> otherwise.b2 + * @see #INTERACTIVE + * @see #BATCH + */ + public boolean setParallelJobProbabilities(int jobType, + double uLow, double uMed, double uHi, double uProb) { + if(jobType > BATCH || jobType < INTERACTIVE) + return false; + else if (uLow > uHi) + return false; + else if (uMed > uHi-1.5 || uMed < uHi-3.5) + return false; + else if(uProb < 0.7 || uProb > 0.95) + return false; + + if(useJobType_) { + this.uLow[jobType] = uLow; + this.uMed[jobType] = uMed; + this.uHi[jobType] = uHi; + this.uProb[jobType] = uProb; + } + else { + this.uLow[INTERACTIVE] = this.uLow[BATCH] = uLow; + this.uMed[INTERACTIVE] = this.uMed[BATCH] = uMed; + this.uHi[INTERACTIVE] = this.uHi[BATCH] = uHi; + this.uProb[INTERACTIVE] = this.uProb[BATCH] = uProb; + } + + return true; + } + + /** Sets the parameters for the running time + * The running time is computed using hyper-gamma distribution. + * The parameters a1,b1,a2,b2 are the parameters of the two gamma distributions + * The p parameter of the hyper-gamma distribution is calculated as a straight + * (linear) line p = pa*nodes + pb. * 'nodes' will be calculated + * in the program, here we defined the 'pa','pb' + * parameters. + * @param a1 hyper-gamma distribution parameter. + * @param a2 hyper-gamma distribution parameter. + * @param b1 hyper-gamma distribution parameter. + * @param b2 hyper-gamma distribution parameter. + * @param pa hyper-gamma distribution parameter. + * @param pb hyper-gamma distribution parameter. + * @return <tt>true</tt> if the parameters have been set, or + * <tt>false</tt> otherwise. + */ + public boolean setRunTimeParameters(int jobType, + double a1, double a2, double b1, double b2, + double pa, double pb) { + if(jobType > BATCH || jobType < INTERACTIVE) + return false; + + if(useJobType_) { + this.a1[jobType] = a1; this.b1[jobType] = b1; + this.a2[jobType] = a2; this.b2[jobType] = b2; + this.pa[jobType] = pa; this.pb[jobType] = pb; + } + else { + this.a1[INTERACTIVE] = this.a1[BATCH] = a1; + this.b1[INTERACTIVE] = this.a1[BATCH] = b1; + this.a2[INTERACTIVE] = this.a1[BATCH] = a2; + this.b2[INTERACTIVE] = this.a1[BATCH] = b2; + this.pa[INTERACTIVE] = this.a1[BATCH] = pa; + this.pb[INTERACTIVE] = this.a1[BATCH] = pb; + } + + return true; + } + + /** + * Sets the parameters for the inter-arrival time + * The inter-arriving time is calculated using two gamma distributions. + * gamma(aarr,barr) represents the inter_arrival time for the rush hours. It is + * independent on the hour the job arrived at. + * The cdf of gamma(bnum,anum) represents the proportion of number of jobs which + * arrived at each time interval (bucket). + * The inter-arrival time is calculated using both gammas + * Since gamma(aarr,barr) represents the arrive-time at the rush time , we use + * a constant ,ARAR (Arrive-Rush-All-Ratio), to set the alpha parameter (the new + * aarr) so it will represent the arrive-time at all hours of the day. + */ + public boolean setInterArrivalTimeParameters(int jobType, + double aarr, double barr, double anum, double bnum, double arar) { + if(jobType > BATCH || jobType < INTERACTIVE) + return false; + + if(useJobType_) { + this.aarr[jobType] = aarr * arar; + this.barr[jobType] = barr; + this.anum[jobType] = anum; + this.bnum[jobType] = bnum; + } + else { + this.aarr[INTERACTIVE] = this.aarr[BATCH] = aarr * arar; + this.barr[INTERACTIVE] = this.barr[BATCH] = barr; + this.anum[INTERACTIVE] = this.barr[BATCH] = anum; + this.bnum[INTERACTIVE] = this.barr[BATCH] = bnum; + } + + return true; + } + + /** + * Sets the maximum number of jobs to be generated by this workload model + * @param numJobs the number of jobs + * @returns <tt>true</tt> if the number of jobs has been set; + * <tt>false</tt> othwerwise. + */ + public boolean setNumJobs(int numJobs) { + if(numJobs < 1) + return false; + + numJobs_ = numJobs; + return true; + } + + /** + * Sets the maximum time duration of the workload. The workload will create + * jobs whose time of submission is less or equals to workloadDuration. + * The workload model will stop when it approaches workloadDuration. + * @param workloadDuration the maximum duration of the workload. + * @return <tt>true</tt> if the duration has been set; + * <tt>false</tt> othwerwise. + */ + public boolean setMaximumWorkloadDuration(double workloadDuration) { + if(workloadDuration <= 0) + return false; + + workloadDuration_ = workloadDuration; + return true; + } + + /** + * Sets a Gridlet file size (in byte) for sending to/from a resource. + * @param size a Gridlet file size (in byte) + * @return <tt>true</tt> if it is successful, <tt>false</tt> otherwise + * @pre size > 0 + * @post $none + */ + public boolean setGridletFileSize(int size) { + if (size < 0) { + return false; + } + + size_ = size; + return true; + } + + /** + * Gets a list of completed Gridlets + * @return a list of Gridlets + * @pre $none + * @post $none + */ + public ArrayList getGridletList() { + return list_; + } + + /** + * Prints the Gridlet objects + * @param history <tt>true</tt> means printing each Gridlet's history, + * <tt>false</tt> otherwise + * @pre $none + * @post $none + */ + public void printGridletList(boolean history) { + String name = super.get_name(); + int size = list_.size(); + Gridlet gridlet; + + String indent = " "; + System.out.println(); + System.out.println("========== OUTPUT for " + name + " =========="); + System.out.println("Gridlet_ID" + indent + "STATUS" + indent + + "Resource_ID" + indent + "Cost"); + + int i = 0; + for (i = 0; i < size; i++) + { + gridlet = (Gridlet) list_.get(i); + System.out.print(indent + gridlet.getGridletID() + indent + + indent); + + // get the status of a Gridlet + System.out.print( gridlet.getGridletStatusString() ); + System.out.println( indent + indent + gridlet.getResourceID() + + indent + indent + gridlet.getProcessingCost() ); + } + + System.out.println(); + if (history == true) + { + // a loop to print each Gridlet's history + System.out.println(); + for (i = 0; i < size; i++) + { + gridlet = (Gridlet) list_.get(i); + System.out.println( gridlet.getGridletHistory() ); + + System.out.print("Gridlet #" + gridlet.getGridletID() ); + System.out.println(", length = " + gridlet.getGridletLength() + + ", finished so far = " + + gridlet.getGridletFinishedSoFar() ); + System.out.println("========================================="); + System.out.println(); + } + } + } + + /** + * Reads from a given file when the simulation starts running. + * Then submits Gridlets to a resource and collects them before exiting. + * To collect the completed Gridlets, use {@link #getGridletList()} + * @pre $none + * @post $none + */ + public void body() { + System.out.println(); + System.out.println(super.get_name() + ".body() :%%%% Start ..."); + + // get the resource id + if (resID_ < 0) + { + System.out.println(super.get_name() + + ".body(): Error - invalid resource name: " + resName_); + return; + } + + boolean success = createGridlets(); + + // if all the gridlets have been submitted + if (success == true) { + collectGridlet(); + } + else { + System.out.println(super.get_name() + + ".body(): Error - unable to parse from a file."); + } + + // shut down all the entities, including GridStatistics entity since + // we used it to record certain events. + shutdownGridStatisticsEntity(); + shutdownUserEntity(); + terminateIOEntities(); + + System.out.println(super.get_name() + ".body() : %%%% Exit ..."); + } + + //////////////////////// PROTECTED METHODS /////////////////////// + + /** + * Collects Gridlets sent and stores them into a list. + * @pre $none + * @post $none + */ + protected void collectGridlet() { + System.out.println(super.get_name() + ": Collecting Gridlets ..."); + list_ = new ArrayList(gridletID_ + 1); + + Object data = null; + Gridlet gl = null; + + int counter = 1; // starts at 1, since gridletID_ starts at 1 too + Sim_event ev = new Sim_event(); + while ( Sim_system.running() ) + { + super.sim_get_next(ev); // get the next available event + data = ev.get_data(); // get the event's data + + // handle ping request + if (ev.get_tag() == GridSimTags.INFOPKT_SUBMIT) + { + processPingRequest(ev); + continue; + } + + // get the Gridlet data + if (data != null && data instanceof Gridlet) { + gl = (Gridlet) data; + list_.add(gl); + counter++; + } + + // if all the Gridlets have been collected + if (counter == gridletID_) { + break; + } + } + } + + /** + * Processes a ping request. + * @param ev a Sim_event object + * @pre ev != null + * @post $none + */ + protected void processPingRequest(Sim_event ev) { + InfoPacket pkt = (InfoPacket) ev.get_data(); + pkt.setTag(GridSimTags.INFOPKT_RETURN); + pkt.setDestID( pkt.getSrcID() ); + + // sends back to the sender + super.send(super.output, GridSimTags.SCHEDULE_NOW, + GridSimTags.INFOPKT_RETURN, + new IO_data(pkt, pkt.getSize(), pkt.getSrcID()) ); + } + + //////////////////////// PRIVATE METHODS /////////////////////// + + /** + * Creates the gridlets according to the workload model and sends them + * to the grid resource entity. + * @return <tt>true</tt> if the gridlets were created successfully or + * <tt>false</tt> otherwise. + */ + private boolean createGridlets() { + + int type = INTERACTIVE; + int nodes; long arrTime; int runTime; + + arrivalInit(aarr, barr, anum, bnum, START, weights); + + for (int i=0; i<numJobs_; i++) { + long[] info = arrive(type, weights, aarr, barr); + type = (int)info[0]; + arrTime = (long)info[1]; + + if(arrTime > workloadDuration_) { + return true; + } + + nodes = calcNumberOfNodes(serialProb[type] , pow2Prob[type], + uLow[type], uMed[type], uHi[type], uProb[type]); + + runTime = (int)timeFromNodes(a1[type], b1[type], a2[type], b2[type], + pa[type], pb[type], nodes); + + submitGridlet(i+1, arrTime, runTime, nodes); + } + + return true; + } + + /*----------------------------------------------------------------------------*/ + /* CALC_NUMBER_OF_NODES (NUMBER OF NODES) */ + /* -------------------------------------------------------------------------- */ + /* + * we distinguish between serial jobs , power2 jobs and other. + * for serial job (with probability SerialProb) the number of nodes is 1 + * for all parallel jobs (both power2 and other jobs) we randomly choose a + * number (called 'par') from two-stage-uniform distribution. + * if the job is a power2 job then we make it an integer (par = round(par)), + * the number of nodes will be 2^par but since it must be an integer we return + * round(pow(2,par)). + * if we made par an integer then 2^par is ,obviously, a power of 2. + */ + private int calcNumberOfNodes(double serialProb, double pow2Prob, double uLow, + double uMed, double uHi, double uProb) { + double u,par; + + u = random_.nextDouble(); + if (u <= serialProb) // serial job + return 1; + par = twoStageUniform(uLow, uMed, uHi, uProb); + if (u <= (serialProb + pow2Prob)) // power of 2 nodes parallel job + par = (int)(par + 0.5); // par = round(par) + + return (int)(Math.pow(2, par) + 0.5); // return round(2^par) + } + + /*----------------------------------------------------------------------------*/ + /* TIMES_FROM_NODES (RUNTIME) */ + /* -------------------------------------------------------------------------- */ + /* + * time_from_nodes returns a value of a random number from hyper_gamma + * distribution. + * The a1,b1,a2,b2 are the parameters of both gammas. + * The 'p' parameter is calculated from the 'nodes' 'pa' and 'pb' arguments + * using the formula: p = pa * nodes + pb. + * we keep 'p' a probability by forcing its value to be in the interval [0,1]. + * if the value that was randomly chosen is too big (larger than + * TOO_MUCH_TIME) then we choose another random value. + */ + private long timeFromNodes(double alpha1, double beta1, + double alpha2, double beta2, + double pa, double pb, int nodes) { + double hg; + double p = pa*nodes + pb; + + if (p>1) + p=1; + else if (p<0) + p=0; + do { + hg = hyperGamma(alpha1 , beta1 , alpha2 , beta2 , p); + } while (hg > TOO_MUCH_TIME); + + return (long)Math.exp(hg); + } + + /* The arrive process. + * 'arrive' returns arrival time (from the beginning of the simulation) of + * the current job. + * The (gamma distribution) parameters 'aarr' and 'barr' represent the + * inter-arrival time at rush hours. + * The (gamma distribution) parameters 'anum' and 'bnum' represent the number + * of jobs arriving at different times of the day. Those parameters fit a day + * that contains the hours [CYCLIC_DAY_START..24+CYCLIC_DAY_START] and are + * cyclically moved back to 0..24 + * 'start' is the starting time (in hours 0-23) of the simulation. + * If the inter-arrival time randomly chosen is too big (larger than + * TOO_MUCH_ARRIVE_TIME) then another value is chosen. + * + * The algorithm (briefly): + * A. Preparations (calculated only once in 'arrive_init()': + * 1. foreach time interval (bucket) calculate its proportion of the number + * of arriving jobs (using 'anum' and 'bnum'). This value will be the + * bucket's points. + * 2. calculate the mean number of points in a bucket () + * 3. divide the points in each bucket by the points mean ("normalize" the + * points in all buckets) + * B. randomly choosing a new arrival time for a job: + * 1. get a random value from distribution gamma(aarr , barr). + * 2. calculate the points we have. + * 3. accumulate inter-arrival time by passing buckets (while paying them + * points for that) until we do not have enough points. + * 4. handle reminders - add the new reminder and subtract the old reminder. + * 5. update the time variables ('current' and 'time_from_begin') + */ + private void arrivalInit(double[] aarr, double[] barr, + double[] anum, double[] bnum, int start_hour, double weights[][]) { + + int idx, moveto = CYCLIC_DAY_START; + double[] mean = new double[] {0,0}; + + for(int i=0; i<weights.length; i++) + for(int j=0; j<weights[i].length; j++) + weights[i][j] = 0; + + current_[BATCH] = current_[INTERACTIVE] = start_hour * BUCKETS / HOURS_IN_DAY; + + /* + * for both batch and interactive calculate the propotion of each bucket , + * and their mean */ + for (int j=0 ; j<=1 ; j++) { + for (int i=moveto ; i<BUCKETS+moveto ; i++) { + idx = (i-1)%BUCKETS; /* i-1 since array indices are 0..47 and not 1..48 */ + weights[j][idx] = + gamcdf(i+0.5, anum[j], bnum[j]) - gamcdf(i-0.5, anum[j],bnum[j]); + mean[j] += weights[j][idx]; + } + mean[j] /= BUCKETS; + } + + /* normalize it so we associates between seconds and points correctly */ + for (int j=0 ; j<=1 ; j++) + for (int i=0 ; i<BUCKETS ; i++) + weights[j][i] /= mean[j]; + + calcNextArrival(BATCH ,weights,aarr,barr); + calcNextArrival(INTERACTIVE,weights,aarr,barr); + } + + /* + * 'calcNextArrival' calculates the next inter-arrival time according + * to the current time of the day. + * 'type' is the type of the next job -- interactive or batch + * alpha and barr are the parameters of the gamma distribution of the + * inter-arrival time. + * NOTE: this function changes the global variables concerning the arrival time. + */ + private void calcNextArrival(int type, double[][] weights, + double[] aarr, double[] barr) { + + double[] points = new double []{0,0}; + double[] reminder = new double[]{0,0}; + int bucket; + double gam, nextArrival, newReminder, moreTime; + + bucket = current_[type]; // the bucket of the current time + do { // randomly choose a (not too big) number from gamma distribution + gam = gamrnd(aarr[type],barr[type]); + } while (gam > TOO_MUCH_ARRIVE_TIME); + + points[type] += (Math.exp(gam) / SECONDS_IN_BUCKET); // number of points + nextArrival = 0; + while (points[type] > weights[type][bucket]) { // while have more points + points[type] -= weights[type][bucket]; // pay points to this bucket + bucket = (bucket+1) % 48; // ... and goto the next bucket + nextArrival += SECONDS_IN_BUCKET; // accumulate time in next_arrive + } + + newReminder = points[type]/weights[type][bucket]; + moreTime = SECONDS_IN_BUCKET * ( newReminder - reminder[type]); + nextArrival += moreTime; // add reminders + reminder[type] = newReminder; // save it for next call + + // update the attributes + timeFromBegin_[type] += nextArrival; + current_[type] = bucket; + } + + /*----------------------------------------------------------------------------*/ + /* ARRIVE (ARRIVAL TIME AND TYPE) */ + /*----------------------------------------------------------------------------*/ + /* + * return the time for next job to arrive the system. + * returns also the type of the next job , which is the type that its + * next arrive time (time_from_begin) is closer to the start (smaller). + * notice that since calc_next_arrive changes time_from_begin[] we must save + * the time_from_begin in 'res' so we would be able to return it. + */ + private long[] arrive(int type, double[][] weights, double[] aarr, double[] barr) { + long res; + + type = (timeFromBegin_[BATCH] < timeFromBegin_[INTERACTIVE]) ? BATCH : INTERACTIVE; + res = timeFromBegin_[type]; // save the job's arrival time + + // randomly choose the next job's (of the same type) arrival time + calcNextArrival(type, weights, aarr, barr); + return new long[] {type, res}; + } + + /** + * Creates a Gridlet with the given information, then submit it to a + * resource + * @param id a Gridlet ID + * @param submitTime Gridlet's submit time + * @param runTime Gridlet's run time + * @param numProc number of processors + * @pre id >= 0 + * @pre submitTime >= 0 + * @pre runTime >= 0 + * @pre numProc > 0 + * @post $none + */ + protected void submitGridlet(int id, long submitTime, int runTime, int numProc) + { + // create the gridlet + int len = runTime * rating_; // calculate a job length for each PE + Gridlet gl = new Gridlet(id, len, size_, size_, GridSim.isTraceEnabled()); + gl.setUserID( super.get_id() ); // set the owner ID + gl.setNumPE(numProc); // set the requested num of proc + + // printing to inform user + if (gridletID_ == 1 || gridletID_ % INTERVAL == 0) + { + System.out.println(super.get_name() + ": Submitting Gridlets to " + + resName_ + " ..."); + } + + // check the submit time + if (submitTime < 0) { + submitTime = 0; + } + + gridletID_++; // increment the counter + + // submit a gridlet to resource + super.send(super.output, submitTime, GridSimTags.GRIDLET_SUBMIT, + new IO_data(gl, gl.getGridletFileSize(), resID_) ); + } + + + // --- Methods required by the distributions used by the workload model --- + + /* + * hyper_gamma returns a value of a random variable of mixture of two + * gammas. its parameters are those of the two gammas: a1,b1,a2,b2 and the + * relation between the gammas (p = the probability of the first gamma). we + * first randomly decide which gamma will be active ((a1,b1) or (a2,b2)). + * then we randomly choose a number from the chosen gamma distribution. + */ + double hyperGamma(double a1, double b1, double a2, double b2, double p) { + double a, b, hg, u = random_.nextDouble(); + + if (u <= p) { /* gamma(a1,b1) */ + a = a1; + b = b1; + } else { /* gamma(a2,b2) */ + a = a2; + b = b2; + } + + /* generate a value of a random variable from distribution gamma(a,b) */ + hg = gamrnd(a, b); + return hg; + } + + /* + * gamrnd returns a value of a random variable of gamma(alpha,beta). + * gamma(alpha,beta) = gamma(int(alpha),beta) + + * gamma(alpha-int(alpha),beta). This function and the following 3 functions + * were written according to Jain Raj, 'THE ART OF COMPUTER SYSTEMS + * PERFORMANCE ANALYSIS Techniques for Experimental Design, Measurement, + * Simulation, and Modeling'. Jhon Wiley & Sons , Inc. 1991. Chapter 28 - + * RANDOM-VARIATE GENERATION (pages 484,485,490,491) + * can be improved by getting 'diff' and 'intalpha' as function's parameters + */ + + private double gamrnd(double alpha, double beta) { + double diff, gam = 0; + long intalpha = (long) alpha; + if (alpha >= 1) + gam += gamrndIntAlpha(intalpha, beta); + if ((diff = alpha - intalpha) > 0) + gam += gamrndAlphaSmaller1(diff, beta); + return gam; + } + + /* + * gamrnd_int_alpha returns a value of a random variable of gamma(n,beta) + * distribution where n is integer(unsigned long actually). gamma(n,beta) == + * beta*gamma(n,1) == beta* sum(1..n){gamma(1,1)} == beta* sum(1..n){exp(1)} == + * beta* sum(1..n){-ln(uniform(0,1))} + */ + private double gamrndIntAlpha(long n, double beta) { + double acc = 0; + for (int i = 0; i < n; i++) + acc += Math.log(random_.nextDouble()); /* sum the exponential + * random variables + */ + return (-acc * beta); + } + + /* + * gamrnd_alpha_smaller_1 returns a value of a random variable of + * gamma(alpha,beta) where alpha is smaller than 1. This is done using the + * Beta distribution. (alpha<1) ==> (1-alpha<1) ==> we can use + * beta_less_1(alpha,1-alpha) gamma(alpha,beta) = exponential(beta) * + * Beta(alpha,1-alpha) + */ + private double gamrndAlphaSmaller1(double alpha, double beta) { + double x = betarndLess1(alpha, 1 - alpha); /* beta random variable */ + double y = -Math.log(random_.nextDouble()); /* exponential random + * variable */ + return (beta * x * y); + } + + /* + * betarnd_less_1 returns a value of a random variable of beta(alpha,beta) + * distribution where both alpha and beta are smaller than 1 (and larger + * than 0) + */ + private double betarndLess1(double alpha, double beta) { + double x, y, u1, u2; + do { + u1 = random_.nextDouble(); + u2 = random_.nextDouble(); + x = Math.pow(u1, 1 / alpha); + y = Math.pow(u2, 1 / beta); + } while (x + y > 1); + return (x / (x + y)); + } + + /* + * Returns the cumulative distribution function of gamma(alpha, beta) + * distribution at the point 'x'; return -1 if an error (non-convergence) + * occurs. + * This function and the following two functions were written + * according to William H. Press , Brian P. Flannery , Saul A. Teukolsky and + * William T. Vetterling. NUMERICAL RECIPES IN PASCAL The Art of Scientific + * Computing. Cambridge University Press 1989 Chapter 6 - Special Functions + * (pages 180-183). + */ + private double gamcdf(double x, double alpha, double beta) { + x /= beta; + if (x < (alpha + 1)) { + return gser(x, alpha); + } + + /* x >= a+1 */ + r... [truncated message content] |
From: <mar...@us...> - 2008-01-29 03:58:02
|
Revision: 84 http://gridsim.svn.sourceforge.net/gridsim/?rev=84&view=rev Author: marcos_dias Date: 2008-01-28 19:58:08 -0800 (Mon, 28 Jan 2008) Log Message: ----------- This commit fixes a bug in GridSim, which allowed a simulation to run out of memory due to excessive trace even when the user chose not to record any statistics. Modified Paths: -------------- branches/gridsim4.0-branch3/source/gridsim/GridSim.java branches/gridsim4.0-branch3/source/gridsim/util/Workload.java Modified: branches/gridsim4.0-branch3/source/gridsim/GridSim.java =================================================================== --- branches/gridsim4.0-branch3/source/gridsim/GridSim.java 2008-01-15 03:33:59 UTC (rev 83) +++ branches/gridsim4.0-branch3/source/gridsim/GridSim.java 2008-01-29 03:58:08 UTC (rev 84) @@ -123,6 +123,7 @@ private static Calendar calendar_ = null; // a Calendar object private static GridInformationService gis_ = null; // a GIS object private final static int NOT_FOUND = -1; // a constant + private static boolean traceFlag_; //////////////////////////////////////////////////////////////////////// @@ -701,6 +702,8 @@ if (cal == null) { calendar_ = Calendar.getInstance(); } + + traceFlag_ = traceFlag; SimulationStartDate = calendar_.getTime(); rand = new GridSimRandom(); @@ -2126,6 +2129,15 @@ } /** + * Checks whether simulation's statistics of other log should be created + * @return <tt>true</tt> if the information should be logged + * or <tt>false</tt> otherwise. + */ + public static boolean isTraceEnabled() { + return traceFlag_; + } + + /** * Gets the total number of PEs (Processing Elements) from a resource * @param resourceID a resource ID * @return total number of PE or <tt>-1</tt> if invalid resource ID Modified: branches/gridsim4.0-branch3/source/gridsim/util/Workload.java =================================================================== --- branches/gridsim4.0-branch3/source/gridsim/util/Workload.java 2008-01-15 03:33:59 UTC (rev 83) +++ branches/gridsim4.0-branch3/source/gridsim/util/Workload.java 2008-01-29 03:58:08 UTC (rev 84) @@ -737,7 +737,7 @@ { // create the gridlet int len = runTime * rating_; // calculate a job length for each PE - Gridlet gl = new Gridlet(id, len, size_, size_); + Gridlet gl = new Gridlet(id, len, size_, size_, GridSim.isTraceEnabled()); gl.setUserID( super.get_id() ); // set the owner ID gl.setNumPE(numProc); // set the requested num of proc This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mar...@us...> - 2008-01-15 03:33:56
|
Revision: 83 http://gridsim.svn.sourceforge.net/gridsim/?rev=83&view=rev Author: marcos_dias Date: 2008-01-14 19:33:59 -0800 (Mon, 14 Jan 2008) Log Message: ----------- Bug fix: + Gridlet history is created regardless the value of traceFlag Modified Paths: -------------- trunk/source/gridsim/GridSim.java trunk/source/gridsim/util/Workload.java Modified: trunk/source/gridsim/GridSim.java =================================================================== --- trunk/source/gridsim/GridSim.java 2007-12-16 23:08:32 UTC (rev 82) +++ trunk/source/gridsim/GridSim.java 2008-01-15 03:33:59 UTC (rev 83) @@ -103,6 +103,7 @@ private static Calendar calendar_ = null; // a Calendar object private static GridInformationService gis_ = null; // a GIS object private final static int NOT_FOUND = -1; // a constant + private static boolean traceFlag_; //////////////////////////////////////////////////////////////////////// @@ -542,6 +543,8 @@ Sim_system.initialise(); Sim_system.set_trc_level(1); Sim_system.set_auto_trace(traceFlag); + + traceFlag_ = traceFlag; // Set the current Wall clock time as the starting time of simulation calendar_ = cal; @@ -2131,6 +2134,15 @@ return GridSim.isResourceExist(id); } + + /** + * Checks whether simulation's statistics of other log should be created + * @return <tt>true</tt> if the information should be logged + * or <tt>false</tt> otherwise. + */ + public static boolean isTraceEnabled() { + return traceFlag_; + } /** * Gets the total number of PEs (Processing Elements) from a resource Modified: trunk/source/gridsim/util/Workload.java =================================================================== --- trunk/source/gridsim/util/Workload.java 2007-12-16 23:08:32 UTC (rev 82) +++ trunk/source/gridsim/util/Workload.java 2008-01-15 03:33:59 UTC (rev 83) @@ -738,7 +738,7 @@ { // create the gridlet int len = runTime * rating_; // calculate a job length for each PE - Gridlet gl = new Gridlet(id, len, size_, size_); + Gridlet gl = new Gridlet(id, len, size_, size_, GridSim.isTraceEnabled()); gl.setUserID( super.get_id() ); // set the owner ID gl.setNumPE(numProc); // set the requested num of proc This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mar...@us...> - 2007-12-16 23:08:29
|
Revision: 82 http://gridsim.svn.sourceforge.net/gridsim/?rev=82&view=rev Author: marcos_dias Date: 2007-12-16 15:08:32 -0800 (Sun, 16 Dec 2007) Log Message: ----------- This update contains an additional resource allocation policy that supports parallel jobs with aggressive (EASY) backfilling. Due to the inclusion of this policy, a few other classes have been updated as well. Added Paths: ----------- branches/gridsim4.0-branch3/build.xml branches/gridsim4.0-branch3/examples/examples/WorkloadWithCancellation.java branches/gridsim4.0-branch3/examples/examples/WorkloadWithReservation.java branches/gridsim4.0-branch3/examples/examples/ar/ARTest.java branches/gridsim4.0-branch3/examples/examples/ar/SimpleARExample01.java branches/gridsim4.0-branch3/examples/examples/workload/ar/TurboARExample01.java branches/gridsim4.0-branch3/examples/examples/workload/ar/TurboARExample02.java branches/gridsim4.0-branch3/examples/examples/workload/ar/TurboARExample03.java branches/gridsim4.0-branch3/examples/examples/workload/ar/TurboARExampleWithCancellation01.java branches/gridsim4.0-branch3/examples/examples/workload/parallel/TurboExample01.java branches/gridsim4.0-branch3/examples/examples/workload/parallel/TurboExampleEasy01.java branches/gridsim4.0-branch3/examples/examples/workload/parallel/TurboExampleWithCancellation01.java branches/gridsim4.0-branch3/source/eduni/simjava/Evqueue.java branches/gridsim4.0-branch3/source/eduni/simjava/Semaphore.java branches/gridsim4.0-branch3/source/eduni/simjava/Sim_any_p.java branches/gridsim4.0-branch3/source/eduni/simjava/Sim_entity.java branches/gridsim4.0-branch3/source/eduni/simjava/Sim_event.java branches/gridsim4.0-branch3/source/eduni/simjava/Sim_exception.java branches/gridsim4.0-branch3/source/eduni/simjava/Sim_from_p.java branches/gridsim4.0-branch3/source/eduni/simjava/Sim_none_p.java branches/gridsim4.0-branch3/source/eduni/simjava/Sim_not_from_p.java branches/gridsim4.0-branch3/source/eduni/simjava/Sim_not_type_p.java branches/gridsim4.0-branch3/source/eduni/simjava/Sim_outfile.java branches/gridsim4.0-branch3/source/eduni/simjava/Sim_output.java branches/gridsim4.0-branch3/source/eduni/simjava/Sim_port.java branches/gridsim4.0-branch3/source/eduni/simjava/Sim_predicate.java branches/gridsim4.0-branch3/source/eduni/simjava/Sim_system.java branches/gridsim4.0-branch3/source/eduni/simjava/Sim_type_p.java branches/gridsim4.0-branch3/source/gridsim/ARGridResource.java branches/gridsim4.0-branch3/source/gridsim/ARObject.java branches/gridsim4.0-branch3/source/gridsim/ARPolicy.java branches/gridsim4.0-branch3/source/gridsim/ARSimpleSpaceShared.java branches/gridsim4.0-branch3/source/gridsim/Accumulator.java branches/gridsim4.0-branch3/source/gridsim/AdvanceReservation.java branches/gridsim4.0-branch3/source/gridsim/AllocPolicy.java branches/gridsim4.0-branch3/source/gridsim/GridInformationService.java branches/gridsim4.0-branch3/source/gridsim/GridResource.java branches/gridsim4.0-branch3/source/gridsim/GridSim.java branches/gridsim4.0-branch3/source/gridsim/GridSimCore.java branches/gridsim4.0-branch3/source/gridsim/GridSimRandom.java branches/gridsim4.0-branch3/source/gridsim/GridSimShutdown.java branches/gridsim4.0-branch3/source/gridsim/GridSimStandardPE.java branches/gridsim4.0-branch3/source/gridsim/GridSimTags.java branches/gridsim4.0-branch3/source/gridsim/GridStatistics.java branches/gridsim4.0-branch3/source/gridsim/GridUser.java branches/gridsim4.0-branch3/source/gridsim/Gridlet.java branches/gridsim4.0-branch3/source/gridsim/GridletList.java branches/gridsim4.0-branch3/source/gridsim/IO_data.java branches/gridsim4.0-branch3/source/gridsim/Machine.java branches/gridsim4.0-branch3/source/gridsim/MachineList.java branches/gridsim4.0-branch3/source/gridsim/ParameterException.java branches/gridsim4.0-branch3/source/gridsim/ResGridlet.java branches/gridsim4.0-branch3/source/gridsim/ResGridletList.java branches/gridsim4.0-branch3/source/gridsim/ResourceCalendar.java branches/gridsim4.0-branch3/source/gridsim/ResourceCharacteristics.java branches/gridsim4.0-branch3/source/gridsim/ResourceUserList.java branches/gridsim4.0-branch3/source/gridsim/Sim_from_port.java branches/gridsim4.0-branch3/source/gridsim/SpaceShared.java branches/gridsim4.0-branch3/source/gridsim/Stat.java branches/gridsim4.0-branch3/source/gridsim/TimeShared.java branches/gridsim4.0-branch3/source/gridsim/gui/AllocationAction.java branches/gridsim4.0-branch3/source/gridsim/gui/AllocationListener.java branches/gridsim4.0-branch3/source/gridsim/gui/DefaultGridSimVisualizer.java branches/gridsim4.0-branch3/source/gridsim/gui/GUISettings.java branches/gridsim4.0-branch3/source/gridsim/gui/GridSimVisualizer.java branches/gridsim4.0-branch3/source/gridsim/gui/ResourceWindow.java branches/gridsim4.0-branch3/source/gridsim/turbo/ARMessage.java branches/gridsim4.0-branch3/source/gridsim/turbo/ARParallelSpaceShared.java branches/gridsim4.0-branch3/source/gridsim/turbo/ARTGridResource.java branches/gridsim4.0-branch3/source/gridsim/turbo/ARTPolicy.java branches/gridsim4.0-branch3/source/gridsim/turbo/AvailabilityInfo.java branches/gridsim4.0-branch3/source/gridsim/turbo/AvailabilityInfoEntry.java branches/gridsim4.0-branch3/source/gridsim/turbo/AvailabilityProfile.java branches/gridsim4.0-branch3/source/gridsim/turbo/AvailabilityProfileEntry.java branches/gridsim4.0-branch3/source/gridsim/turbo/CBParallelSpaceShared.java branches/gridsim4.0-branch3/source/gridsim/turbo/EBParallelSpaceShared.java branches/gridsim4.0-branch3/source/gridsim/turbo/FilterARMessage.java branches/gridsim4.0-branch3/source/gridsim/turbo/OrderGridletByStartTime.java branches/gridsim4.0-branch3/source/gridsim/turbo/PERange.java branches/gridsim4.0-branch3/source/gridsim/turbo/PERangeList.java branches/gridsim4.0-branch3/source/gridsim/turbo/Reservation.java branches/gridsim4.0-branch3/source/gridsim/turbo/ReservationRequester.java branches/gridsim4.0-branch3/source/gridsim/turbo/SSGridlet.java branches/gridsim4.0-branch3/source/gridsim/turbo/SSReservation.java branches/gridsim4.0-branch3/source/gridsim/turbo/ScheduleItem.java branches/gridsim4.0-branch3/source/gridsim/turbo/TAllocPolicy.java branches/gridsim4.0-branch3/source/gridsim/turbo/TResourceCharacteristics.java branches/gridsim4.0-branch3/workloads/sdsc_blue_2000_01.txt branches/gridsim4.0-branch3/workloads/sdsc_blue_2000_02.txt branches/gridsim4.0-branch3/workloads/sdsc_blue_2000_03.txt Removed Paths: ------------- branches/gridsim4.0-branch3/workloads/sdsc_blue_2000.swf Added: branches/gridsim4.0-branch3/build.xml =================================================================== --- branches/gridsim4.0-branch3/build.xml (rev 0) +++ branches/gridsim4.0-branch3/build.xml 2007-12-16 23:08:32 UTC (rev 82) @@ -0,0 +1,63 @@ +<?xml version="1.0"?> + +<!-- September 2004 +Build file or Makefile for GridSim. +NOTE: Make sure you have installed 'ant' and put the location of it into + your path so you can access it anywhere. + 'ant' can be downloadable from http://ant.apache.org/ + +Usage: +* type 'ant' to compile all gridsim source files and put them into + classes/ directory +* type 'ant makejar' to compile the source files (if necessary) and to create + a jar file into jar/ directory + +NOTE: rule for javadoc is not included yet. Use javadoc.sh script instead under + Unix/Linux environment. + +Acknowledgement: Thank to Uros Cibej for providing this file and instruction on + how to use it. +--> + + +<project name="GridSim" basedir="." default="build"> + <description> + This is the build file for GridSim + </description> + + <!-- gridsim version id --> + <property name="version" value="turbo01"/> + + <!-- location to store Java classes --> + <property name="class.dir" location="./classes" /> + + <!-- location to store GridSim source files --> + <property name="src.dir" location="./source" /> + + <!-- location to store jar files --> + <property name="jar.dir" location="./jars" /> + + <!-- location to store Javadoc files --> + <property name="doc.dir" location="./doc" /> + + <target name="prepare"> + <mkdir dir="${class.dir}" /> + </target> + + <!-- rule to compile GridSim source files --> + <target name="build" depends="prepare"> + <javac srcdir="${src.dir}" destdir="${class.dir}" classpath="." /> + </target> + + <!-- rule for making a jar file. + NOTE: + * The new jar file is named as "gridsim_VERSION.jar". + --> + <target name="makejar" depends="build"> + <echo>Compiling a new jar file, named: "gridsim_${version}.jar".</echo> + <jar destfile="${jar.dir}/gridsim_${version}.jar" basedir="${class.dir}" /> + </target> + +</project> + + Added: branches/gridsim4.0-branch3/examples/examples/WorkloadWithCancellation.java =================================================================== --- branches/gridsim4.0-branch3/examples/examples/WorkloadWithCancellation.java (rev 0) +++ branches/gridsim4.0-branch3/examples/examples/WorkloadWithCancellation.java 2007-12-16 23:08:32 UTC (rev 82) @@ -0,0 +1,250 @@ +/* Title: GridSim Toolkit + * Description: GridSim (Grid Simulation) Toolkit for Modeling and Simulation + * of Parallel and Distributed Systems such as Clusters and Grids + * Licence: GPL - http://www.gnu.org/copyleft/gpl.html + */ + +package examples; + +import eduni.simjava.Sim_event; +import eduni.simjava.Sim_system; +import gridsim.GridSimTags; +import gridsim.Gridlet; +import gridsim.IO_data; +import gridsim.ParameterException; +import gridsim.net.Link; +import gridsim.util.Workload; + +import java.util.ArrayList; + +/** + * This class is an extended version of {@link Workload}. This class + * cancels some gridlets submitted. + * + * @author Marcos Dias de Assuncao + * @since GridSim Turbo Alpha 0.1 + * + * @see Workload + */ +public class WorkloadWithCancellation extends Workload { + private final int NUM_GRIDLETS_BETWEEN_CANCELLATIONS = 50; + // value of 1, means that the cancellation will be sent + // at the gridlet's submission time + (gridlet duration * 1) + private final double TIME_CANCELLATION = 0.5; + + /** + * Create a new {@link WorkloadWithCancellation} object <b>without</b> using + * the network extension. This means this entity directly sends Gridlets + * to a resource destination without going through a wired network. <br> + * <tt>NOTE:</tt> + * You can not use this constructor in an experiment that uses a wired + * network topology. + * + * @param name this entity name + * @param fileName the workload trace filename in one of the following + * format: <i>ASCII text, zip, gz.</i> + * @param resourceName the resource name + * @param rating the resource's PE rating + * @throws Exception This happens when creating this entity before + * initialising GridSim package or this entity name is + * <tt>null</tt> or empty + * @throws ParameterException This happens for the following conditions: + * <ul> + * <li>the entity name is null or empty + * <li>the workload trace file name is null or empty + * <li>the resource entity name is null or empty + * <li>the resource PE rating <= 0 + * </ul> + * @pre name != null + * @pre fileName != null + * @pre resourceName != null + * @pre rating > 0 + * @post $none + */ + public WorkloadWithCancellation(String name, String fileName, String resourceName, + int rating) throws ParameterException, Exception { + + super(name, fileName, resourceName, rating); + } + + /** + * Create a new {@link WorkloadWithCancellation} object <b>with</b> the network extension. + * This means this entity directly sends Gridlets to a destination resource + * through a link. The link is automatically created by this constructor. + * + * @param name this entity name + * @param baudRate baud rate of this link (bits/s) + * @param propDelay Propagation delay of the Link in milliseconds + * @param MTU Maximum Transmission Unit of the Link in bytes. + * Packets which are larger than the MTU should be split + * up into MTU size units. + * For example, a 1024 byte packet trying to cross a 576 + * byte MTU link should get split into 2 packets of 576 + * bytes and 448 bytes. + * @param fileName the workload trace filename in one of the following + * format: <i>ASCII text, zip, gz.</i> + * @param resourceName the resource name + * @param rating the resource's PE rating + * @throws Exception This happens when creating this entity before + * initialising GridSim package or this entity name is + * <tt>null</tt> or empty + * @throws ParameterException This happens for the following conditions: + * <ul> + * <li>the entity name is null or empty + * <li> baudRate <= 0 + * <li> propDelay <= 0 + * <li> MTU <= 0 + * <li>the workload trace file name is null or empty + * <li>the resource entity name is null or empty + * <li>the resource PE rating <= 0 + * </ul> + * @pre name != null + * @pre baudRate > 0 + * @pre propDelay > 0 + * @pre MTU > 0 + * @pre fileName != null + * @pre resourceName != null + * @pre rating > 0 + * @post $none + */ + public WorkloadWithCancellation(String name, double baudRate, double propDelay, int MTU, + String fileName, String resourceName, int rating) + throws ParameterException, Exception { + + super( name, baudRate, propDelay, MTU, fileName, resourceName, rating ); + } + + /** + * Create a new Workload object <b>with</b> the network extension. + * This means this entity directly sends Gridlets to a destination resource + * through a link. The link is automatically created by this constructor. + * + * @param name this entity name + * @param link the link that will be used to connect this Workload + * to another entity or a Router. + * @param fileName the workload trace filename in one of the following + * format: <i>ASCII text, zip, gz.</i> + * @param resourceName the resource name + * @param rating the resource's PE rating + * @throws Exception This happens when creating this entity before + * initialising GridSim package or this entity name is + * <tt>null</tt> or empty + * @throws ParameterException This happens for the following conditions: + * <ul> + * <li>the entity name is null or empty + * <li>the link is empty + * <li>the workload trace file name is null or empty + * <li>the resource entity name is null or empty + * <li>the resource PE rating <= 0 + * </ul> + * @pre name != null + * @pre link != null + * @pre fileName != null + * @pre resourceName != null + * @pre rating > 0 + * @post $none + */ + public WorkloadWithCancellation(String name, Link link, String fileName, + String resourceName, int rating) + throws ParameterException, Exception { + + super(name, link, fileName, resourceName, rating); + } + + //////////////////////// PRIVATE METHODS /////////////////////// + + /** + * Collects Gridlets sent and stores them into a list. + * @pre $none + * @post $none + */ + protected void collectGridlet() { + System.out.println(super.get_name() + ": Collecting Gridlets ..."); + list_ = new ArrayList(gridletID_ + 1); + + Object data = null; + Gridlet gl = null; + + int counter = 1; // starts at 1, since gridletID_ starts at 1 too + Sim_event ev = new Sim_event(); + while ( Sim_system.running() ) { + + super.sim_get_next(ev); // get the next available event + data = ev.get_data(); // get the event's data + + // handle ping request + if (ev.get_tag() == GridSimTags.INFOPKT_SUBMIT) { + processPingRequest(ev); + continue; + } + + // get the Gridlet data + if (data != null && data instanceof Gridlet) { + gl = (Gridlet) data; + +// if(gl.getGridletStatus() == Gridlet.FAILED) +// System.out.println("Gridlet failed"); +// +// if(gl.getGridletStatus() == Gridlet.CANCELED) +// System.out.println("Gridlet cancelled"); + + list_.add(gl); + counter++; + } + + // if all the Gridlets have been collected + if (counter == gridletID_) { + break; + } + } + } + + /** + * Creates a Gridlet with the given information, then submit it to a + * resource + * @param id a Gridlet ID + * @param submitTime Gridlet's submit time + * @param runTime Gridlet's run time + * @param numProc number of processors + * @pre id >= 0 + * @pre submitTime >= 0 + * @pre runTime >= 0 + * @pre numProc > 0 + * @post $none + */ + protected void submitGridlet(int id, long submitTime, int runTime, int numProc) { + + // create the gridlet + int len = runTime * rating_; // calculate a job length for each PE + Gridlet gl = new Gridlet(id, len, size_, size_); + gl.setUserID( super.get_id() ); // set the owner ID + gl.setNumPE(numProc); // set the requested num of proc + + // printing to inform user + if (gridletID_ == 1 || gridletID_ % INTERVAL == 0) { + System.out.println(super.get_name() + ": Submitting Gridlets to " + + resName_ + " ..."); + } + + // check the submit time + if (submitTime < 0) { + submitTime = 0; + } + + gridletID_++; // increment the counter + + // submit a gridlet to resource + super.send(super.output, submitTime, GridSimTags.GRIDLET_SUBMIT, + new IO_data(gl, gl.getGridletFileSize(), resID_) ); + + // check whether a cancellation has to be scheduled or not + int result = gridletID_ % NUM_GRIDLETS_BETWEEN_CANCELLATIONS; + if(result == 0) { + super.send(super.output, (submitTime + (TIME_CANCELLATION * runTime)), GridSimTags.GRIDLET_CANCEL, + new IO_data(gl, 0, resID_) ); + gridletID_++; + } + } + +} // end class + Added: branches/gridsim4.0-branch3/examples/examples/WorkloadWithReservation.java =================================================================== --- branches/gridsim4.0-branch3/examples/examples/WorkloadWithReservation.java (rev 0) +++ branches/gridsim4.0-branch3/examples/examples/WorkloadWithReservation.java 2007-12-16 23:08:32 UTC (rev 82) @@ -0,0 +1,1077 @@ +/* + * Title: GridSim Toolkit + * Description: GridSim (Grid Simulation) Toolkit for Modeling and Simulation + * of Parallel and Distributed Systems such as Clusters and Grids + * Licence: GPL - http://www.gnu.org/copyleft/gpl.html + * + */ + +package examples; + +import java.io.BufferedReader; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Enumeration; +import java.util.Random; +import java.util.zip.GZIPInputStream; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; + +import eduni.simjava.Sim_event; +import eduni.simjava.Sim_system; + +import gridsim.GridSim; +import gridsim.GridSimTags; +import gridsim.Gridlet; +import gridsim.IO_data; +import gridsim.ParameterException; +import gridsim.net.InfoPacket; +import gridsim.net.Link; +import gridsim.net.SimpleLink; +import gridsim.turbo.Reservation; +import gridsim.turbo.ReservationRequester; + +/** + * The main purpose of this class is to create a realistic simulation + * environment where your jobs or Gridlets are competing with others. + * In other words, the grid resource might not be available at certain times. + * In addition, the arrival time of jobs are also captured in the trace file. + * <p> + * This workload class has been modified to simulate advance reservations. + * Some parameters where included to indicate the frequency in which + * advance reservations are made. Additionally, it is possible to specify how + * long in advance the advance reservations are made. + * <p> + * This class is responsible for reading resource traces from a file and + * sends Gridlets to only <tt>one</tt> destinated resource. <br> + * <b>NOTE:</b> + * <ul> + * <li> This class can only take <tt>one</tt> trace file of the following + * format: <i>ASCII text, zip, gz.</i> + * <li> This class can be classified as <b>one grid user entity</b>. + * Hence, you need to incorporate this entity into <tt>numUser</tt> + * during {@link gridsim.GridSim#init(int, Calendar, boolean)} + * <li> If you need to use multiple trace files to submit Gridlets to + * same or different resources, then you need to create multiple + * instances of this class <tt>each with a unique entity name</tt>. + * <li> If size of the trace file is huge or contains lots of traces + * please increase the JVM heap size accordingly by using + * <tt>java -Xmx</tt> option when running the simulation. + * <li> If you are running an experiment using the network extension, + * i.e. the gridsim.net package, then you need to use + * {@link #Workload(String, double, double, int, String, String, int)} + * instead. + * <li> The default job file size for sending to and receiving from + * a resource is {@link gridsim.net.Link#DEFAULT_MTU}. + * However, you can specify + * the file size by using {@link #setGridletFileSize(int)}. + * <li> A job run time is only for 1 PE <tt>not</tt> the total number of + * allocated PEs. + * Therefore, a Gridlet length is also calculated for 1 PE.<br> + * For example, job #1 in the trace has a run time of 100 seconds + * for 2 processors. This means each processor runs + * job #1 for 100 seconds, if the processors have the same + * specification. + * </ul> + * <p> + * By default, this class follows the standard workload format as specified + * in <a href="http://www.cs.huji.ac.il/labs/parallel/workload/"> + * http://www.cs.huji.ac.il/labs/parallel/workload/</a> <br> + * However, you can use other format by calling the below methods before + * running the simulation: + * <ul> + * <li> {@link #setComment(String)} + * <li> {@link #setField(int, int, int, int, int)} + * </ul> + * + * @see gridsim.GridSim#init(int, Calendar, boolean) + * @author Marcos Dias de Assuncao (the most of the code came + * from {@link Workload} class) + * @since GridSim Turbo Alpha 0.1 + * @invariant $none + */ + +public class WorkloadWithReservation extends ReservationRequester { + + protected String fileName_; // file name + protected String resName_; // resource name + protected int resID_; // resource ID + protected int rating_; // a PE rating + protected int gridletID_; // gridletID + protected int size_; // job size for sending it through a network + protected ArrayList list_; // a list for getting all the Gridlets + + // constant + private int JOB_NUM; // job number + private int SUBMIT_TIME; // submit time of a Gridlet + private int RUN_TIME; // running time of a Gridlet + private int NUM_PROC; // number of processors needed for a Gridlet + private int REQ_NUM_PROC; // required number of processors + private int REQ_RUN_TIME; // required running time + private int MAX_FIELD; // max number of field in the trace file + private String COMMENT; // a string that denotes the start of a comment + private final int IRRELEVANT = -1; // irrelevant number + protected final int INTERVAL = 10; // number of intervals + private String[] fieldArray_; // a temp array storing all the fields + + // ADVANCE RESERVATION PROPERTIES + private double reservProbability_; + private double timeInAdvance_; + private Random numGen_; + private long seed_ = 11L*13*17*19*23+1; + + // TAGS FOR INTERNAL EVENTS + private final int GRIDLET_SUBMIT = 10; + private final int RESERVE_RESOURCES = 11; + + /** + * Create a new Workload object <b>without</b> using the network extension. + * This means this entity directly sends Gridlets to a destination resource + * without going through a wired network. <br> + * <tt>NOTE:</tt> + * You can not use this constructor in an experiment that uses a wired + * network topology. + * + * @param name this entity name + * @param fileName the workload trace filename in one of the following + * format: <i>ASCII text, zip, gz.</i> + * @param resourceName the resource name + * @param rating the resource's PE rating + * @throws Exception This happens when creating this entity before + * initialising GridSim package or this entity name is + * <tt>null</tt> or empty + * @throws ParameterException This happens for the following conditions: + * <ul> + * <li>the entity name is null or empty + * <li>the workload trace file name is null or empty + * <li>the resource entity name is null or empty + * <li>the resource PE rating <= 0 + * </ul> + * @pre name != null + * @pre fileName != null + * @pre resourceName != null + * @pre rating > 0 + * @post $none + */ + public WorkloadWithReservation(String name, String fileName, String resourceName, + int rating) throws ParameterException, Exception { + super(name, GridSimTags.DEFAULT_BAUD_RATE); + + // check the input parameters first + String msg = name + "(): Error - "; + if (fileName == null || fileName.length() == 0) { + throw new ParameterException(msg + "invalid trace file name."); + } + else if (resourceName == null || resourceName.length() == 0) { + throw new ParameterException(msg + "invalid resource name."); + } + else if (rating <= 0) { + throw new ParameterException(msg+"resource PE rating must be > 0."); + } + + System.out.println(name + ": Creating a workload object ..."); + init(fileName, resourceName, rating); + } + + /** + * Create a new Workload object <b>with</b> the network extension. + * This means this entity directly sends Gridlets to a destination resource + * through a link. The link is automatically created by this constructor. + * + * @param name this entity name + * @param baudRate baud rate of this link (bits/s) + * @param propDelay Propagation delay of the Link in milliseconds + * @param MTU Maximum Transmission Unit of the Link in bytes. + * Packets which are larger than the MTU should be split + * up into MTU size units. + * For example, a 1024 byte packet trying to cross a 576 + * byte MTU link should get split into 2 packets of 576 + * bytes and 448 bytes. + * @param fileName the workload trace filename in one of the following + * format: <i>ASCII text, zip, gz.</i> + * @param resourceName the resource name + * @param rating the resource's PE rating + * @throws Exception This happens when creating this entity before + * initialising GridSim package or this entity name is + * <tt>null</tt> or empty + * @throws ParameterException This happens for the following conditions: + * <ul> + * <li>the entity name is null or empty + * <li> baudRate <= 0 + * <li> propDelay <= 0 + * <li> MTU <= 0 + * <li>the workload trace file name is null or empty + * <li>the resource entity name is null or empty + * <li>the resource PE rating <= 0 + * </ul> + * @pre name != null + * @pre baudRate > 0 + * @pre propDelay > 0 + * @pre MTU > 0 + * @pre fileName != null + * @pre resourceName != null + * @pre rating > 0 + * @post $none + */ + public WorkloadWithReservation(String name, double baudRate, double propDelay, int MTU, + String fileName, String resourceName, int rating) + throws ParameterException, Exception { + super( name, new SimpleLink(name+"_link", baudRate, propDelay, MTU) ); + + // check the input parameters first + String msg = name + "(): Error - "; + if (fileName == null || fileName.length() == 0) { + throw new ParameterException(msg + "invalid trace file name."); + } + else if (resourceName == null || resourceName.length() == 0) { + throw new ParameterException(msg + "invalid resource name."); + } + else if (rating <= 0) { + throw new ParameterException(msg+"resource PE rating must be > 0."); + } + + System.out.println(name + ": Creating a workload object ..."); + init(fileName, resourceName, rating); + } + + /** + * Create a new Workload object <b>with</b> the network extension. + * This means this entity directly sends Gridlets to a destination resource + * through a link. The link is automatically created by this constructor. + * + * @param name this entity name + * @param link the link that will be used to connect this Workload + * to another entity or a Router. + * @param fileName the workload trace filename in one of the following + * format: <i>ASCII text, zip, gz.</i> + * @param resourceName the resource name + * @param rating the resource's PE rating + * @throws Exception This happens when creating this entity before + * initialising GridSim package or this entity name is + * <tt>null</tt> or empty + * @throws ParameterException This happens for the following conditions: + * <ul> + * <li>the entity name is null or empty + * <li>the link is empty + * <li>the workload trace file name is null or empty + * <li>the resource entity name is null or empty + * <li>the resource PE rating <= 0 + * </ul> + * @pre name != null + * @pre link != null + * @pre fileName != null + * @pre resourceName != null + * @pre rating > 0 + * @post $none + */ + public WorkloadWithReservation(String name, Link link, String fileName, + String resourceName, int rating) + throws ParameterException, Exception { + super(name, link); + + // check the input parameters first + String msg = name + "(): Error - "; + if (fileName == null || fileName.length() == 0) { + throw new ParameterException(msg + "invalid trace file name."); + } + else if (resourceName == null || resourceName.length() == 0) { + throw new ParameterException(msg + "invalid resource name."); + } + else if (rating <= 0) { + throw new ParameterException(msg+"resource PE rating must be > 0."); + } + + System.out.println(name + ": Creating a workload object ..."); + init(fileName, resourceName, rating); + } + + /** + * Gets the probability of a job in the workload + * be an advance reservation + * @return the reservation probability + */ + public double getReservationProbability() { + return reservProbability_; + } + + /** + * Sets the probability of a job in the workload + * be an advance reservation + * @param probability the reservation probability + */ + public void setReservationProbability(double probability) { + reservProbability_ = probability; + } + + /** + * Gets how long in advance an advance reservation has to + * be made. The time in advance is how long in advance to + * the submission time included in the log the reservation + * has to be made + * @return the time in advance + */ + public double getARTimeInAdvance() { + return timeInAdvance_; + } + + /** + * Sets how long in advance an advance reservation has to + * be made. The time in advance is how long in advance to + * the submission time included in the log the reservation + * has to be made + * @param time the time in advance + */ + public void setARTimeInAdvance(double time) { + timeInAdvance_ = time; + } + + /** + * Initialises all the attributes + * @param fileName trace file name + * @param resourceName resource entity name + * @param rating resource PE rating + * @pre $none + * @post $none + */ + private void init(String fileName, String resourceName, int rating) + { + fileName_ = fileName; + resName_ = resourceName; + resID_ = GridSim.getEntityId(resName_); + rating_ = rating; + gridletID_ = 1; // starts at 1 to make it the same as in a trace file + list_ = null; + size_ = Link.DEFAULT_MTU; + + timeInAdvance_ = 60 * 60; // one hour + reservProbability_ = 0D; + numGen_ = new Random(seed_); + + // if using Standard Workload Format -- don't forget to substract by 1 + // since an array starts at 0, but the field in a trace starts at 1 + JOB_NUM = 1 - 1; + SUBMIT_TIME = 2 - 1; + RUN_TIME = 4 - 1; + NUM_PROC = 5 - 1; + REQ_NUM_PROC = 8 - 1; + REQ_RUN_TIME = 9 - 1; + + COMMENT = ";"; // semicolon means the start of a comment + MAX_FIELD = 18; // standard workload format has 18 fields + fieldArray_ = null; + } + + /** + * Sets a Gridlet file size (in byte) for sending to/from a resource. + * @param size a Gridlet file size (in byte) + * @return <tt>true</tt> if it is successful, <tt>false</tt> otherwise + * @pre size > 0 + * @post $none + */ + public boolean setGridletFileSize(int size) { + if (size < 0) { + return false; + } + + size_ = size; + return true; + } + + /** + * Identifies the start of a comment line. Hence, a line that starts + * with a given comment will be ignored. + * @param comment a character that denotes the start of a comment, + * e.g. ";" or "#" + * @return <tt>true</tt> if it is successful, <tt>false</tt> otherwise + * @pre comment != null + * @post $none + */ + public boolean setComment(String comment) + { + boolean success = false; + if (comment != null && comment.length() > 0) + { + COMMENT = comment; + success = true; + } + return success; + } + + /** + * Tells this class what to look in the trace file. + * This method should be called before the start of the simulation. + * <p> + * By default, this class follows the standard workload format as specified + * in <a href="http://www.cs.huji.ac.il/labs/parallel/workload/"> + * http://www.cs.huji.ac.il/labs/parallel/workload/</a> <br> + * However, you can use other format by calling this method. + * <p> + * The parameters must be a positive integer number starting from 1. + * A special case is where <tt>jobNum == -1</tt>, meaning the job or + * gridlet ID starts at 1. + * + * @param maxField max. number of field/column in one row + * @param jobNum field/column number for locating the job ID + * @param submitTime field/column number for locating the job submit time + * @param runTime field/column number for locating the job run time + * @param numProc field/column number for locating the number of PEs + * required to run a job + * @return <tt>true</tt> if successful, <tt>false</tt> otherwise + * @pre maxField > 0 + * @pre submitTime > 0 + * @pre runTime > 0 + * @pre numProc > 0 + * @post $none + */ + public boolean setField(int maxField, int jobNum, int submitTime, + int runTime, int numProc) + { + // need to substract by 1 since array starts at 0. Need to convert, + // position in a field into the index of the array + if (jobNum > 0) { + JOB_NUM = jobNum - 1; + } + else if (jobNum == 0) + { + System.out.println(super.get_name() + + ".setField(): Invalid job number field."); + return false; + } + else { + JOB_NUM = -1; + } + + // get the max. number of field + if (maxField > 0) { + MAX_FIELD = maxField; + } + else + { + System.out.println(super.get_name() + + ".setField(): Invalid max. number of field."); + return false; + } + + // get the submit time field + if (submitTime > 0) { + SUBMIT_TIME = submitTime - 1; + } + else + { + System.out.println(super.get_name() + + ".setField(): Invalid submit time field."); + return false; + } + + // get the run time field + if (runTime > 0) { + REQ_RUN_TIME = runTime - 1; + } + else + { + System.out.println(super.get_name() + + ".setField(): Invalid run time field."); + return false; + } + + // get the number of processors field + if (numProc > 0) { + REQ_NUM_PROC = numProc - 1; + } + else + { + System.out.println(super.get_name() + + ".setField(): Invalid number of processors field."); + return false; + } + + return true; + } + + /** + * Gets a list of completed Gridlets + * @return a list of Gridlets + * @pre $none + * @post $none + */ + public ArrayList getGridletList() { + return list_; + } + + /** + * Prints the Gridlet objects + * @param history <tt>true</tt> means printing each Gridlet's history, + * <tt>false</tt> otherwise + * @pre $none + * @post $none + */ + public void printGridletList(boolean history) + { + String name = super.get_name(); + int size = list_.size(); + Gridlet gridlet; + + String indent = " "; + System.out.println(); + System.out.println("========== OUTPUT for " + name + " =========="); + System.out.println("Gridlet_ID" + indent + "STATUS" + indent + + "Resource_ID" + indent + "Cost"); + + int i = 0; + for (i = 0; i < size; i++) + { + gridlet = (Gridlet) list_.get(i); + System.out.print(indent + gridlet.getGridletID() + indent + + indent); + + // get the status of a Gridlet + System.out.print( gridlet.getGridletStatusString() ); + System.out.println( indent + indent + gridlet.getResourceID() + + indent + indent + gridlet.getProcessingCost() ); + } + + System.out.println(); + if (history == true) + { + // a loop to print each Gridlet's history + System.out.println(); + for (i = 0; i < size; i++) + { + gridlet = (Gridlet) list_.get(i); + System.out.println( gridlet.getGridletHistory() ); + + System.out.print("Gridlet #" + gridlet.getGridletID() ); + System.out.println(", length = " + gridlet.getGridletLength() + + ", finished so far = " + + gridlet.getGridletFinishedSoFar() ); + System.out.println("========================================="); + System.out.println(); + } + } + } + + /** + * Reads from a given file when the simulation starts running. + * Then submits Gridlets to a resource and collects them before exiting. + * To collect the completed Gridlets, use {@link #getGridletList()} + * @pre $none + * @post $none + */ + public void body() { + System.out.println(); + System.out.println(super.get_name() + ".body() :%%%% Start ..."); + + // create a temp array + fieldArray_ = new String[MAX_FIELD]; + + // get the resource id + if (resID_ < 0) + { + System.out.println(super.get_name() + + ".body(): Error - invalid resource name: " + resName_); + return; + } + + boolean success = false; + + // read the gz file + if (fileName_.endsWith(".gz") == true) { + success = readGZIPFile(fileName_); + } + // read the zip file + else if (fileName_.endsWith(".zip") == true) { + success = readZipFile(fileName_); + } + // read from uncompressed file as well + else { + success = readFile(fileName_); + } + + // if all the gridlets have been submitted + if (!success ) { + System.out.println(super.get_name() + + ".body(): Error - unable to parse from a file."); + return; + } + + System.out.println(super.get_name() + ": Collecting Gridlets ..."); + list_ = new ArrayList(gridletID_ + 1); + + Object data = null; + Gridlet gl = null; + + int counter = 1; // starts at 1, since gridletID_ starts at 1 too + Sim_event ev = new Sim_event(); + Object[] reservObj = null; + + while ( Sim_system.running() + && counter < gridletID_ ) { + + super.sim_get_next(ev); // get the next available event + data = ev.get_data(); // get the event's data + + // handle ping request + if (ev.get_tag() == GridSimTags.INFOPKT_SUBMIT) { + processPingRequest(ev); + continue; + } + else if (ev.get_tag() == RESERVE_RESOURCES) { + + reservObj = (Object[])ev.get_data(); + + double startTime = (Double)reservObj[0]; + int duration = (Integer)reservObj[1]; + Gridlet resGl = (Gridlet)reservObj[2]; + + // creates a new reservation + Reservation reservation = null; + reservation = super.createReservation(startTime, duration, resGl.getNumPE(), resID_); + + success = true; + if(reservation == null) { + success = false; + } + + // commit the reservation + if(success) { + // for a reservation with an even number, commits straightaway + // without sending any Gridlets yet + success = super.commitReservation(reservation.getID()); + + // submit the gridlet if success + if(success) { + + // sets the reservation id of this gridlet + resGl.setReservationID(reservation.getID()); + + // submit the gridlet to the resource + super.send(super.output, GridSimTags.SCHEDULE_NOW, GridSimTags.GRIDLET_SUBMIT, + new IO_data(resGl, resGl.getGridletFileSize(), resID_) ); + } + // if the reservation fails, then sets the status of the + // gridlet to failed and adds the gridlet to the list + else { + try { + resGl.setGridletStatus(Gridlet.FAILED); + } + catch(Exception ex) { + + } + list_.add(resGl); + } + } + counter++; + } + + // get the Gridlet data + else if (data != null && data instanceof Gridlet) { + gl = (Gridlet) data; + list_.add(gl); + counter++; + } + + // if all the Gridlets have been collected + if (counter == gridletID_) { + break; + } + } + + // shut down all the entities, including GridStatistics entity since + // we used it to record certain events. + shutdownGridStatisticsEntity(); + shutdownUserEntity(); + terminateIOEntities(); + + System.out.println(super.get_name() + ".body() : %%%% Exit ..."); + } + + //////////////////////// PROTECTED METHODS /////////////////////// + + /** + * Processes a ping request. + * @param ev a Sim_event object + * @pre ev != null + * @post $none + */ + protected void processPingRequest(Sim_event ev) + { + InfoPacket pkt = (InfoPacket) ev.get_data(); + pkt.setTag(GridSimTags.INFOPKT_RETURN); + pkt.setDestID( pkt.getSrcID() ); + + // sends back to the sender + super.send(super.output, GridSimTags.SCHEDULE_NOW, + GridSimTags.INFOPKT_RETURN, + new IO_data(pkt, pkt.getSize(), pkt.getSrcID()) ); + } + + //////////////////////// PRIVATE METHODS /////////////////////// + + /** + * Breaks a line of string into many fields. + * @param line a line of string + * @param lineNum a line number + * @pre line != null + * @pre lineNum > 0 + * @post $none + */ + private void parseValue(String line, int lineNum) + { + // skip a comment line + if (line.startsWith(COMMENT) == true) { + return; + } + + String[] sp = line.split("\\s+"); // split the fields based on a space + int i; // a counter + int len = 0; // length of a string + int index = 0; // the index of an array + + // check for each field in the array + for (i = 0; i < sp.length; i++) + { + len = sp[i].length(); // get the length of a string + + // if it is empty then ignore + if (len == 0) { + continue; + } + // if not, then put into the array + else + { + fieldArray_[index] = sp[i]; + index++; + } + } + + if (index == MAX_FIELD) { + extractField(fieldArray_, lineNum); + } + } + + /** + * Extracts relevant information from a given array + * @param array an array of String + * @param line a line number + * @pre array != null + * @pre line > 0 + */ + private void extractField(String[] array, int line) + { + try + { + Integer obj = null; + + // get the job number + int id = 0; + if (JOB_NUM == IRRELEVANT) { + id = gridletID_; + } + else + { + obj = new Integer( array[JOB_NUM].trim() ); + id = obj.intValue(); + } + + // get the submit time + Long l = new Long( array[SUBMIT_TIME].trim() ); + long submitTime = l.intValue(); + + // get the run time + obj = new Integer( array[REQ_RUN_TIME].trim() ); + int runTime = obj.intValue(); + + // if the required run time field is ignored, then use + // the actual run time + if (runTime == IRRELEVANT) + { + obj = new Integer( array[RUN_TIME].trim() ); + runTime = obj.intValue(); + } + + // according to the SWF manual, runtime of 0 is possible due + // to rounding down. E.g. runtime is 0.4 seconds -> runtime = 0 + if (runTime == 0) { + runTime = 1; // change to 1 second + } + + // get the number of allocated processors + obj = new Integer( array[REQ_NUM_PROC].trim() ); + int numProc = obj.intValue(); + + // if the required num of allocated processors field is ignored + // or zero, then use the actual field + if (numProc == IRRELEVANT || numProc == 0) + { + obj = new Integer( array[NUM_PROC].trim() ); + numProc = obj.intValue(); + } + + // finally, check if the num of PEs required is valid or not + if (numProc <= 0) + { + System.out.println(super.get_name() + ": Warning - job #" + + id + " at line " + line + " requires " + numProc + + " CPU. Change to 1 CPU."); + numProc = 1; + } + + // creates a submission/reservation event + submitGridlet(id, submitTime, runTime, numProc); + } + catch (Exception e) + { + System.out.println(super.get_name() + + ": Exception in reading file at line #" + line); + e.printStackTrace(); + } + } + + /** + * Creates a Gridlet with the given information, then submit it to a + * resource + * @param id a Gridlet ID + * @param submitTime Gridlet's submit time + * @param runTime Gridlet's run time + * @param numProc number of processors + * @pre id >= 0 + * @pre submitTime >= 0 + * @pre runTime >= 0 + * @pre numProc > 0 + * @post $none + */ + protected void submitGridlet(int id, long submitTime, int runTime, int numProc) { + // create the gridlet + int len = runTime * rating_; // calculate a job length for each PE + Gridlet gridlet = new Gridlet(id, len, size_, size_); + gridlet.setUserID( super.get_id() ); // set the owner ID + gridlet.setNumPE(numProc); // set the requested num of proc + + // check the probability of creating an advance reservation + double probAR = Math.abs(numGen_.nextDouble()); + + // check the submit time + if (submitTime < 0) { + submitTime = 0; + } + + if(probAR <= reservProbability_) { + + // calculate how long in advance the reservation is made + double timeInAdvance = timeInAdvance_ * numGen_.nextDouble(); + + // convert to seconds + double timeToReserve = submitTime - timeInAdvance; + + // if the time the reservation would be done has already + // past, then consider now as the submission time + if(timeToReserve <= 0.0D) { + timeToReserve = GridSimTags.SCHEDULE_NOW; + } + + //TODO To check the duration of the advance reservation later + Object[] reservObj = new Object[3]; + reservObj[0] = new Double(submitTime); // start time of the reservation + reservObj[1] = (int) runTime + 1; // the advance reservation duration + reservObj[2] = gridlet; // the gridlet to be submitted + + // submit an internal event to create a reservation for this gridlet + super.send(super.get_id(), timeToReserve, RESERVE_RESOURCES, reservObj); + } + else { + // printing to inform user + if (gridletID_ == 1 || gridletID_ % INTERVAL == 0) { + System.out.println(super.get_name() + ": Submitting Gridlets to " + + resName_ + " ..."); + } + + // submit a gridlet to resource + super.send(super.output, submitTime, GridSimTags.GRIDLET_SUBMIT, + new IO_data(gridlet, gridlet.getGridletFileSize(), resID_) ); + } + + gridletID_++; // increment the counter + } + + /** + * Reads a text file one line at the time + * @param fileName a file name + * @return <tt>true</tt> if reading a file is successful, <tt>false</tt> + * otherwise. + * @pre fileName != null + * @post $none + */ + private boolean readFile(String fileName) + { + boolean success = false; + BufferedReader reader = null; + try + { + FileInputStream file = new FileInputStream(fileName); + InputStreamReader input = new InputStreamReader(file); + reader = new BufferedReader(input); + + // read one line at the time + int line = 1; + while ( reader.ready() ) + { + parseValue(reader.readLine(), line); + line++; + } + + reader.close(); // close the file + success = true; + } + catch (FileNotFoundException f) + { + System.out.println(super.get_name() + + ": Error - the file was not found: " + f.getMessage()); + } + catch (IOException e) + { + System.out.println(super.get_name() + + ": Error - an IOException occurred: " + e.getMessage()); + } + finally + { + if (reader != null) + { + try { + reader.close(); // close the file + } + catch (IOException e) + { + System.out.println(super.get_name() + + ": Error - an IOException occurred: " + e.getMessage()); + } + } + } + + return success; + } + + /** + * Reads a gzip file one line at the time + * @param fileName a gzip file name + * @return <tt>true</tt> if reading a file is successful, <tt>false</tt> + * otherwise. + * @pre fileName != null + * @post $none + */ + private boolean readGZIPFile(String fileName) + { + boolean success = false; + BufferedReader reader = null; + try + { + FileInputStream file = new FileInputStream(fileName); + GZIPInputStream gz = new GZIPInputStream(file); + InputStreamReader input = new InputStreamReader(gz); + reader = new BufferedReader(input); + + // read one line at the time + int line = 1; + while ( reader.ready() ) + { + parseValue(reader.readLine(), line); + line++; + } + + reader.close(); // close the file + success = true; + } + catch (FileNotFoundException f) + { + System.out.println(super.get_name() + + ": Error - the file was not found: " + f.getMessage()); + } + catch (IOException e) + { + System.out.println(super.get_name() + + ": Error - an IOException occurred: " + e.getMessage()); + } + finally + { + if (reader != null) + { + try { + reader.close(); // close the file + } + catch (IOException e) + { + System.out.println(super.get_name() + + ": Error - an IOException occurred: " + e.getMessage()); + } + } + } + + return success; + } + + /** + * Reads a Zip file. Iterating through each entry and reading it one line + * at the time. + * @param fileName a zip file name + * @return <tt>true</tt> if reading a file is successful, <tt>false</tt> + * otherwise. + * @pre fileName != null + * @post $none + */ + private boolean readZipFile(String fileName) + { + boolean success = false; + ZipFile zipFile = null; + try + { + InputStreamReader input = null; + BufferedReader reader = null; + + // ZipFile offers an Enumeration of all the files in the Zip file + zipFile = new ZipFile(fileName); + for (Enumeration e = zipFile.entries(); e.hasMoreElements();) + { + success = false; // reset the value again + ZipEntry zipEntry = (ZipEntry) e.nextElement(); + + input = new InputStreamReader(zipFile.getInputStream(zipEntry)); + reader = new BufferedReader(input); + + // read one line at the time + int line = 1; + while ( reader.ready() ) + { + parseValue(reader.readLine(), line); + line++; + } + + reader.close(); // close the file + success = true; + } + } + catch (IOException e) + { + System.out.println(super.get_name() + + ": Error - an IOException occurred: " + e.getMessage()); + } + finally + { + if (zipFile != null) + { + try { + zipFile.close(); // close the file + } + catch (IOException e) + { + System.out.println(super.get_name() + + ": Error - an IOException occurred: " + e.getMessage()); + } + } + } + + return success; + } +} Added: branches/gridsim4.0-branch3/examples/examples/ar/ARTest.java =================================================================== --- branches/gridsim4.0-branch3/examples/examples/ar/ARTest.java (rev 0) +++ branches/gridsim4.0-branch3/examples/examples/ar/ARTest.java 2007-12-16 23:08:32 UTC (rev 82) @@ -0,0 +1,288 @@ +/* + * Author Marcos Dias de Assuncao + * Date: September 2007 + * Description: A simple program to demonstrate of how to use basic + * advanced reservation functionalities, such as create, commit + * and status. + */ + +package examples.ar; + +import gridsim.GridSim; +import gridsim.Gridlet; +import gridsim.GridletList; +import gridsim.turbo.Reservation; +import gridsim.turbo.ReservationRequester; +import gridsim.turbo.AvailabilityInfo; + +import java.util.ArrayList; +import java.util.Calendar; +import java.util.LinkedList; +import java.util.Random; + +/** + * A user entity that reserves a resource in advance. + * In this example, only explore some functionalities, such as: + * - requests a new advanced reservation + * - requests a new immediate reservation. Immediate reservation means use + * current time as the starting time + * - commits an accepted reservation + * - checks the status of a reservation + */ +public class A... [truncated message content] |
From: <mar...@us...> - 2007-11-29 01:04:00
|
Revision: 81 http://gridsim.svn.sourceforge.net/gridsim/?rev=81&view=rev Author: marcos_dias Date: 2007-11-28 17:04:02 -0800 (Wed, 28 Nov 2007) Log Message: ----------- Problem with subversion. Deleting the files to update them later. Removed Paths: ------------- branches/gridsim4.0-branch3/examples/examples/WorkloadWithCancellation.java branches/gridsim4.0-branch3/examples/examples/WorkloadWithReservation.java branches/gridsim4.0-branch3/examples/examples/ar/ARTest.java branches/gridsim4.0-branch3/examples/examples/ar/SimpleARExample01.java branches/gridsim4.0-branch3/examples/examples/workload/ar/TurboARExample01.java branches/gridsim4.0-branch3/examples/examples/workload/ar/TurboARExample02.java branches/gridsim4.0-branch3/examples/examples/workload/ar/TurboARExampleWithCancellation01.java branches/gridsim4.0-branch3/examples/examples/workload/parallel/TurboExample01.java branches/gridsim4.0-branch3/examples/examples/workload/parallel/TurboExampleWithCancellation01.java branches/gridsim4.0-branch3/source/eduni/simjava/Evqueue.java branches/gridsim4.0-branch3/source/eduni/simjava/Semaphore.java branches/gridsim4.0-branch3/source/eduni/simjava/Sim_any_p.java branches/gridsim4.0-branch3/source/eduni/simjava/Sim_entity.java branches/gridsim4.0-branch3/source/eduni/simjava/Sim_event.java branches/gridsim4.0-branch3/source/eduni/simjava/Sim_exception.java branches/gridsim4.0-branch3/source/eduni/simjava/Sim_from_p.java branches/gridsim4.0-branch3/source/eduni/simjava/Sim_none_p.java branches/gridsim4.0-branch3/source/eduni/simjava/Sim_not_from_p.java branches/gridsim4.0-branch3/source/eduni/simjava/Sim_not_type_p.java branches/gridsim4.0-branch3/source/eduni/simjava/Sim_outfile.java branches/gridsim4.0-branch3/source/eduni/simjava/Sim_output.java branches/gridsim4.0-branch3/source/eduni/simjava/Sim_port.java branches/gridsim4.0-branch3/source/eduni/simjava/Sim_predicate.java branches/gridsim4.0-branch3/source/eduni/simjava/Sim_system.java branches/gridsim4.0-branch3/source/eduni/simjava/Sim_type_p.java branches/gridsim4.0-branch3/source/gridsim/ARGridResource.java branches/gridsim4.0-branch3/source/gridsim/ARObject.java branches/gridsim4.0-branch3/source/gridsim/ARPolicy.java branches/gridsim4.0-branch3/source/gridsim/ARSimpleSpaceShared.java branches/gridsim4.0-branch3/source/gridsim/Accumulator.java branches/gridsim4.0-branch3/source/gridsim/AdvanceReservation.java branches/gridsim4.0-branch3/source/gridsim/AllocPolicy.java branches/gridsim4.0-branch3/source/gridsim/GridInformationService.java branches/gridsim4.0-branch3/source/gridsim/GridResource.java branches/gridsim4.0-branch3/source/gridsim/GridSim.java branches/gridsim4.0-branch3/source/gridsim/GridSimCore.java branches/gridsim4.0-branch3/source/gridsim/GridSimRandom.java branches/gridsim4.0-branch3/source/gridsim/GridSimShutdown.java branches/gridsim4.0-branch3/source/gridsim/GridSimStandardPE.java branches/gridsim4.0-branch3/source/gridsim/GridSimTags.java branches/gridsim4.0-branch3/source/gridsim/GridStatistics.java branches/gridsim4.0-branch3/source/gridsim/GridUser.java branches/gridsim4.0-branch3/source/gridsim/Gridlet.java branches/gridsim4.0-branch3/source/gridsim/GridletList.java branches/gridsim4.0-branch3/source/gridsim/IO_data.java branches/gridsim4.0-branch3/source/gridsim/Machine.java branches/gridsim4.0-branch3/source/gridsim/MachineList.java branches/gridsim4.0-branch3/source/gridsim/ParameterException.java branches/gridsim4.0-branch3/source/gridsim/ResGridlet.java branches/gridsim4.0-branch3/source/gridsim/ResGridletList.java branches/gridsim4.0-branch3/source/gridsim/ResourceCalendar.java branches/gridsim4.0-branch3/source/gridsim/ResourceCharacteristics.java branches/gridsim4.0-branch3/source/gridsim/ResourceUserList.java branches/gridsim4.0-branch3/source/gridsim/Sim_from_port.java branches/gridsim4.0-branch3/source/gridsim/SpaceShared.java branches/gridsim4.0-branch3/source/gridsim/Stat.java branches/gridsim4.0-branch3/source/gridsim/TimeShared.java branches/gridsim4.0-branch3/source/gridsim/gui/AllocationAction.java branches/gridsim4.0-branch3/source/gridsim/gui/AllocationListener.java branches/gridsim4.0-branch3/source/gridsim/gui/DefaultGridSimVisualizer.java branches/gridsim4.0-branch3/source/gridsim/gui/GUISettings.java branches/gridsim4.0-branch3/source/gridsim/gui/GridSimVisualizer.java branches/gridsim4.0-branch3/source/gridsim/gui/ResourceWindow.java branches/gridsim4.0-branch3/source/gridsim/turbo/ARMessage.java branches/gridsim4.0-branch3/source/gridsim/turbo/ARParallelSpaceShared.java branches/gridsim4.0-branch3/source/gridsim/turbo/ARTGridResource.java branches/gridsim4.0-branch3/source/gridsim/turbo/ARTPolicy.java branches/gridsim4.0-branch3/source/gridsim/turbo/AvailabilityInfo.java branches/gridsim4.0-branch3/source/gridsim/turbo/AvailabilityInfoEntry.java branches/gridsim4.0-branch3/source/gridsim/turbo/AvailabilityProfile.java branches/gridsim4.0-branch3/source/gridsim/turbo/AvailabilityProfileEntry.java branches/gridsim4.0-branch3/source/gridsim/turbo/FilterARMessage.java branches/gridsim4.0-branch3/source/gridsim/turbo/OrderGridletByStartTime.java branches/gridsim4.0-branch3/source/gridsim/turbo/PERange.java branches/gridsim4.0-branch3/source/gridsim/turbo/PERangeList.java branches/gridsim4.0-branch3/source/gridsim/turbo/ParallelSpaceShared.java branches/gridsim4.0-branch3/source/gridsim/turbo/Reservation.java branches/gridsim4.0-branch3/source/gridsim/turbo/ReservationRequester.java branches/gridsim4.0-branch3/source/gridsim/turbo/SSGridlet.java branches/gridsim4.0-branch3/source/gridsim/turbo/SSReservation.java branches/gridsim4.0-branch3/source/gridsim/turbo/ScheduleItem.java branches/gridsim4.0-branch3/source/gridsim/turbo/TAllocPolicy.java branches/gridsim4.0-branch3/source/gridsim/turbo/TResourceCharacteristics.java Deleted: branches/gridsim4.0-branch3/examples/examples/WorkloadWithCancellation.java =================================================================== --- branches/gridsim4.0-branch3/examples/examples/WorkloadWithCancellation.java 2007-11-14 11:23:50 UTC (rev 80) +++ branches/gridsim4.0-branch3/examples/examples/WorkloadWithCancellation.java 2007-11-29 01:04:02 UTC (rev 81) @@ -1,250 +0,0 @@ -/* Title: GridSim Toolkit - * Description: GridSim (Grid Simulation) Toolkit for Modeling and Simulation - * of Parallel and Distributed Systems such as Clusters and Grids - * Licence: GPL - http://www.gnu.org/copyleft/gpl.html - */ - -package examples; - -import eduni.simjava.Sim_event; -import eduni.simjava.Sim_system; -import gridsim.GridSimTags; -import gridsim.Gridlet; -import gridsim.IO_data; -import gridsim.ParameterException; -import gridsim.net.Link; -import gridsim.util.Workload; - -import java.util.ArrayList; - -/** - * This class is an extended version of {@link Workload}. This class - * cancels some gridlets submitted. - * - * @author Marcos Dias de Assuncao - * @since GridSim Turbo Alpha 0.1 - * - * @see Workload - */ -public class WorkloadWithCancellation extends Workload { - private final int NUM_GRIDLETS_BETWEEN_CANCELLATIONS = 50; - // value of 1, means that the cancellation will be sent - // at the gridlet's submission time + (gridlet duration * 1) - private final double TIME_CANCELLATION = 0.5; - - /** - * Create a new {@link WorkloadWithCancellation} object <b>without</b> using - * the network extension. This means this entity directly sends Gridlets - * to a resource destination without going through a wired network. <br> - * <tt>NOTE:</tt> - * You can not use this constructor in an experiment that uses a wired - * network topology. - * - * @param name this entity name - * @param fileName the workload trace filename in one of the following - * format: <i>ASCII text, zip, gz.</i> - * @param resourceName the resource name - * @param rating the resource's PE rating - * @throws Exception This happens when creating this entity before - * initialising GridSim package or this entity name is - * <tt>null</tt> or empty - * @throws ParameterException This happens for the following conditions: - * <ul> - * <li>the entity name is null or empty - * <li>the workload trace file name is null or empty - * <li>the resource entity name is null or empty - * <li>the resource PE rating <= 0 - * </ul> - * @pre name != null - * @pre fileName != null - * @pre resourceName != null - * @pre rating > 0 - * @post $none - */ - public WorkloadWithCancellation(String name, String fileName, String resourceName, - int rating) throws ParameterException, Exception { - - super(name, fileName, resourceName, rating); - } - - /** - * Create a new {@link WorkloadWithCancellation} object <b>with</b> the network extension. - * This means this entity directly sends Gridlets to a destination resource - * through a link. The link is automatically created by this constructor. - * - * @param name this entity name - * @param baudRate baud rate of this link (bits/s) - * @param propDelay Propagation delay of the Link in milliseconds - * @param MTU Maximum Transmission Unit of the Link in bytes. - * Packets which are larger than the MTU should be split - * up into MTU size units. - * For example, a 1024 byte packet trying to cross a 576 - * byte MTU link should get split into 2 packets of 576 - * bytes and 448 bytes. - * @param fileName the workload trace filename in one of the following - * format: <i>ASCII text, zip, gz.</i> - * @param resourceName the resource name - * @param rating the resource's PE rating - * @throws Exception This happens when creating this entity before - * initialising GridSim package or this entity name is - * <tt>null</tt> or empty - * @throws ParameterException This happens for the following conditions: - * <ul> - * <li>the entity name is null or empty - * <li> baudRate <= 0 - * <li> propDelay <= 0 - * <li> MTU <= 0 - * <li>the workload trace file name is null or empty - * <li>the resource entity name is null or empty - * <li>the resource PE rating <= 0 - * </ul> - * @pre name != null - * @pre baudRate > 0 - * @pre propDelay > 0 - * @pre MTU > 0 - * @pre fileName != null - * @pre resourceName != null - * @pre rating > 0 - * @post $none - */ - public WorkloadWithCancellation(String name, double baudRate, double propDelay, int MTU, - String fileName, String resourceName, int rating) - throws ParameterException, Exception { - - super( name, baudRate, propDelay, MTU, fileName, resourceName, rating ); - } - - /** - * Create a new Workload object <b>with</b> the network extension. - * This means this entity directly sends Gridlets to a destination resource - * through a link. The link is automatically created by this constructor. - * - * @param name this entity name - * @param link the link that will be used to connect this Workload - * to another entity or a Router. - * @param fileName the workload trace filename in one of the following - * format: <i>ASCII text, zip, gz.</i> - * @param resourceName the resource name - * @param rating the resource's PE rating - * @throws Exception This happens when creating this entity before - * initialising GridSim package or this entity name is - * <tt>null</tt> or empty - * @throws ParameterException This happens for the following conditions: - * <ul> - * <li>the entity name is null or empty - * <li>the link is empty - * <li>the workload trace file name is null or empty - * <li>the resource entity name is null or empty - * <li>the resource PE rating <= 0 - * </ul> - * @pre name != null - * @pre link != null - * @pre fileName != null - * @pre resourceName != null - * @pre rating > 0 - * @post $none - */ - public WorkloadWithCancellation(String name, Link link, String fileName, - String resourceName, int rating) - throws ParameterException, Exception { - - super(name, link, fileName, resourceName, rating); - } - - //////////////////////// PRIVATE METHODS /////////////////////// - - /** - * Collects Gridlets sent and stores them into a list. - * @pre $none - * @post $none - */ - protected void collectGridlet() { - System.out.println(super.get_name() + ": Collecting Gridlets ..."); - list_ = new ArrayList(gridletID_ + 1); - - Object data = null; - Gridlet gl = null; - - int counter = 1; // starts at 1, since gridletID_ starts at 1 too - Sim_event ev = new Sim_event(); - while ( Sim_system.running() ) { - - super.sim_get_next(ev); // get the next available event - data = ev.get_data(); // get the event's data - - // handle ping request - if (ev.get_tag() == GridSimTags.INFOPKT_SUBMIT) { - processPingRequest(ev); - continue; - } - - // get the Gridlet data - if (data != null && data instanceof Gridlet) { - gl = (Gridlet) data; - -// if(gl.getGridletStatus() == Gridlet.FAILED) -// System.out.println("Gridlet failed"); -// -// if(gl.getGridletStatus() == Gridlet.CANCELED) -// System.out.println("Gridlet cancelled"); - - list_.add(gl); - counter++; - } - - // if all the Gridlets have been collected - if (counter == gridletID_) { - break; - } - } - } - - /** - * Creates a Gridlet with the given information, then submit it to a - * resource - * @param id a Gridlet ID - * @param submitTime Gridlet's submit time - * @param runTime Gridlet's run time - * @param numProc number of processors - * @pre id >= 0 - * @pre submitTime >= 0 - * @pre runTime >= 0 - * @pre numProc > 0 - * @post $none - */ - protected void submitGridlet(int id, long submitTime, int runTime, int numProc) { - - // create the gridlet - int len = runTime * rating_; // calculate a job length for each PE - Gridlet gl = new Gridlet(id, len, size_, size_); - gl.setUserID( super.get_id() ); // set the owner ID - gl.setNumPE(numProc); // set the requested num of proc - - // printing to inform user - if (gridletID_ == 1 || gridletID_ % INTERVAL == 0) { - System.out.println(super.get_name() + ": Submitting Gridlets to " + - resName_ + " ..."); - } - - // check the submit time - if (submitTime < 0) { - submitTime = 0; - } - - gridletID_++; // increment the counter - - // submit a gridlet to resource - super.send(super.output, submitTime, GridSimTags.GRIDLET_SUBMIT, - new IO_data(gl, gl.getGridletFileSize(), resID_) ); - - // check whether a cancellation has to be scheduled or not - int result = gridletID_ % NUM_GRIDLETS_BETWEEN_CANCELLATIONS; - if(result == 0) { - super.send(super.output, (submitTime + (TIME_CANCELLATION * runTime)), GridSimTags.GRIDLET_CANCEL, - new IO_data(gl, 0, resID_) ); - gridletID_++; - } - } - -} // end class - Deleted: branches/gridsim4.0-branch3/examples/examples/WorkloadWithReservation.java =================================================================== --- branches/gridsim4.0-branch3/examples/examples/WorkloadWithReservation.java 2007-11-14 11:23:50 UTC (rev 80) +++ branches/gridsim4.0-branch3/examples/examples/WorkloadWithReservation.java 2007-11-29 01:04:02 UTC (rev 81) @@ -1,1077 +0,0 @@ -/* - * Title: GridSim Toolkit - * Description: GridSim (Grid Simulation) Toolkit for Modeling and Simulation - * of Parallel and Distributed Systems such as Clusters and Grids - * Licence: GPL - http://www.gnu.org/copyleft/gpl.html - * - */ - -package examples; - -import java.io.BufferedReader; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStreamReader; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.Enumeration; -import java.util.Random; -import java.util.zip.GZIPInputStream; -import java.util.zip.ZipEntry; -import java.util.zip.ZipFile; - -import eduni.simjava.Sim_event; -import eduni.simjava.Sim_system; - -import gridsim.GridSim; -import gridsim.GridSimTags; -import gridsim.Gridlet; -import gridsim.IO_data; -import gridsim.ParameterException; -import gridsim.net.InfoPacket; -import gridsim.net.Link; -import gridsim.net.SimpleLink; -import gridsim.turbo.Reservation; -import gridsim.turbo.ReservationRequester; - -/** - * The main purpose of this class is to create a realistic simulation - * environment where your jobs or Gridlets are competing with others. - * In other words, the grid resource might not be available at certain times. - * In addition, the arrival time of jobs are also captured in the trace file. - * <p> - * This workload class has been modified to simulate advance reservations. - * Some parameters where included to indicate the frequency in which - * advance reservations are made. Additionally, it is possible to specify how - * long in advance the advance reservations are made. - * <p> - * This class is responsible for reading resource traces from a file and - * sends Gridlets to only <tt>one</tt> destinated resource. <br> - * <b>NOTE:</b> - * <ul> - * <li> This class can only take <tt>one</tt> trace file of the following - * format: <i>ASCII text, zip, gz.</i> - * <li> This class can be classified as <b>one grid user entity</b>. - * Hence, you need to incorporate this entity into <tt>numUser</tt> - * during {@link gridsim.GridSim#init(int, Calendar, boolean)} - * <li> If you need to use multiple trace files to submit Gridlets to - * same or different resources, then you need to create multiple - * instances of this class <tt>each with a unique entity name</tt>. - * <li> If size of the trace file is huge or contains lots of traces - * please increase the JVM heap size accordingly by using - * <tt>java -Xmx</tt> option when running the simulation. - * <li> If you are running an experiment using the network extension, - * i.e. the gridsim.net package, then you need to use - * {@link #Workload(String, double, double, int, String, String, int)} - * instead. - * <li> The default job file size for sending to and receiving from - * a resource is {@link gridsim.net.Link#DEFAULT_MTU}. - * However, you can specify - * the file size by using {@link #setGridletFileSize(int)}. - * <li> A job run time is only for 1 PE <tt>not</tt> the total number of - * allocated PEs. - * Therefore, a Gridlet length is also calculated for 1 PE.<br> - * For example, job #1 in the trace has a run time of 100 seconds - * for 2 processors. This means each processor runs - * job #1 for 100 seconds, if the processors have the same - * specification. - * </ul> - * <p> - * By default, this class follows the standard workload format as specified - * in <a href="http://www.cs.huji.ac.il/labs/parallel/workload/"> - * http://www.cs.huji.ac.il/labs/parallel/workload/</a> <br> - * However, you can use other format by calling the below methods before - * running the simulation: - * <ul> - * <li> {@link #setComment(String)} - * <li> {@link #setField(int, int, int, int, int)} - * </ul> - * - * @see gridsim.GridSim#init(int, Calendar, boolean) - * @author Marcos Dias de Assuncao (the most of the code came - * from {@link Workload} class) - * @since GridSim Turbo Alpha 0.1 - * @invariant $none - */ - -public class WorkloadWithReservation extends ReservationRequester { - - protected String fileName_; // file name - protected String resName_; // resource name - protected int resID_; // resource ID - protected int rating_; // a PE rating - protected int gridletID_; // gridletID - protected int size_; // job size for sending it through a network - protected ArrayList list_; // a list for getting all the Gridlets - - // constant - private int JOB_NUM; // job number - private int SUBMIT_TIME; // submit time of a Gridlet - private int RUN_TIME; // running time of a Gridlet - private int NUM_PROC; // number of processors needed for a Gridlet - private int REQ_NUM_PROC; // required number of processors - private int REQ_RUN_TIME; // required running time - private int MAX_FIELD; // max number of field in the trace file - private String COMMENT; // a string that denotes the start of a comment - private final int IRRELEVANT = -1; // irrelevant number - protected final int INTERVAL = 10; // number of intervals - private String[] fieldArray_; // a temp array storing all the fields - - // ADVANCE RESERVATION PROPERTIES - private double reservProbability_; - private double timeInAdvance_; - private Random numGen_; - private long seed_ = 11L*13*17*19*23+1; - - // TAGS FOR INTERNAL EVENTS - private final int GRIDLET_SUBMIT = 10; - private final int RESERVE_RESOURCES = 11; - - /** - * Create a new Workload object <b>without</b> using the network extension. - * This means this entity directly sends Gridlets to a destination resource - * without going through a wired network. <br> - * <tt>NOTE:</tt> - * You can not use this constructor in an experiment that uses a wired - * network topology. - * - * @param name this entity name - * @param fileName the workload trace filename in one of the following - * format: <i>ASCII text, zip, gz.</i> - * @param resourceName the resource name - * @param rating the resource's PE rating - * @throws Exception This happens when creating this entity before - * initialising GridSim package or this entity name is - * <tt>null</tt> or empty - * @throws ParameterException This happens for the following conditions: - * <ul> - * <li>the entity name is null or empty - * <li>the workload trace file name is null or empty - * <li>the resource entity name is null or empty - * <li>the resource PE rating <= 0 - * </ul> - * @pre name != null - * @pre fileName != null - * @pre resourceName != null - * @pre rating > 0 - * @post $none - */ - public WorkloadWithReservation(String name, String fileName, String resourceName, - int rating) throws ParameterException, Exception { - super(name, GridSimTags.DEFAULT_BAUD_RATE); - - // check the input parameters first - String msg = name + "(): Error - "; - if (fileName == null || fileName.length() == 0) { - throw new ParameterException(msg + "invalid trace file name."); - } - else if (resourceName == null || resourceName.length() == 0) { - throw new ParameterException(msg + "invalid resource name."); - } - else if (rating <= 0) { - throw new ParameterException(msg+"resource PE rating must be > 0."); - } - - System.out.println(name + ": Creating a workload object ..."); - init(fileName, resourceName, rating); - } - - /** - * Create a new Workload object <b>with</b> the network extension. - * This means this entity directly sends Gridlets to a destination resource - * through a link. The link is automatically created by this constructor. - * - * @param name this entity name - * @param baudRate baud rate of this link (bits/s) - * @param propDelay Propagation delay of the Link in milliseconds - * @param MTU Maximum Transmission Unit of the Link in bytes. - * Packets which are larger than the MTU should be split - * up into MTU size units. - * For example, a 1024 byte packet trying to cross a 576 - * byte MTU link should get split into 2 packets of 576 - * bytes and 448 bytes. - * @param fileName the workload trace filename in one of the following - * format: <i>ASCII text, zip, gz.</i> - * @param resourceName the resource name - * @param rating the resource's PE rating - * @throws Exception This happens when creating this entity before - * initialising GridSim package or this entity name is - * <tt>null</tt> or empty - * @throws ParameterException This happens for the following conditions: - * <ul> - * <li>the entity name is null or empty - * <li> baudRate <= 0 - * <li> propDelay <= 0 - * <li> MTU <= 0 - * <li>the workload trace file name is null or empty - * <li>the resource entity name is null or empty - * <li>the resource PE rating <= 0 - * </ul> - * @pre name != null - * @pre baudRate > 0 - * @pre propDelay > 0 - * @pre MTU > 0 - * @pre fileName != null - * @pre resourceName != null - * @pre rating > 0 - * @post $none - */ - public WorkloadWithReservation(String name, double baudRate, double propDelay, int MTU, - String fileName, String resourceName, int rating) - throws ParameterException, Exception { - super( name, new SimpleLink(name+"_link", baudRate, propDelay, MTU) ); - - // check the input parameters first - String msg = name + "(): Error - "; - if (fileName == null || fileName.length() == 0) { - throw new ParameterException(msg + "invalid trace file name."); - } - else if (resourceName == null || resourceName.length() == 0) { - throw new ParameterException(msg + "invalid resource name."); - } - else if (rating <= 0) { - throw new ParameterException(msg+"resource PE rating must be > 0."); - } - - System.out.println(name + ": Creating a workload object ..."); - init(fileName, resourceName, rating); - } - - /** - * Create a new Workload object <b>with</b> the network extension. - * This means this entity directly sends Gridlets to a destination resource - * through a link. The link is automatically created by this constructor. - * - * @param name this entity name - * @param link the link that will be used to connect this Workload - * to another entity or a Router. - * @param fileName the workload trace filename in one of the following - * format: <i>ASCII text, zip, gz.</i> - * @param resourceName the resource name - * @param rating the resource's PE rating - * @throws Exception This happens when creating this entity before - * initialising GridSim package or this entity name is - * <tt>null</tt> or empty - * @throws ParameterException This happens for the following conditions: - * <ul> - * <li>the entity name is null or empty - * <li>the link is empty - * <li>the workload trace file name is null or empty - * <li>the resource entity name is null or empty - * <li>the resource PE rating <= 0 - * </ul> - * @pre name != null - * @pre link != null - * @pre fileName != null - * @pre resourceName != null - * @pre rating > 0 - * @post $none - */ - public WorkloadWithReservation(String name, Link link, String fileName, - String resourceName, int rating) - throws ParameterException, Exception { - super(name, link); - - // check the input parameters first - String msg = name + "(): Error - "; - if (fileName == null || fileName.length() == 0) { - throw new ParameterException(msg + "invalid trace file name."); - } - else if (resourceName == null || resourceName.length() == 0) { - throw new ParameterException(msg + "invalid resource name."); - } - else if (rating <= 0) { - throw new ParameterException(msg+"resource PE rating must be > 0."); - } - - System.out.println(name + ": Creating a workload object ..."); - init(fileName, resourceName, rating); - } - - /** - * Gets the probability of a job in the workload - * be an advance reservation - * @return the reservation probability - */ - public double getReservationProbability() { - return reservProbability_; - } - - /** - * Sets the probability of a job in the workload - * be an advance reservation - * @param probability the reservation probability - */ - public void setReservationProbability(double probability) { - reservProbability_ = probability; - } - - /** - * Gets how long in advance an advance reservation has to - * be made. The time in advance is how long in advance to - * the submission time included in the log the reservation - * has to be made - * @return the time in advance - */ - public double getARTimeInAdvance() { - return timeInAdvance_; - } - - /** - * Sets how long in advance an advance reservation has to - * be made. The time in advance is how long in advance to - * the submission time included in the log the reservation - * has to be made - * @param time the time in advance - */ - public void setARTimeInAdvance(double time) { - timeInAdvance_ = time; - } - - /** - * Initialises all the attributes - * @param fileName trace file name - * @param resourceName resource entity name - * @param rating resource PE rating - * @pre $none - * @post $none - */ - private void init(String fileName, String resourceName, int rating) - { - fileName_ = fileName; - resName_ = resourceName; - resID_ = GridSim.getEntityId(resName_); - rating_ = rating; - gridletID_ = 1; // starts at 1 to make it the same as in a trace file - list_ = null; - size_ = Link.DEFAULT_MTU; - - timeInAdvance_ = 60 * 60; // one hour - reservProbability_ = 0D; - numGen_ = new Random(seed_); - - // if using Standard Workload Format -- don't forget to substract by 1 - // since an array starts at 0, but the field in a trace starts at 1 - JOB_NUM = 1 - 1; - SUBMIT_TIME = 2 - 1; - RUN_TIME = 4 - 1; - NUM_PROC = 5 - 1; - REQ_NUM_PROC = 8 - 1; - REQ_RUN_TIME = 9 - 1; - - COMMENT = ";"; // semicolon means the start of a comment - MAX_FIELD = 18; // standard workload format has 18 fields - fieldArray_ = null; - } - - /** - * Sets a Gridlet file size (in byte) for sending to/from a resource. - * @param size a Gridlet file size (in byte) - * @return <tt>true</tt> if it is successful, <tt>false</tt> otherwise - * @pre size > 0 - * @post $none - */ - public boolean setGridletFileSize(int size) { - if (size < 0) { - return false; - } - - size_ = size; - return true; - } - - /** - * Identifies the start of a comment line. Hence, a line that starts - * with a given comment will be ignored. - * @param comment a character that denotes the start of a comment, - * e.g. ";" or "#" - * @return <tt>true</tt> if it is successful, <tt>false</tt> otherwise - * @pre comment != null - * @post $none - */ - public boolean setComment(String comment) - { - boolean success = false; - if (comment != null && comment.length() > 0) - { - COMMENT = comment; - success = true; - } - return success; - } - - /** - * Tells this class what to look in the trace file. - * This method should be called before the start of the simulation. - * <p> - * By default, this class follows the standard workload format as specified - * in <a href="http://www.cs.huji.ac.il/labs/parallel/workload/"> - * http://www.cs.huji.ac.il/labs/parallel/workload/</a> <br> - * However, you can use other format by calling this method. - * <p> - * The parameters must be a positive integer number starting from 1. - * A special case is where <tt>jobNum == -1</tt>, meaning the job or - * gridlet ID starts at 1. - * - * @param maxField max. number of field/column in one row - * @param jobNum field/column number for locating the job ID - * @param submitTime field/column number for locating the job submit time - * @param runTime field/column number for locating the job run time - * @param numProc field/column number for locating the number of PEs - * required to run a job - * @return <tt>true</tt> if successful, <tt>false</tt> otherwise - * @pre maxField > 0 - * @pre submitTime > 0 - * @pre runTime > 0 - * @pre numProc > 0 - * @post $none - */ - public boolean setField(int maxField, int jobNum, int submitTime, - int runTime, int numProc) - { - // need to substract by 1 since array starts at 0. Need to convert, - // position in a field into the index of the array - if (jobNum > 0) { - JOB_NUM = jobNum - 1; - } - else if (jobNum == 0) - { - System.out.println(super.get_name() + - ".setField(): Invalid job number field."); - return false; - } - else { - JOB_NUM = -1; - } - - // get the max. number of field - if (maxField > 0) { - MAX_FIELD = maxField; - } - else - { - System.out.println(super.get_name() + - ".setField(): Invalid max. number of field."); - return false; - } - - // get the submit time field - if (submitTime > 0) { - SUBMIT_TIME = submitTime - 1; - } - else - { - System.out.println(super.get_name() + - ".setField(): Invalid submit time field."); - return false; - } - - // get the run time field - if (runTime > 0) { - REQ_RUN_TIME = runTime - 1; - } - else - { - System.out.println(super.get_name() + - ".setField(): Invalid run time field."); - return false; - } - - // get the number of processors field - if (numProc > 0) { - REQ_NUM_PROC = numProc - 1; - } - else - { - System.out.println(super.get_name() + - ".setField(): Invalid number of processors field."); - return false; - } - - return true; - } - - /** - * Gets a list of completed Gridlets - * @return a list of Gridlets - * @pre $none - * @post $none - */ - public ArrayList getGridletList() { - return list_; - } - - /** - * Prints the Gridlet objects - * @param history <tt>true</tt> means printing each Gridlet's history, - * <tt>false</tt> otherwise - * @pre $none - * @post $none - */ - public void printGridletList(boolean history) - { - String name = super.get_name(); - int size = list_.size(); - Gridlet gridlet; - - String indent = " "; - System.out.println(); - System.out.println("========== OUTPUT for " + name + " =========="); - System.out.println("Gridlet_ID" + indent + "STATUS" + indent + - "Resource_ID" + indent + "Cost"); - - int i = 0; - for (i = 0; i < size; i++) - { - gridlet = (Gridlet) list_.get(i); - System.out.print(indent + gridlet.getGridletID() + indent - + indent); - - // get the status of a Gridlet - System.out.print( gridlet.getGridletStatusString() ); - System.out.println( indent + indent + gridlet.getResourceID() + - indent + indent + gridlet.getProcessingCost() ); - } - - System.out.println(); - if (history == true) - { - // a loop to print each Gridlet's history - System.out.println(); - for (i = 0; i < size; i++) - { - gridlet = (Gridlet) list_.get(i); - System.out.println( gridlet.getGridletHistory() ); - - System.out.print("Gridlet #" + gridlet.getGridletID() ); - System.out.println(", length = " + gridlet.getGridletLength() - + ", finished so far = " - + gridlet.getGridletFinishedSoFar() ); - System.out.println("========================================="); - System.out.println(); - } - } - } - - /** - * Reads from a given file when the simulation starts running. - * Then submits Gridlets to a resource and collects them before exiting. - * To collect the completed Gridlets, use {@link #getGridletList()} - * @pre $none - * @post $none - */ - public void body() { - System.out.println(); - System.out.println(super.get_name() + ".body() :%%%% Start ..."); - - // create a temp array - fieldArray_ = new String[MAX_FIELD]; - - // get the resource id - if (resID_ < 0) - { - System.out.println(super.get_name() + - ".body(): Error - invalid resource name: " + resName_); - return; - } - - boolean success = false; - - // read the gz file - if (fileName_.endsWith(".gz") == true) { - success = readGZIPFile(fileName_); - } - // read the zip file - else if (fileName_.endsWith(".zip") == true) { - success = readZipFile(fileName_); - } - // read from uncompressed file as well - else { - success = readFile(fileName_); - } - - // if all the gridlets have been submitted - if (!success ) { - System.out.println(super.get_name() + - ".body(): Error - unable to parse from a file."); - return; - } - - System.out.println(super.get_name() + ": Collecting Gridlets ..."); - list_ = new ArrayList(gridletID_ + 1); - - Object data = null; - Gridlet gl = null; - - int counter = 1; // starts at 1, since gridletID_ starts at 1 too - Sim_event ev = new Sim_event(); - Object[] reservObj = null; - - while ( Sim_system.running() - && counter < gridletID_ ) { - - super.sim_get_next(ev); // get the next available event - data = ev.get_data(); // get the event's data - - // handle ping request - if (ev.get_tag() == GridSimTags.INFOPKT_SUBMIT) { - processPingRequest(ev); - continue; - } - else if (ev.get_tag() == RESERVE_RESOURCES) { - - reservObj = (Object[])ev.get_data(); - - double startTime = (Double)reservObj[0]; - int duration = (Integer)reservObj[1]; - Gridlet resGl = (Gridlet)reservObj[2]; - - // creates a new reservation - Reservation reservation = null; - reservation = super.createReservation(startTime, duration, resGl.getNumPE(), resID_); - - success = true; - if(reservation == null) { - success = false; - } - - // commit the reservation - if(success) { - // for a reservation with an even number, commits straightaway - // without sending any Gridlets yet - success = super.commitReservation(reservation.getID()); - - // submit the gridlet if success - if(success) { - - // sets the reservation id of this gridlet - resGl.setReservationID(reservation.getID()); - - // submit the gridlet to the resource - super.send(super.output, GridSimTags.SCHEDULE_NOW, GridSimTags.GRIDLET_SUBMIT, - new IO_data(resGl, resGl.getGridletFileSize(), resID_) ); - } - // if the reservation fails, then sets the status of the - // gridlet to failed and adds the gridlet to the list - else { - try { - resGl.setGridletStatus(Gridlet.FAILED); - } - catch(Exception ex) { - - } - list_.add(resGl); - } - } - counter++; - } - - // get the Gridlet data - else if (data != null && data instanceof Gridlet) { - gl = (Gridlet) data; - list_.add(gl); - counter++; - } - - // if all the Gridlets have been collected - if (counter == gridletID_) { - break; - } - } - - // shut down all the entities, including GridStatistics entity since - // we used it to record certain events. - shutdownGridStatisticsEntity(); - shutdownUserEntity(); - terminateIOEntities(); - - System.out.println(super.get_name() + ".body() : %%%% Exit ..."); - } - - //////////////////////// PROTECTED METHODS /////////////////////// - - /** - * Processes a ping request. - * @param ev a Sim_event object - * @pre ev != null - * @post $none - */ - protected void processPingRequest(Sim_event ev) - { - InfoPacket pkt = (InfoPacket) ev.get_data(); - pkt.setTag(GridSimTags.INFOPKT_RETURN); - pkt.setDestID( pkt.getSrcID() ); - - // sends back to the sender - super.send(super.output, GridSimTags.SCHEDULE_NOW, - GridSimTags.INFOPKT_RETURN, - new IO_data(pkt, pkt.getSize(), pkt.getSrcID()) ); - } - - //////////////////////// PRIVATE METHODS /////////////////////// - - /** - * Breaks a line of string into many fields. - * @param line a line of string - * @param lineNum a line number - * @pre line != null - * @pre lineNum > 0 - * @post $none - */ - private void parseValue(String line, int lineNum) - { - // skip a comment line - if (line.startsWith(COMMENT) == true) { - return; - } - - String[] sp = line.split("\\s+"); // split the fields based on a space - int i; // a counter - int len = 0; // length of a string - int index = 0; // the index of an array - - // check for each field in the array - for (i = 0; i < sp.length; i++) - { - len = sp[i].length(); // get the length of a string - - // if it is empty then ignore - if (len == 0) { - continue; - } - // if not, then put into the array - else - { - fieldArray_[index] = sp[i]; - index++; - } - } - - if (index == MAX_FIELD) { - extractField(fieldArray_, lineNum); - } - } - - /** - * Extracts relevant information from a given array - * @param array an array of String - * @param line a line number - * @pre array != null - * @pre line > 0 - */ - private void extractField(String[] array, int line) - { - try - { - Integer obj = null; - - // get the job number - int id = 0; - if (JOB_NUM == IRRELEVANT) { - id = gridletID_; - } - else - { - obj = new Integer( array[JOB_NUM].trim() ); - id = obj.intValue(); - } - - // get the submit time - Long l = new Long( array[SUBMIT_TIME].trim() ); - long submitTime = l.intValue(); - - // get the run time - obj = new Integer( array[REQ_RUN_TIME].trim() ); - int runTime = obj.intValue(); - - // if the required run time field is ignored, then use - // the actual run time - if (runTime == IRRELEVANT) - { - obj = new Integer( array[RUN_TIME].trim() ); - runTime = obj.intValue(); - } - - // according to the SWF manual, runtime of 0 is possible due - // to rounding down. E.g. runtime is 0.4 seconds -> runtime = 0 - if (runTime == 0) { - runTime = 1; // change to 1 second - } - - // get the number of allocated processors - obj = new Integer( array[REQ_NUM_PROC].trim() ); - int numProc = obj.intValue(); - - // if the required num of allocated processors field is ignored - // or zero, then use the actual field - if (numProc == IRRELEVANT || numProc == 0) - { - obj = new Integer( array[NUM_PROC].trim() ); - numProc = obj.intValue(); - } - - // finally, check if the num of PEs required is valid or not - if (numProc <= 0) - { - System.out.println(super.get_name() + ": Warning - job #" - + id + " at line " + line + " requires " + numProc - + " CPU. Change to 1 CPU."); - numProc = 1; - } - - // creates a submission/reservation event - submitGridlet(id, submitTime, runTime, numProc); - } - catch (Exception e) - { - System.out.println(super.get_name() + - ": Exception in reading file at line #" + line); - e.printStackTrace(); - } - } - - /** - * Creates a Gridlet with the given information, then submit it to a - * resource - * @param id a Gridlet ID - * @param submitTime Gridlet's submit time - * @param runTime Gridlet's run time - * @param numProc number of processors - * @pre id >= 0 - * @pre submitTime >= 0 - * @pre runTime >= 0 - * @pre numProc > 0 - * @post $none - */ - protected void submitGridlet(int id, long submitTime, int runTime, int numProc) { - // create the gridlet - int len = runTime * rating_; // calculate a job length for each PE - Gridlet gridlet = new Gridlet(id, len, size_, size_); - gridlet.setUserID( super.get_id() ); // set the owner ID - gridlet.setNumPE(numProc); // set the requested num of proc - - // check the probability of creating an advance reservation - double probAR = Math.abs(numGen_.nextDouble()); - - // check the submit time - if (submitTime < 0) { - submitTime = 0; - } - - if(probAR <= reservProbability_) { - - // calculate how long in advance the reservation is made - double timeInAdvance = timeInAdvance_ * numGen_.nextDouble(); - - // convert to seconds - double timeToReserve = submitTime - timeInAdvance; - - // if the time the reservation would be done has already - // past, then consider now as the submission time - if(timeToReserve <= 0.0D) { - timeToReserve = GridSimTags.SCHEDULE_NOW; - } - - //TODO To check the duration of the advance reservation later - Object[] reservObj = new Object[3]; - reservObj[0] = new Double(submitTime); // start time of the reservation - reservObj[1] = (int) runTime + 1; // the advance reservation duration - reservObj[2] = gridlet; // the gridlet to be submitted - - // submit an internal event to create a reservation for this gridlet - super.send(super.get_id(), timeToReserve, RESERVE_RESOURCES, reservObj); - } - else { - // printing to inform user - if (gridletID_ == 1 || gridletID_ % INTERVAL == 0) { - System.out.println(super.get_name() + ": Submitting Gridlets to " + - resName_ + " ..."); - } - - // submit a gridlet to resource - super.send(super.output, submitTime, GridSimTags.GRIDLET_SUBMIT, - new IO_data(gridlet, gridlet.getGridletFileSize(), resID_) ); - } - - gridletID_++; // increment the counter - } - - /** - * Reads a text file one line at the time - * @param fileName a file name - * @return <tt>true</tt> if reading a file is successful, <tt>false</tt> - * otherwise. - * @pre fileName != null - * @post $none - */ - private boolean readFile(String fileName) - { - boolean success = false; - BufferedReader reader = null; - try - { - FileInputStream file = new FileInputStream(fileName); - InputStreamReader input = new InputStreamReader(file); - reader = new BufferedReader(input); - - // read one line at the time - int line = 1; - while ( reader.ready() ) - { - parseValue(reader.readLine(), line); - line++; - } - - reader.close(); // close the file - success = true; - } - catch (FileNotFoundException f) - { - System.out.println(super.get_name() + - ": Error - the file was not found: " + f.getMessage()); - } - catch (IOException e) - { - System.out.println(super.get_name() + - ": Error - an IOException occurred: " + e.getMessage()); - } - finally - { - if (reader != null) - { - try { - reader.close(); // close the file - } - catch (IOException e) - { - System.out.println(super.get_name() + - ": Error - an IOException occurred: " + e.getMessage()); - } - } - } - - return success; - } - - /** - * Reads a gzip file one line at the time - * @param fileName a gzip file name - * @return <tt>true</tt> if reading a file is successful, <tt>false</tt> - * otherwise. - * @pre fileName != null - * @post $none - */ - private boolean readGZIPFile(String fileName) - { - boolean success = false; - BufferedReader reader = null; - try - { - FileInputStream file = new FileInputStream(fileName); - GZIPInputStream gz = new GZIPInputStream(file); - InputStreamReader input = new InputStreamReader(gz); - reader = new BufferedReader(input); - - // read one line at the time - int line = 1; - while ( reader.ready() ) - { - parseValue(reader.readLine(), line); - line++; - } - - reader.close(); // close the file - success = true; - } - catch (FileNotFoundException f) - { - System.out.println(super.get_name() + - ": Error - the file was not found: " + f.getMessage()); - } - catch (IOException e) - { - System.out.println(super.get_name() + - ": Error - an IOException occurred: " + e.getMessage()); - } - finally - { - if (reader != null) - { - try { - reader.close(); // close the file - } - catch (IOException e) - { - System.out.println(super.get_name() + - ": Error - an IOException occurred: " + e.getMessage()); - } - } - } - - return success; - } - - /** - * Reads a Zip file. Iterating through each entry and reading it one line - * at the time. - * @param fileName a zip file name - * @return <tt>true</tt> if reading a file is successful, <tt>false</tt> - * otherwise. - * @pre fileName != null - * @post $none - */ - private boolean readZipFile(String fileName) - { - boolean success = false; - ZipFile zipFile = null; - try - { - InputStreamReader input = null; - BufferedReader reader = null; - - // ZipFile offers an Enumeration of all the files in the Zip file - zipFile = new ZipFile(fileName); - for (Enumeration e = zipFile.entries(); e.hasMoreElements();) - { - success = false; // reset the value again - ZipEntry zipEntry = (ZipEntry) e.nextElement(); - - input = new InputStreamReader(zipFile.getInputStream(zipEntry)); - reader = new BufferedReader(input); - - // read one line at the time - int line = 1; - while ( reader.ready() ) - { - parseValue(reader.readLine(), line); - line++; - } - - reader.close(); // close the file - success = true; - } - } - catch (IOException e) - { - System.out.println(super.get_name() + - ": Error - an IOException occurred: " + e.getMessage()); - } - finally - { - if (zipFile != null) - { - try { - zipFile.close(); // close the file - } - catch (IOException e) - { - System.out.println(super.get_name() + - ": Error - an IOException occurred: " + e.getMessage()); - } - } - } - - return success; - } -} Deleted: branches/gridsim4.0-branch3/examples/examples/ar/ARTest.java =================================================================== --- branches/gridsim4.0-branch3/examples/examples/ar/ARTest.java 2007-11-14 11:23:50 UTC (rev 80) +++ branches/gridsim4.0-branch3/examples/examples/ar/ARTest.java 2007-11-29 01:04:02 UTC (rev 81) @@ -1,288 +0,0 @@ -/* - * Author Marcos Dias de Assuncao - * Date: September 2007 - * Description: A simple program to demonstrate of how to use basic - * advanced reservation functionalities, such as create, commit - * and status. - */ - -package examples.ar; - -import gridsim.GridSim; -import gridsim.Gridlet; -import gridsim.GridletList; -import gridsim.turbo.Reservation; -import gridsim.turbo.ReservationRequester; -import gridsim.turbo.AvailabilityInfo; - -import java.util.ArrayList; -import java.util.Calendar; -import java.util.LinkedList; -import java.util.Random; - -/** - * A user entity that reserves a resource in advance. - * In this example, only explore some functionalities, such as: - * - requests a new advanced reservation - * - requests a new immediate reservation. Immediate reservation means use - * current time as the starting time - * - commits an accepted reservation - * - checks the status of a reservation - */ -public class ARTest extends ReservationRequester { - private GridletList list_; // a list containing new Gridlets - private GridletList receiveList_; // a list containing completed Gridlets - private int failReservation_; // number of reservations failed - - // time constant values - private final int SEC = 1; // 1 second - private final int MIN = 60 * SEC; // 1 min in seconds - private final int HOUR = 60 * MIN; // 1 hour in minutes - private final int DAY = 24 * HOUR; // 1 day in hours - - - /** - * Creates a new grid user entity - * @param name the Entity name of this object - * @param baud_rate the communication speed - * @param totalJob number of Gridlets to be created - * @throws Exception This happens when creating this entity before - * initializing GridSim package or the entity name is - * <tt>null</tt> or empty - * @see gridsim.GridSim#init(int, Calendar, boolean) - */ - public ARTest(String name, double baud_rate, int totalJob) throws Exception { - super(name, baud_rate); - this.receiveList_ = new GridletList(); - this.failReservation_ = 0; - - // create Gridlets - list_ = createGridlet( totalJob, super.get_id() ); - - System.out.println("Creating a grid user entity with name = " + - name + ", and id = " + super.get_id()); - System.out.println(name + ": Creating " + totalJob + " Gridlets."); - } - - /** - * The core method that handles communications among GridSim entities. - */ - public void body() { - LinkedList resList; - - // waiting to get list of resources. Since GridSim package uses - // multi-threaded environment, your request might arrive earlier - // before one or more grid resource entities manage to register - // themselves to GridInformationService (GIS) entity. - // Therefore, it's better to wait in the first place - while (true) { - // need to pause for a while to wait GridResources finish - // registering to GIS - super.gridSimHold(2*SEC); // wait for 2 seconds - - resList = getGridResourceList(); - if (resList.size() > 0) { - break; - } - else { - System.out.println(super.get_name() + - ": Waiting to get list of resources ..."); - } - } - - // list of resource IDs that can support Advanced Reservation (AR) - ArrayList resARList = new ArrayList(); - - // list of resource names that can support AR - ArrayList resNameList = new ArrayList(); - - int totalPE = 0; - int i = 0; - Integer intObj = null; // resource ID - String name; // resource name - - // a loop that gets a list of resources that can support AR - for (i = 0; i < resList.size(... [truncated message content] |
From: <xu...@us...> - 2007-11-14 11:23:52
|
Revision: 80 http://gridsim.svn.sourceforge.net/gridsim/?rev=80&view=rev Author: xulio Date: 2007-11-14 03:23:50 -0800 (Wed, 14 Nov 2007) Log Message: ----------- Creating a private branch of trunk to integrate parallel extensions Added Paths: ----------- branches/gridsim-4.1-parallel/ Copied: branches/gridsim-4.1-parallel (from rev 79, trunk) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mar...@us...> - 2007-11-07 21:56:16
|
Revision: 79 http://gridsim.svn.sourceforge.net/gridsim/?rev=79&view=rev Author: marcos_dias Date: 2007-11-07 13:56:19 -0800 (Wed, 07 Nov 2007) Log Message: ----------- A problem that prevented the ResourceWindow from updating its components properly when resized has been fixed. This problem could be noticed on Windows machines. Modified Paths: -------------- branches/gridsim4.0-branch3/source/gridsim/gui/ResourceWindow.java Modified: branches/gridsim4.0-branch3/source/gridsim/gui/ResourceWindow.java =================================================================== --- branches/gridsim4.0-branch3/source/gridsim/gui/ResourceWindow.java 2007-11-07 03:40:40 UTC (rev 78) +++ branches/gridsim4.0-branch3/source/gridsim/gui/ResourceWindow.java 2007-11-07 21:56:19 UTC (rev 79) @@ -130,17 +130,19 @@ // the jobs or advance reservations displayed by this window private ArrayList<ScheduleItem> scheduledItems_; - // time unit used to display information on the screen - private int timeUnit_ = GridSimVisualizer.TIME_UNIT_SECOND; - // the settings object private GUISettings settings_; + + // time unit used to display information on the screen + private int timeUnit_ = GridSimVisualizer.TIME_UNIT_SECOND; private static final int WINDOW_WIDTH = 1100; private static final int WINDOW_HEIGHT = 300; private static final int SHIFT_X = 30; private static final int SHIFT_Y = 25; private static final int SHIFT_BOTTOM = 15; + private static final float PROPORTION_LEFT_PANEL = 0.6f; + private static final float PROPORTION_RIGHT_PANEL = 1f - PROPORTION_LEFT_PANEL; /** * Creates the scheduling window. @@ -163,7 +165,6 @@ // initialise the left and right panels initPanels(); ResizeFrame adapter = new ResizeFrame(); - adapter.frame_ = this; super.addComponentListener(adapter); super.setLocation(DefaultGridSimVisualizer.WINDOW_WIDTH, windowId * 200); @@ -193,28 +194,32 @@ switch(type){ case AllocationAction.ITEM_ARRIVED: - case AllocationAction.ITEM_STATUS_CHANGED: for(ScheduleItem item : list){ - itemPanel_.updateItem(item); + itemPanel_.insertNewItem(item); } updateResourceWindow(); break; + case AllocationAction.ITEM_STATUS_CHANGED: + itemPanel_.updateItem(list.getLast()); + updateResourceWindow(); + break; + case AllocationAction.ITEM_SCHEDULED: for(ScheduleItem item : list){ scheduledItems_.add(item); double finishTime = item.getFinishTime(); settings_.setTimeSpan(finishTime); - itemPanel_.updateItem(item); } + itemPanel_.updateItem(list.getLast()); updateResourceWindow(); break; case AllocationAction.ITEM_CANCELLED: for(ScheduleItem item : list){ - itemPanel_.updateItem(item); scheduledItems_.remove(item); } + itemPanel_.updateItem(list.getLast()); updateResourceWindow(); break; @@ -263,10 +268,9 @@ // calculates the size of the two panels // to be added to the window - int leftPanelWidth = (int)((super.getWidth()/3.5) * 2.3); - int leftPanelHeight = (int)((super.getHeight()) - 20); - int gridletPanelWidth = (int)((super.getWidth()/3.5) * 1.2); - int gridletPanelHeight = leftPanelHeight; + int leftPanelWidth = (int)((super.getWidth()) * PROPORTION_LEFT_PANEL); + int panelsHeight = (int)((super.getHeight()) - 20); + int gridletPanelWidth = (int)((super.getWidth()) * PROPORTION_RIGHT_PANEL) - 10; int leftPanelXPos = 0; int gridletPanelXPos = leftPanelXPos + leftPanelWidth; @@ -274,7 +278,7 @@ leftPanel_.setOpaque(true); leftPanel_.setLayout(new BorderLayout()); leftPanel_.setLocation(leftPanelXPos, 0); - leftPanel_.setSize(leftPanelWidth, leftPanelHeight); + leftPanel_.setSize(leftPanelWidth, panelsHeight); Border raisedetched = BorderFactory.createEtchedBorder(EtchedBorder.RAISED); JPanel instructionPanel = new JPanel(); @@ -361,7 +365,7 @@ itemPanel_ = new ItemPanel(); itemPanel_.setLocation(gridletPanelXPos, 0); - itemPanel_.setSize(gridletPanelWidth, gridletPanelHeight); + itemPanel_.setSize(gridletPanelWidth, panelsHeight); this.getContentPane().add(leftPanel_); this.getContentPane().add(itemPanel_); @@ -390,30 +394,28 @@ * that compose the resource window interface */ class ResizeFrame extends ComponentAdapter { - JFrame frame_ = null; public ResizeFrame() { super(); } public void componentResized(ComponentEvent evt) { - if(evt.getSource() == frame_) { - int windowWidth = frame_.getWidth(); - int windowHeight = frame_.getHeight(); + + // calculates the size of the two panels + // to be added to the window + int leftPanelWidth = (int)((ResourceWindow.this.getWidth()) * PROPORTION_LEFT_PANEL); + int panelsHeight = (int)((ResourceWindow.this.getHeight()) - 20); + int gridletPanelWidth = (int)((ResourceWindow.this.getWidth()) * PROPORTION_RIGHT_PANEL) - 10; + int leftPanelXPos = 0; + int gridletPanelXPos = leftPanelXPos + leftPanelWidth; + + leftPanel_.setLocation(leftPanelXPos, 0); + leftPanel_.setSize(leftPanelWidth, panelsHeight); + leftPanel_.updateUI(); - int leftPanelWidth = (int)((windowWidth/3.5) * 2.3); - int leftPanelHeight = (int)((windowHeight) - 20); - int gridletPanelWidth = (int)((windowWidth/3.5) * 1.2); - int gridletPanelHeight = leftPanelHeight; - int leftPanelXPos = 0; - int gridletPanelXPos = leftPanelXPos + leftPanelWidth; - - leftPanel_.setLocation(leftPanelXPos, 0); - leftPanel_.setSize(leftPanelWidth, leftPanelHeight); - - itemPanel_.setLocation(gridletPanelXPos, 0); - itemPanel_.setSize(gridletPanelWidth, gridletPanelHeight); - } + itemPanel_.setLocation(gridletPanelXPos, 0); + itemPanel_.setSize(gridletPanelWidth, panelsHeight); + itemPanel_.updateUI(); } } @@ -461,13 +463,12 @@ // been selected ScheduleItem highlightedItem_ = null; - public DrawingPanel(){ + public DrawingPanel() { super(); super.setBackground(backgroundColor_); } protected synchronized void paintComponent(Graphics g2) { - super.paintComponent(g2); Graphics2D g2D = (Graphics2D)g2; g2D.setFont(graphFont_); @@ -487,7 +488,7 @@ (int) ((numPE_) * scaleY_) + SHIFT_Y + SHIFT_BOTTOM)); drawSchedulingQueue(g2D); - drawGridsAndAxes(timeSpan, g2D); + drawGridsAndAxes(g2D); super.revalidate(); } @@ -496,8 +497,10 @@ * @param timeSpan the time span of the simulation * @param g2D the graphics 2D context */ - private void drawGridsAndAxes(double timeSpan, Graphics2D g2D) { + private void drawGridsAndAxes(Graphics2D g2D) { + double timeSpan = settings_.getTimeSpan(); + String text = null; g2D.setColor(timeGridColor_); g2D.setStroke(dashedStroke_); @@ -775,6 +778,32 @@ } /** + * Inserts a Gridlet to the JList and the vector of Gridlets + * @param insertItem the item to be inserted in the vector of + * schedule items and the JList + */ + public void insertNewItem(ScheduleItem insertItem) { + if(insertItem == null) + return; + + DefaultListModel listModel; + + int index = items_.size(); + items_.add(index, insertItem); + + listModel = (DefaultListModel)itemQueueJList_.getModel(); + listModel.add(index, itemSummary(insertItem)); + try { + itemQueueJList_.ensureIndexIsVisible(index); + itemQueueJList_.setSelectedIndex(index); + } + catch(Exception ex) { + // cannot happen + } + updateItemDetails(insertItem); + } + + /** * Updates information in the list. This method checks whether * the Item is already in the list or not. If it is, just update * the details window. Otherwise, inserts the item in @@ -782,16 +811,17 @@ * @param item the item whose information has to be updated */ protected void updateItem(ScheduleItem item) { + if(item == null) + return; + int position = getPosition(item.getID(), item.getSenderID(), item.isAdvanceReservation()); - if(position < 0) { - position = insertNewItem(item); - } + int selectedIndex = (int) itemQueueJList_.getSelectedIndex(); - itemQueueJList_.ensureIndexIsVisible(position); - itemQueueJList_.setSelectedIndex(position); - updateItemDetails(item); + if(selectedIndex == position) { + updateItemDetails(item); + } } /** @@ -903,43 +933,6 @@ } return -1; } - - /** - * Inserts a Gridlet to the JList and the vector of Gridlets - * @param insertItem the item to be inserted in the vector of - * schedule items and the JList - */ - private int insertNewItem(ScheduleItem insertItem) { - int sizeVector = items_.size(); - double submittedTime = insertItem.getSubmissionTime(); - int i; - - ScheduleItem item; - DefaultListModel listModel; - - for(i=0; i<sizeVector; i++) { - item = items_.get(i); - - if(submittedTime < item.getSubmissionTime()) { - items_.add(i, insertItem); - break; - } - - if(submittedTime == item.getSubmissionTime() - && insertItem.getID() == item.getID() - && insertItem.isAdvanceReservation() == item.isAdvanceReservation() - && insertItem.getSenderID() == item.getSenderID() ) { - return i; - } - } - - if(i == sizeVector) - items_.add(insertItem); - - listModel = (DefaultListModel)itemQueueJList_.getModel(); - listModel.add(i, itemSummary(insertItem)); - return i; - } } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |