Browse Source

track time that jobs spend beyond their timeslice and compensate

Darren Ranalli 18 years ago
parent
commit
ba78c5139f
1 changed files with 18 additions and 0 deletions
  1. 18 0
      direct/src/showbase/JobManager.py

+ 18 - 0
direct/src/showbase/JobManager.py

@@ -27,6 +27,9 @@ class JobManager:
         # how many timeslices to give each job; this is used to efficiently implement
         # how many timeslices to give each job; this is used to efficiently implement
         # the relative job priorities
         # the relative job priorities
         self._jobId2timeslices = {}
         self._jobId2timeslices = {}
+        # how much time did the job use beyond the allotted timeslice, used to balance
+        # out CPU usage
+        self._jobId2overflowTime = {}
         # this is a generator that we use to give high-priority jobs more timeslices
         # this is a generator that we use to give high-priority jobs more timeslices
         self._jobIdGenerator = None
         self._jobIdGenerator = None
         self._highestPriority = Job.Priorities.Normal
         self._highestPriority = Job.Priorities.Normal
@@ -48,6 +51,8 @@ class JobManager:
         self._pri2jobIds[pri].append(jobId)
         self._pri2jobIds[pri].append(jobId)
         # record the job's relative timeslice count
         # record the job's relative timeslice count
         self._jobId2timeslices[jobId] = pri
         self._jobId2timeslices[jobId] = pri
+        # init the overflow time tracking
+        self._jobId2overflowTime[jobId] = 0.
         # reset the jobId round-robin
         # reset the jobId round-robin
         self._jobIdGenerator = None
         self._jobIdGenerator = None
         if len(self._jobId2pri) == 1:
         if len(self._jobId2pri) == 1:
@@ -69,6 +74,8 @@ class JobManager:
         job._cleanupGenerator()
         job._cleanupGenerator()
         # remove the job's timeslice count
         # remove the job's timeslice count
         self._jobId2timeslices.pop(jobId)
         self._jobId2timeslices.pop(jobId)
+        # remove the overflow time
+        self._jobId2overflowTime.pop(jobId)
         if len(self._pri2jobId2job[pri]) == 0:
         if len(self._pri2jobId2job[pri]) == 0:
             del self._pri2jobId2job[pri]
             del self._pri2jobId2job[pri]
             if pri == self._highestPriority:
             if pri == self._highestPriority:
@@ -152,6 +159,14 @@ class JobManager:
                 if pri is None:
                 if pri is None:
                     # this job is no longer present
                     # this job is no longer present
                     continue
                     continue
+                # check if there's overflow time that we need to make up for
+                overflowTime = self._jobId2overflowTime[jobId]
+                timeLeft = endT - globalClock.getRealTime()
+                if overflowTime >= timeLeft:
+                    self._jobId2overflowTime[jobId] = max(0., overflowTime-timeLeft)
+                    # don't run any more jobs this frame, this makes up
+                    # for the extra overflow time that was used before
+                    break
                 job = self._pri2jobId2job[pri][jobId]
                 job = self._pri2jobId2job[pri][jobId]
                 gen = job._getGenerator()
                 gen = job._getGenerator()
                 if __debug__:
                 if __debug__:
@@ -185,6 +200,9 @@ class JobManager:
                     # we've run out of time
                     # we've run out of time
                     #assert self.notify.debug('timeslice end: %s, %s' % (endT, globalClock.getRealTime()))
                     #assert self.notify.debug('timeslice end: %s, %s' % (endT, globalClock.getRealTime()))
                     job.suspend()
                     job.suspend()
+                    overflowTime = globalClock.getRealTime() - endT
+                    if overflowTime > self.getTimeslice():
+                        self._jobId2overflowTime[jobId] += overflowTime
                     if __debug__:
                     if __debug__:
                         job._pstats.stop()
                         job._pstats.stop()
                     break
                     break