[haizea-commit] r764 - in branches/1.1/src/haizea: core core/scheduler pluggable/policies
haizea-commit at mailman.cs.uchicago.edu
haizea-commit at mailman.cs.uchicago.edu
Thu Jan 14 23:20:03 CST 2010
Author: borja
Date: 2010-01-14 23:20:03 -0600 (Thu, 14 Jan 2010)
New Revision: 764
Modified:
branches/1.1/src/haizea/core/leases.py
branches/1.1/src/haizea/core/scheduler/lease_scheduler.py
branches/1.1/src/haizea/core/scheduler/slottable.py
branches/1.1/src/haizea/core/scheduler/vm_scheduler.py
branches/1.1/src/haizea/pluggable/policies/preemption.py
Log:
- Optimized rescheduling of deadline leases
- Allow leases to be preempted at any point, not just at the "last vm"
- Enable rescheduling of deadline leases when a lease ends prematurely
Modified: branches/1.1/src/haizea/core/leases.py
===================================================================
--- branches/1.1/src/haizea/core/leases.py 2010-01-14 04:09:27 UTC (rev 763)
+++ branches/1.1/src/haizea/core/leases.py 2010-01-15 05:20:03 UTC (rev 764)
@@ -474,7 +474,10 @@
"""Returns the last VM reservation for this lease.
"""
- return self.vm_rrs[-1]
+ if len(self.vm_rrs) > 0:
+ return self.vm_rrs[-1]
+ else:
+ return None
def get_vmrr_at(self, time):
"""...
@@ -509,6 +512,30 @@
vmrr = self.get_last_vmrr()
return vmrr.end
+ def get_accumulated_duration_at(self, time):
+ """Returns the amount of time required to fulfil the entire
+ requested duration of the lease at a given time.
+
+ """
+ t = TimeDelta(0)
+ for vmrr in self.vm_rrs:
+ if time >= vmrr.end:
+ t += vmrr.end - vmrr.start
+ elif time >= vmrr.start and time < vmrr.end:
+ t += time -vmrr.start
+ break
+ else:
+ break
+ return t
+
+
+ def get_remaining_duration_at(self, time):
+ """Returns the amount of time required to fulfil the entire
+ requested duration of the lease at a given time.
+
+ """
+ return self.duration.requested - self.get_accumulated_duration_at(time)
+
def append_vmrr(self, vmrr):
"""Adds a VM resource reservation to the lease.
@@ -1038,7 +1065,7 @@
known duration of the lease.
ONLY for simulations.
- """
+ """
return self.known - self.accumulated
def __repr__(self):
Modified: branches/1.1/src/haizea/core/scheduler/lease_scheduler.py
===================================================================
--- branches/1.1/src/haizea/core/scheduler/lease_scheduler.py 2010-01-14 04:09:27 UTC (rev 763)
+++ branches/1.1/src/haizea/core/scheduler/lease_scheduler.py 2010-01-15 05:20:03 UTC (rev 764)
@@ -33,6 +33,7 @@
from haizea.common.utils import round_datetime, get_config, get_clock, get_policy, get_persistence
from haizea.core.leases import Lease
from haizea.core.scheduler import RescheduleLeaseException, NormalEndLeaseException, InconsistentLeaseStateError, EnactmentError, UnrecoverableError, NotSchedulableException, EarliestStartingTime
+from haizea.core.scheduler.vm_scheduler import VMResourceReservation
from haizea.core.scheduler.slottable import ResourceReservation
from operator import attrgetter
@@ -432,17 +433,18 @@
self._handle_end_rr(vmrr)
# TODO: Exception handling
self.vm_scheduler._handle_unscheduled_end_vm(lease, vmrr)
- self._handle_end_lease(lease)
- get_persistence().persist_lease(lease)
# We need to reevaluate the schedule to see if there are any
# leases scheduled in the future that could be rescheduled
# to start earlier
nexttime = get_clock().get_next_schedulable_time()
- self.reevaluate_schedule(nexttime)
+ self.reevaluate_schedule(nexttime, lease)
+ self._handle_end_lease(lease)
+ get_persistence().persist_lease(lease)
- def reevaluate_schedule(self, nexttime):
+
+ def reevaluate_schedule(self, nexttime, ending_lease):
"""Reevaluates the schedule.
This method can be called whenever resources are freed up
@@ -461,9 +463,9 @@
## BEGIN NOT-FIT-FOR-PRODUCTION CODE
## This is only necessary because we're currently using the best-effort
## scheduling algorithm for many of the deadline leases
- future = [l for l in future if l.get_type() == Lease.BEST_EFFORT]
+ future_best_effort = [l for l in future if l.get_type() == Lease.BEST_EFFORT]
## END NOT-FIT-FOR-PRODUCTION CODE
- for l in future:
+ for l in future_best_effort:
# We can only reschedule leases in the following four states
if l.get_state() in (Lease.STATE_PREPARING, Lease.STATE_READY, Lease.STATE_SCHEDULED, Lease.STATE_SUSPENDED_SCHEDULED):
# For each reschedulable lease already scheduled in the
@@ -488,7 +490,52 @@
# scenario is that it simply replicates the previous schedule)
self.__schedule_lease(l, nexttime)
+ future_vmrrs = self.slottable.get_reservations_on_or_after(nexttime)
+ future_vmrrs = [rr for rr in future_vmrrs
+ if isinstance(rr, VMResourceReservation)
+ and rr.lease.get_type() == Lease.DEADLINE
+ and rr.lease.get_state() in (Lease.STATE_SCHEDULED, Lease.STATE_READY, Lease.STATE_SUSPENDED_SCHEDULED)]
+ leases = list(set([future_vmrr.lease for future_vmrr in future_vmrrs]))
+
+ leases.sort(key= lambda l: (l.deadline - nexttime) / l.get_remaining_duration_at(nexttime))
+ if len(leases) > 0:
+ self.logger.debug("Rescheduling future deadline leases")
+ self.slottable.save(leases)
+ feasible = True
+ node_ids = self.slottable.nodes.keys()
+ earliest = {}
+ for node in node_ids:
+ earliest[node] = EarliestStartingTime(nexttime, EarliestStartingTime.EARLIEST_NOPREPARATION)
+
+ orig_vmrrs = dict([(l,[rr for rr in future_vmrrs if rr.lease == l]) for l in leases])
+ dirtynodes = ending_lease.get_last_vmrr().resources_in_pnode.keys()
+
+ dirtynodes, cleanleases = self.vm_scheduler.find_dirty_nodes(leases, dirtynodes, orig_vmrrs)
+
+ for vmrr in [vmrr2 for vmrr2 in future_vmrrs if vmrr2.lease not in cleanleases]:
+ self.vm_scheduler.cancel_vm(vmrr)
+
+ dirtyleases = [l for l in leases if l not in cleanleases]
+
+ try:
+ (scheduled, add_vmrrs, dirtytime) = self.vm_scheduler.reschedule_deadline_leases(dirtyleases, orig_vmrrs, nexttime, earliest, nexttime, dirtytime=None)
+ except NotSchedulableException:
+ self.logger.debug("Future leases could not be rescheduled, undoing changes.")
+ feasible = False
+
+ if feasible:
+ for l in [l2 for l2 in orig_vmrrs if l2 in scheduled]:
+ for vmrr in orig_vmrrs[l]:
+ vmrr.lease.remove_vmrr(vmrr)
+
+ for lease2, vmrr in add_vmrrs.items():
+ lease2.append_vmrr(vmrr)
+ else:
+ self.slottable.restore()
+
+
+
def is_queue_empty(self):
"""Return True is the queue is empty, False otherwise"""
return self.queue.is_empty()
@@ -746,13 +793,7 @@
lease.print_contents()
def __preempt_leases_deadline(self, lease, vmrr, preempted_leases, preemption_time, nexttime):
- orig_vmrrs = dict([(l.id,l.vm_rrs[:]) for l in preempted_leases])
- orig_vmrrs_data = {}
- for orig_vmrr in orig_vmrrs.values():
- for vmrr2 in orig_vmrr:
- orig_vmrrs_data[vmrr2] = (vmrr2.start, vmrr2.end, vmrr2.prematureend, vmrr2.pre_rrs[:], vmrr2.post_rrs[:])
-
- self.slottable.push()
+ self.slottable.save(preempted_leases)
# Pre-VM RRs (if any)
for rr in vmrr.pre_rrs:
@@ -770,7 +811,7 @@
new_state = {}
durs = {}
for lease_to_preempt in preempted_leases:
- preempt_vmrr = lease_to_preempt.get_last_vmrr()
+ preempt_vmrr = lease_to_preempt.get_vmrr_at(preemption_time)
susptype = get_config().get("suspension")
@@ -779,7 +820,7 @@
if susptype == constants.SUSPENSION_NONE:
cancel = True
else:
- if preempt_vmrr.state == ResourceReservation.STATE_SCHEDULED and preempt_vmrr.start >= preemption_time:
+ if preempt_vmrr == None:
self.logger.debug("Lease was set to start in the middle of the preempting lease.")
cancel = True
else:
@@ -788,29 +829,31 @@
if not can_suspend:
self.logger.debug("Suspending the lease does not meet scheduling threshold.")
cancel = True
- else:
- orig_end = preempt_vmrr.end
- orig_prematureend = preempt_vmrr.prematureend
-
- self.vm_scheduler.preempt_vm(preempt_vmrr, preemption_time)
- durs[lease_to_preempt] = orig_end - preempt_vmrr.end
-
- if cancel:
- self.preparation_scheduler.cancel_preparation(lease_to_preempt)
- durs[lease_to_preempt] = preempt_vmrr.end - preempt_vmrr.start
+ after_vmrrs = lease_to_preempt.get_vmrr_after(preemption_time)
- active_vmrrs = lease_to_preempt.get_active_vmrrs(preemption_time)
-
- lease_to_preempt.remove_vmrr(preempt_vmrr)
- self.vm_scheduler.cancel_vm(preempt_vmrr)
+ if not cancel:
+ # Preempting
+ durs[lease_to_preempt] = lease_to_preempt.get_remaining_duration_at(preemption_time)
+ self.vm_scheduler.preempt_vm(preempt_vmrr, preemption_time)
+ susp_time = preempt_vmrr.post_rrs[-1].end - preempt_vmrr.post_rrs[0].start
+ durs[lease_to_preempt] += susp_time
+
+ else:
cancelled.append(lease_to_preempt.id)
-
- lease_state = lease_to_preempt.get_state()
- if preempt_vmrr in active_vmrrs:
- # The VMRR we're preempting is the active one
- new_state[lease_to_preempt] = Lease.STATE_READY
+
+ if preempt_vmrr != None:
+ durs[lease_to_preempt] = lease_to_preempt.get_remaining_duration_at(preempt_vmrr.start)
+
+ if preempt_vmrr.state == ResourceReservation.STATE_ACTIVE:
+ # The VMRR we're preempting is the active one
+ new_state[lease_to_preempt] = Lease.STATE_READY
+
+ lease_to_preempt.remove_vmrr(preempt_vmrr)
+ self.vm_scheduler.cancel_vm(preempt_vmrr)
else:
+ durs[lease_to_preempt] = lease_to_preempt.get_remaining_duration_at(preemption_time)
+ lease_state = lease_to_preempt.get_state()
if lease_state == Lease.STATE_ACTIVE:
# Don't do anything. The lease is active, but not in the VMs
# we're preempting.
@@ -821,8 +864,11 @@
new_state[lease_to_preempt] = None
elif lease_state != Lease.STATE_READY:
new_state[lease_to_preempt] = Lease.STATE_READY
-
-
+
+ # Cancel future VMs
+ for after_vmrr in after_vmrrs:
+ lease_to_preempt.remove_vmrr(after_vmrr)
+ self.vm_scheduler.cancel_vm(after_vmrr)
for lease_to_preempt in preempted_leases:
dur = durs[lease_to_preempt]
@@ -836,9 +882,14 @@
lease.duration.accumulated = lease.duration.requested - dur
if lease_to_preempt.id in cancelled:
+ last_vmrr = lease_to_preempt.get_last_vmrr()
+ if last_vmrr != None and last_vmrr.is_suspending():
+ override_state = Lease.STATE_SUSPENDED_PENDING
+ else:
+ override_state = None
for node in node_ids:
earliest[node] = EarliestStartingTime(nexttime, EarliestStartingTime.EARLIEST_NOPREPARATION)
- (new_vmrr, preemptions) = self.vm_scheduler.reschedule_deadline(lease_to_preempt, dur, nexttime, earliest)
+ (new_vmrr, preemptions) = self.vm_scheduler.reschedule_deadline(lease_to_preempt, dur, nexttime, earliest, override_state)
else:
for node in node_ids:
earliest[node] = EarliestStartingTime(preemption_time, EarliestStartingTime.EARLIEST_NOPREPARATION)
@@ -867,15 +918,7 @@
break
if not feasible:
- for l in preempted_leases:
- l.vm_rrs = orig_vmrrs[l.id]
- for vm_rr in l.vm_rrs:
- vm_rr.start = orig_vmrrs_data[vm_rr][0]
- vm_rr.end = orig_vmrrs_data[vm_rr][1]
- vm_rr.prematureend = orig_vmrrs_data[vm_rr][2]
- vm_rr.pre_rrs = orig_vmrrs_data[vm_rr][3]
- vm_rr.post_rrs = orig_vmrrs_data[vm_rr][4]
- self.slottable.pop()
+ self.slottable.restore()
raise NotSchedulableException, "Unable to preempt leases to make room for lease."
else:
# Pre-VM RRs (if any)
Modified: branches/1.1/src/haizea/core/scheduler/slottable.py
===================================================================
--- branches/1.1/src/haizea/core/scheduler/slottable.py 2010-01-14 04:09:27 UTC (rev 763)
+++ branches/1.1/src/haizea/core/scheduler/slottable.py 2010-01-15 05:20:03 UTC (rev 764)
@@ -569,7 +569,7 @@
@param rr: Resource reservation
@type rr: L{ResourceReservation}
- """
+ """
startitem = KeyValueWrapper(rr.start, rr)
enditem = KeyValueWrapper(rr.end, rr)
bisect.insort(self.reservations_by_start, startitem)
@@ -855,13 +855,30 @@
from haizea.core.scheduler.vm_scheduler import VMResourceReservation
return [i.value for i in self.reservations_by_end if isinstance(i.value, VMResourceReservation) and i.value.prematureend == time]
- def push(self):
+ def save(self, leases = []):
self.reservations_by_start2 = self.reservations_by_start[:]
self.reservations_by_end2 = self.reservations_by_end[:]
+
+ self.orig_vmrrs = dict([(l,l.vm_rrs[:]) for l in leases])
+ self.orig_vmrrs_data = {}
+ for orig_vmrr in self.orig_vmrrs.values():
+ for vmrr in orig_vmrr:
+ self.orig_vmrrs_data[vmrr] = (vmrr.start, vmrr.end, vmrr.prematureend, vmrr.pre_rrs[:], vmrr.post_rrs[:])
- def pop(self):
+
+ def restore(self):
self.reservations_by_start = self.reservations_by_start2
self.reservations_by_end = self.reservations_by_end2
+
+ for l in self.orig_vmrrs:
+ l.vm_rrs = self.orig_vmrrs[l]
+ for vm_rr in l.vm_rrs:
+ vm_rr.start = self.orig_vmrrs_data[vm_rr][0]
+ vm_rr.end = self.orig_vmrrs_data[vm_rr][1]
+ vm_rr.prematureend = self.orig_vmrrs_data[vm_rr][2]
+ vm_rr.pre_rrs = self.orig_vmrrs_data[vm_rr][3]
+ vm_rr.post_rrs = self.orig_vmrrs_data[vm_rr][4]
+
self.__dirty()
Modified: branches/1.1/src/haizea/core/scheduler/vm_scheduler.py
===================================================================
--- branches/1.1/src/haizea/core/scheduler/vm_scheduler.py 2010-01-14 04:09:27 UTC (rev 763)
+++ branches/1.1/src/haizea/core/scheduler/vm_scheduler.py 2010-01-15 05:20:03 UTC (rev 764)
@@ -249,11 +249,8 @@
Arguments:
vmrr -- VM RR to be preempted
t -- Time by which the VM must be preempted
- """
- # TODO: Make more general, should determine vmrr based on current time
- # This won't currently break, though, since the calling function
- # operates on the last VM RR.
- vmrr = lease.get_last_vmrr()
+ """
+ vmrr = lease.get_vmrr_at(t)
time_until_suspend = t - vmrr.start
min_duration = self.__compute_scheduling_threshold(lease)
can_suspend = time_until_suspend >= min_duration
@@ -618,8 +615,10 @@
def __schedule_deadline(self, lease, duration, nexttime, earliest, override_state):
+ earliest_time = nexttime
for n in earliest:
earliest[n].time = max(lease.start.requested, earliest[n].time)
+ earliest_time = max(earliest_time, earliest[n].time)
slack = (lease.deadline - lease.start.requested) / lease.duration.requested
if slack <= 2.0:
@@ -641,59 +640,116 @@
if vmrr == None or vmrr.end - vmrr.start != duration or vmrr.end > lease.deadline or len(preemptions)>0:
self.logger.debug("Lease #%i cannot be scheduled before deadline using best-effort." % lease.id)
- self.slottable.push()
- future_vmrrs = self.slottable.get_reservations_on_or_after(min([e.time for e in earliest.values()]))
+ self.slottable.save()
+
+ dirtynodes = set()
+ dirtytime = earliest_time
+
+ future_vmrrs = self.slottable.get_reservations_on_or_after(earliest_time)
future_vmrrs = [rr for rr in future_vmrrs
if isinstance(rr, VMResourceReservation)
- and rr.state==ResourceReservation.STATE_SCHEDULED
- and not rr.is_resuming()
- and not rr.is_suspending()]
+ and rr.lease.get_state() in (Lease.STATE_SCHEDULED, Lease.STATE_READY, Lease.STATE_SUSPENDED_SCHEDULED)]
- for vmrr in future_vmrrs:
- for rr in vmrr.pre_rrs:
- if rr.state == ResourceReservation.STATE_SCHEDULED:
- self.slottable.remove_reservation(rr)
-
- for rr in vmrr.post_rrs:
- self.slottable.remove_reservation(rr)
-
- self.slottable.remove_reservation(vmrr)
+ for future_vmrr in future_vmrrs:
+ self.cancel_vm(future_vmrr)
- leases = [vmrr.lease for vmrr in future_vmrrs]
+ leases = list(set([future_vmrr.lease for future_vmrr in future_vmrrs]))
+
+ orig_vmrrs = dict([(l,[rr for rr in future_vmrrs if rr.lease == l]) for l in leases])
+
leases.append(lease)
- leases.sort(key= lambda l: (l.deadline - l.start.requested) / l.duration.requested)
+ leases.sort(key= lambda l: (l.deadline - earliest_time) / l.get_remaining_duration_at(nexttime))
new_vmrrs = {}
self.logger.debug("Attempting to reschedule leases %s" % [l.id for l in leases])
+ # First pass
+ scheduled = set()
for lease2 in leases:
for n in earliest:
earliest[n].time = max(lease2.start.requested, nexttime)
self.logger.debug("Rescheduling lease %s" % lease2.id)
- vmrr, preemptions = self.__schedule_asap(lease2, lease2.duration.get_remaining_duration(), nexttime, earliest, allow_in_future = True)
- if vmrr.end - vmrr.start != lease2.duration.requested or vmrr.end > lease2.deadline or len(preemptions) != 0:
+ dur = lease2.get_remaining_duration_at(nexttime)
+ vmrr, preemptions = self.__schedule_asap(lease2, dur, nexttime, earliest, allow_in_future = True)
+ if vmrr.end - vmrr.start != dur or vmrr.end > lease2.deadline or len(preemptions) != 0:
self.logger.debug("Lease %s could not be rescheduled, undoing changes." % lease2.id)
- self.slottable.pop()
+ self.slottable.restore()
raise NotSchedulableException, "Could not schedule before deadline without making other leases miss deadline"
+ dirtytime = max(vmrr.end, dirtytime)
+ dirtynodes.update(vmrr.resources_in_pnode.keys())
+
for rr in vmrr.pre_rrs:
self.slottable.add_reservation(rr)
self.slottable.add_reservation(vmrr)
for rr in vmrr.post_rrs:
self.slottable.add_reservation(rr)
+ scheduled.add(lease2)
if lease2 == lease:
return_vmrr = vmrr
+ break
else:
new_vmrrs[lease2] = vmrr
-
- for vmrr in future_vmrrs:
- vmrr.lease.remove_vmrr(vmrr)
+
+ # We've scheduled the lease. Now we try to schedule the rest of the leases but,
+ # since now we know the nodes the new lease is in, we can do a few optimizations
+
+ # Restore the leases in nodes we haven't used, and that would not be
+ # affected by the new lease. We need to find what this set of nodes is.
+
+ to_schedule = [l for l in leases if l not in scheduled]
+ dirtynodes, cleanleases = self.find_dirty_nodes(to_schedule, dirtynodes, orig_vmrrs)
+
+
+ print "Ignoring %i nodes" % (len(set(self.slottable.nodes.keys()) - dirtynodes) - 1)
+
+ # Restore the leases
+ restored_leases = set()
+ for l in leases:
+ if l in cleanleases:
+ # Restore
+ for l_vmrr in orig_vmrrs[l]:
+ for rr in l_vmrr.pre_rrs:
+ self.slottable.add_reservation(rr)
+ self.slottable.add_reservation(l_vmrr)
+ for rr in l_vmrr.post_rrs:
+ self.slottable.add_reservation(rr)
+ scheduled.add(l)
+ restored_leases.add(l)
+
+ to_schedule = [l for l in leases if l not in scheduled]
+ try:
+ (more_scheduled, add_vmrrs, dirtytime) = self.reschedule_deadline_leases(to_schedule, orig_vmrrs, earliest_time, earliest, nexttime, dirtytime)
+ scheduled.update(more_scheduled)
+ new_vmrrs.update(add_vmrrs)
+ except NotSchedulableException:
+ self.logger.debug("Lease %s could not be rescheduled, undoing changes." % l.id)
+ self.slottable.restore()
+ raise
+
+ for l in leases:
+ if l not in scheduled:
+ for l_vmrr in orig_vmrrs[l]:
+ for rr in l_vmrr.pre_rrs:
+ self.slottable.add_reservation(rr)
+ self.slottable.add_reservation(l_vmrr)
+ for rr in l_vmrr.post_rrs:
+ self.slottable.add_reservation(rr)
+ restored_leases.add(l)
+
+ print "Skipped re-scheduling %i leases (out of %i)" % (len(restored_leases), len(leases))
+
+ for l in [l2 for l2 in orig_vmrrs if l2 in scheduled - restored_leases]:
+ for vmrr in orig_vmrrs[l]:
+ vmrr.lease.remove_vmrr(vmrr)
for lease2, vmrr in new_vmrrs.items():
lease2.append_vmrr(vmrr)
+ # Remove from slottable, because lease_scheduler is the one that actually
+ # adds the RRs
for rr in return_vmrr.pre_rrs:
self.slottable.remove_reservation(rr)
self.slottable.remove_reservation(return_vmrr)
@@ -704,6 +760,61 @@
else:
return vmrr, preemptions
+
+ def find_dirty_nodes(self, to_schedule, dirtynodes, orig_vmrrs):
+ dirtynodes = set(dirtynodes)
+ done = False
+ while not done:
+ stable = True
+ cleanleases = set()
+ for l in to_schedule:
+ pnodes = set()
+ for l_vmrr in orig_vmrrs[l]:
+ pnodes.update(l_vmrr.resources_in_pnode.keys())
+ in_dirty = dirtynodes & pnodes
+ in_clean = pnodes - dirtynodes
+ if len(in_dirty) > 0 and len(in_clean) > 0:
+ stable = False
+ dirtynodes.update(in_clean)
+ if len(in_clean) > 0 and len(in_dirty) == 0:
+ cleanleases.add(l)
+ if stable == True:
+ done = True
+
+ return dirtynodes, cleanleases
+
+
+ def reschedule_deadline_leases(self, leases, orig_vmrrs, earliest_time, earliest, nexttime, dirtytime):
+ scheduled = set()
+ new_vmrrs = {}
+ for l in leases:
+ if len(scheduled) < len(leases) and dirtytime != None:
+ min_future_start = min([min([rr.start for rr in lrr]) for l2, lrr in orig_vmrrs.items() if l2 in leases and l2 not in scheduled])
+ if min_future_start > dirtytime:
+ print "Ignoring after %s" % dirtytime
+ break
+ for n in earliest:
+ earliest[n].time = max(l.start.requested, nexttime)
+ self.logger.debug("Rescheduling lease %s" % l.id)
+ dur = l.get_remaining_duration_at(earliest_time)
+ vmrr, preemptions = self.__schedule_asap(l, dur, nexttime, earliest, allow_in_future = True)
+ if vmrr.end - vmrr.start != dur or vmrr.end > l.deadline or len(preemptions) != 0:
+ raise NotSchedulableException, "Could not schedule before deadline without making other leases miss deadline"
+
+ if dirtytime != None:
+ dirtytime = max(vmrr.end, dirtytime)
+
+ for rr in vmrr.pre_rrs:
+ self.slottable.add_reservation(rr)
+ self.slottable.add_reservation(vmrr)
+ for rr in vmrr.post_rrs:
+ self.slottable.add_reservation(rr)
+ new_vmrrs[l] = vmrr
+ scheduled.add(l)
+
+ return scheduled, new_vmrrs, dirtytime
+
+
def reschedule_deadline(self, lease, duration, nexttime, earliest, override_state = None):
for n in earliest:
earliest[n].time = max(lease.start.requested, earliest[n].time)
Modified: branches/1.1/src/haizea/pluggable/policies/preemption.py
===================================================================
--- branches/1.1/src/haizea/pluggable/policies/preemption.py 2010-01-14 04:09:27 UTC (rev 763)
+++ branches/1.1/src/haizea/pluggable/policies/preemption.py 2010-01-15 05:20:03 UTC (rev 764)
@@ -104,20 +104,8 @@
preemptor -- Preemptor lease
preemptee -- Preemptee lease
time -- Time at which preemption would take place
- """
+ """
if preemptee.get_type() == Lease.DEADLINE:
- for vmrr in preemptee.vm_rrs:
- if time >= vmrr.start and time < vmrr.end:
- preempt_vmrr = vmrr
- break
- last_vmrr = preemptee.get_last_vmrr()
-
- if preempt_vmrr != last_vmrr:
- return -1
-
- if preempt_vmrr.is_suspending():
- return -1
-
# We can only preempt leases in these states
if not preemptee.get_state() in (Lease.STATE_SCHEDULED, Lease.STATE_READY,
Lease.STATE_ACTIVE, Lease.STATE_SUSPENDING, Lease.STATE_SUSPENDED_PENDING,
@@ -125,7 +113,7 @@
return -1
deadline = preemptee.deadline
- remaining_duration = preempt_vmrr.end - time
+ remaining_duration = preemptee.get_remaining_duration_at(time)
slack = (deadline - time) / remaining_duration
delay = preemptee.estimate_suspend_time() + preemptor.duration.requested + preemptee.estimate_resume_time()
if time + delay + remaining_duration < deadline:
More information about the Haizea-commit
mailing list