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] |