mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 10:54:24 -04:00
added GarbageReportScheduler
This commit is contained in:
parent
645fd746a4
commit
4ac6f8c885
@ -820,6 +820,7 @@ class ContainerLeakDetector(Job):
|
|||||||
ContainerLeakDetector.addPrivateObj(ContainerLeakDetector.PrivateIds)
|
ContainerLeakDetector.addPrivateObj(ContainerLeakDetector.PrivateIds)
|
||||||
ContainerLeakDetector.addPrivateObj(self.__dict__)
|
ContainerLeakDetector.addPrivateObj(self.__dict__)
|
||||||
|
|
||||||
|
self.setPriority(Job.Priorities.Min)
|
||||||
jobMgr.add(self)
|
jobMgr.add(self)
|
||||||
|
|
||||||
def destroy(self):
|
def destroy(self):
|
||||||
@ -840,9 +841,6 @@ class ContainerLeakDetector(Job):
|
|||||||
# passes description string as argument
|
# passes description string as argument
|
||||||
return 'containerLeakDetected-%s' % self._serialNum
|
return 'containerLeakDetected-%s' % self._serialNum
|
||||||
|
|
||||||
def getPriority(self):
|
|
||||||
return Job.Priorities.Min
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def addPrivateObj(cls, obj):
|
def addPrivateObj(cls, obj):
|
||||||
cls.PrivateIds.add(id(obj))
|
cls.PrivateIds.add(id(obj))
|
||||||
|
@ -26,7 +26,7 @@ class GarbageReport(Job):
|
|||||||
NotGarbage = 'NG'
|
NotGarbage = 'NG'
|
||||||
|
|
||||||
def __init__(self, name, log=True, verbose=False, fullReport=False, findCycles=True,
|
def __init__(self, name, log=True, verbose=False, fullReport=False, findCycles=True,
|
||||||
threaded=False, doneCallback=None, autoDestroy=False):
|
threaded=False, doneCallback=None, autoDestroy=False, priority=None):
|
||||||
# if autoDestroy is True, GarbageReport will self-destroy after logging
|
# if autoDestroy is True, GarbageReport will self-destroy after logging
|
||||||
# if false, caller is responsible for calling destroy()
|
# if false, caller is responsible for calling destroy()
|
||||||
# if threaded is True, processing will be performed over multiple frames
|
# if threaded is True, processing will be performed over multiple frames
|
||||||
@ -35,6 +35,8 @@ class GarbageReport(Job):
|
|||||||
self._args = ScratchPad(name=name, log=log, verbose=verbose, fullReport=fullReport,
|
self._args = ScratchPad(name=name, log=log, verbose=verbose, fullReport=fullReport,
|
||||||
findCycles=findCycles, doneCallback=doneCallback,
|
findCycles=findCycles, doneCallback=doneCallback,
|
||||||
autoDestroy=autoDestroy)
|
autoDestroy=autoDestroy)
|
||||||
|
if priority is not None:
|
||||||
|
self.setPriority(priority)
|
||||||
jobMgr.add(self)
|
jobMgr.add(self)
|
||||||
if not threaded:
|
if not threaded:
|
||||||
jobMgr.finish(self)
|
jobMgr.finish(self)
|
||||||
@ -114,6 +116,10 @@ class GarbageReport(Job):
|
|||||||
yield None
|
yield None
|
||||||
self.cycleIds.update(set(cycle))
|
self.cycleIds.update(set(cycle))
|
||||||
|
|
||||||
|
if self._args.findCycles:
|
||||||
|
s = ['===== GarbageReport: \'%s\' (%s items, %s cycles) =====' % (
|
||||||
|
self._args.name, self.numGarbage, len(self.cycles))]
|
||||||
|
else:
|
||||||
s = ['===== GarbageReport: \'%s\' (%s items) =====' % (
|
s = ['===== GarbageReport: \'%s\' (%s items) =====' % (
|
||||||
self._args.name, self.numGarbage)]
|
self._args.name, self.numGarbage)]
|
||||||
if self.numGarbage > 0:
|
if self.numGarbage > 0:
|
||||||
@ -265,7 +271,6 @@ class GarbageReport(Job):
|
|||||||
yield byNum, byRef
|
yield byNum, byRef
|
||||||
|
|
||||||
def _getCycles(self, index, cycleSets=None):
|
def _getCycles(self, index, cycleSets=None):
|
||||||
# TODO: make this a generator
|
|
||||||
# detect garbage cycles for a particular item of garbage
|
# detect garbage cycles for a particular item of garbage
|
||||||
assert self.notify.debugCall()
|
assert self.notify.debugCall()
|
||||||
# returns list of lists, sublists are garbage reference cycles
|
# returns list of lists, sublists are garbage reference cycles
|
||||||
|
40
direct/src/showbase/GarbageReportScheduler.py
Executable file
40
direct/src/showbase/GarbageReportScheduler.py
Executable file
@ -0,0 +1,40 @@
|
|||||||
|
from direct.showbase.GarbageReport import GarbageReport
|
||||||
|
|
||||||
|
class GarbageReportScheduler:
|
||||||
|
# runs a garbage report every once in a while and logs the results
|
||||||
|
def __init__(self, waitBetween=None, waitScale=None):
|
||||||
|
# waitBetween is in seconds
|
||||||
|
# waitScale is a multiplier for the waitBetween every time around
|
||||||
|
if waitBetween is None:
|
||||||
|
waitBetween = 30*60
|
||||||
|
if waitScale is None:
|
||||||
|
waitScale = 1.5
|
||||||
|
self._waitBetween = waitBetween
|
||||||
|
self._waitScale = waitScale
|
||||||
|
self._taskName = 'startScheduledGarbageReport-%s' % serialNum()
|
||||||
|
self._garbageReport = None
|
||||||
|
self._scheduleNextGarbageReport()
|
||||||
|
|
||||||
|
def getTaskName(self):
|
||||||
|
return self._taskName
|
||||||
|
|
||||||
|
def _scheduleNextGarbageReport(self, garbageReport=None):
|
||||||
|
if garbageReport:
|
||||||
|
# this report finished, wait a bit then start another
|
||||||
|
assert garbageReport is self._garbageReport
|
||||||
|
# garbagereport will clean itself up
|
||||||
|
self._garbageReport = None
|
||||||
|
# run another garbagereport after a delay
|
||||||
|
taskMgr.doMethodLater(self._waitBetween,
|
||||||
|
self._runGarbageReport,
|
||||||
|
self._taskName)
|
||||||
|
# and increase the delay every time around
|
||||||
|
self._waitBetween = self._waitBetween * self._waitScale
|
||||||
|
def _runGarbageReport(self, task):
|
||||||
|
# run a garbage report and schedule the next one after this one finishes
|
||||||
|
# give this job 3 times as many timeslices as normal-priority jobs
|
||||||
|
self._garbageReport = GarbageReport('ScheduledGarbageReport', threaded=True,
|
||||||
|
doneCallback=self._scheduleNextGarbageReport,
|
||||||
|
autoDestroy=True,
|
||||||
|
priority=GarbageReport.Priorities.Normal * 3)
|
||||||
|
return task.done
|
@ -23,6 +23,7 @@ class Job(DirectObject):
|
|||||||
self._generator = None
|
self._generator = None
|
||||||
self._id = Job._SerialGen.next()
|
self._id = Job._SerialGen.next()
|
||||||
self._printing = False
|
self._printing = False
|
||||||
|
self._priority = Job.Priorities.Normal
|
||||||
if __debug__:
|
if __debug__:
|
||||||
self._pstats = PStatCollector("App:Show code:jobManager:%s" % self._name)
|
self._pstats = PStatCollector("App:Show code:jobManager:%s" % self._name)
|
||||||
|
|
||||||
@ -45,8 +46,9 @@ class Job(DirectObject):
|
|||||||
raise "don't call down"
|
raise "don't call down"
|
||||||
|
|
||||||
def getPriority(self):
|
def getPriority(self):
|
||||||
# override if you want a different priority
|
return self._priority
|
||||||
return Job.Priorities.Normal
|
def setPriority(self, priority):
|
||||||
|
self._priority = priority
|
||||||
|
|
||||||
def printingBegin(self):
|
def printingBegin(self):
|
||||||
self._printing = True
|
self._printing = True
|
||||||
|
Loading…
x
Reference in New Issue
Block a user