11from direct .directnotify .DirectNotifyGlobal import directNotify
22from direct .fsm .StatePush import FunctionCall
33from direct .showbase .PythonUtil import formatTimeExact , normalDistrib
4+ from direct .task import Task
45
56class FrameProfiler :
67 notify = directNotify .newCategory ('FrameProfiler' )
78
8- # for precision, all times related to the profile/log schedule are stored as integers
9+ # because of precision requirements, all times related to the profile/log
10+ # schedule are stored as integers
911 Minute = 60
1012 Hour = 60 * Minute
1113 Day = 24 * Hour
@@ -14,7 +16,7 @@ def __init__(self):
1416 Hour = FrameProfiler .Hour
1517 # how long to wait between frame profiles
1618 self ._period = 2 * FrameProfiler .Minute
17- if config .GetBool ('frame-profiler-debug ' , 0 ):
19+ if config .GetBool ('frequent- frame-profiles ' , 0 ):
1820 self ._period = 1 * FrameProfiler .Minute
1921 # used to prevent profile from being taken exactly every 'period' seconds
2022 self ._jitterMagnitude = self ._period * .75
@@ -26,7 +28,7 @@ def __init__(self):
2628 12 * FrameProfiler .Hour ,
2729 1 * FrameProfiler .Day ,
2830 ] # day schedule proceeds as 1, 2, 4, 8 days, etc.
29- if config .GetBool ('frame-profiler-debug ' , 0 ):
31+ if config .GetBool ('frequent- frame-profiles ' , 0 ):
3032 self ._logSchedule = [ 1 * FrameProfiler .Minute ,
3133 4 * FrameProfiler .Minute ,
3234 12 * FrameProfiler .Minute ,
@@ -113,6 +115,18 @@ def _analyzeResults(self, sessionId):
113115 Functor (self ._doAnalysis , sessionId ), 'FrameProfilerAnalysis-%s' % sessionId )
114116
115117 def _doAnalysis (self , sessionId , task ):
118+ if hasattr (task , '_generator' ):
119+ gen = task ._generator
120+ else :
121+ gen = self ._doAnalysisGen (sessionId )
122+ task ._generator = gen
123+ result = gen .next ()
124+ if result == Task .done :
125+ del task ._generator
126+ return result
127+
128+ def _doAnalysisGen (self , sessionId ):
129+ # generator to limit max number of profile loggings per frame
116130 p2ap = self ._period2aggregateProfile
117131
118132 self ._id2task .pop (sessionId )
@@ -131,14 +145,21 @@ def _doAnalysis(self, sessionId, task):
131145 session .release ()
132146 session = None
133147
148+ counter = 0
149+
134150 # log profiles when it's time, and aggregate them upwards into the
135151 # next-longer profile
136152 for pi in xrange (len (self ._logSchedule )):
137153 period = self ._logSchedule [pi ]
138154 if (self ._timeElapsed % period ) == 0 :
139155 if period in p2ap :
156+ # delay until the next frame if we've already processed N profiles this frame
157+ if counter >= 3 :
158+ counter = 0
159+ yield Task .cont
140160 self .notify .info ('aggregate profile of sampled frames over last %s\n %s' %
141161 (formatTimeExact (period ), p2ap [period ].getResults ()))
162+ counter += 1
142163 # aggregate this profile into the next larger profile
143164 nextIndex = pi + 1
144165 if nextIndex >= len (self ._logSchedule ):
@@ -161,5 +182,4 @@ def _doAnalysis(self, sessionId, task):
161182 # periods are multiples of this one
162183 break
163184
164- return task .done
165-
185+ yield Task .done
0 commit comments