public ProfilerCodeBlockInstance(ProfilerCodeBlock instanceOf, ProfilerCodeBlockInstance parent) { _instanceOf = instanceOf; _parent = parent; }
public ProfilerCodeBlock(string name) { _name = name; _nextCodeBlock = Profiler.Instance._codeBlockList; Profiler.Instance._codeBlockList = this; }
public void StartBlock(string name) { #if TORQUE_PROFILE // validate name if (name == null || name.Length < 1) return; // get the profiler code block object for this name ProfilerCodeBlock thisBlock = _managedCodeBlocks[name] as ProfilerCodeBlock; // create a profiler code block for this root if none exists if (thisBlock == null) { // create a new code block and hash it thisBlock = new ProfilerCodeBlock(name); _managedCodeBlocks.Add(name, thisBlock); } // start this code block StartBlock(thisBlock); #endif }
public void StartBlock(ProfilerCodeBlock thisBlock) { #if TORQUE_PROFILE // increment stack depth _stackDepth++; // assert that stack depth is not huge if (_stackDepth >= _maxStackDepth) { // find the code block with the most invocations List<ProfilerCodeBlock> codeBlocks = _GetCodeBlocksList(); ProfilerCodeBlock block = codeBlocks[0]; foreach (ProfilerCodeBlock codeBlock in codeBlocks) if (codeBlock.InvokeCount > block.InvokeCount) block = codeBlock; Assert.Fatal(false, "Profiler.StartBlock - Stack overflow in profiler. Most likely culprit is: " + block.Name + " (" + block.InvokeCount.ToString() + " on stack)\n\nPlease make sure your StartBlock and EndBlock calls match up!"); } // make sure we're profiling if (!_isProfiling || thisBlock == null) return; // get the profiler code block instance object for this particular code path ProfilerCodeBlockInstance thisBlockInstance = null; // check for recursion if (_currentBlockInstance != null && _currentBlockInstance.InstanceOf == thisBlock) { // recursion: use the current code block rather than creating another instance thisBlockInstance = _currentBlockInstance; // increase the recursion depth of this instance thisBlockInstance.RecursionDepth++; } else { // check if this is a root instance bool isRoot = _currentBlockInstance == null; // check for the last seen instance if (!isRoot && _currentBlockInstance != null && _currentBlockInstance.LastSeenInstance != null && _currentBlockInstance.LastSeenInstance.InstanceOf == thisBlock) { // get the last seen instance on this code block thisBlockInstance = _currentBlockInstance.LastSeenInstance; } else { // get the existing block instance if (!isRoot) thisBlockInstance = _currentBlockInstance._childHash[thisBlock.Name] as ProfilerCodeBlockInstance; else thisBlockInstance = _rootBlockInstanceHash[thisBlock.Name] as ProfilerCodeBlockInstance; // create a code block instance for this section if none exists if (thisBlockInstance == null) { // create a new instance and hash it on the code block thisBlockInstance = new ProfilerCodeBlockInstance(thisBlock, _currentBlockInstance); // hash the instance on either the current code block, or the root hash if (!isRoot) _currentBlockInstance._childHash.Add(thisBlock.Name, thisBlockInstance); else _rootBlockInstanceHash.Add(thisBlock.Name, thisBlockInstance); } } // set the start time of the current pass long ticks; QueryPerformanceCounter(out ticks); thisBlockInstance.PassStartTime = ((double)ticks / (double)_tickFrequency) * 1000.0; // validate the current code block instance Assert.Fatal(_ValidateCodeBlockInstance(thisBlockInstance), "Profiler.StartBlock - Profiler doesn't support multiple code paths to the same child-parent code block pair. Email Adam Larson for details: [email protected]"); // record the last seen instance for fast lookups next time if (_currentBlockInstance != null) _currentBlockInstance.LastSeenInstance = thisBlockInstance; // push the new codeblock onto the stack _currentBlockInstance = thisBlockInstance; } // increment the invoke count thisBlock.InvokeCount++; thisBlockInstance.InvokeCount++; #endif // TORQUE_PROFILE }
public void EndBlock(ProfilerCodeBlock thisBlock) { #if TORQUE_PROFILE // decrement stack depth _stackDepth--; // assert that stack depth is not negative! Assert.Fatal(_stackDepth >= 0, "Profiler.EndBlock - Stack underflow in profiler. \n\nPlease make sure your StartBlock and EndBlock calls match up!"); // validate name if (thisBlock.Name == null || thisBlock.Name.Length < 1) return; // make sure we're enabled if (_isProfiling) { // check for recursion depth if (_currentBlockInstance.RecursionDepth > 0) { // current code block was called by itself, decrement // recursion depth and return _currentBlockInstance.RecursionDepth--; return; } // get the elapsed time since this instance was started long ticks; QueryPerformanceCounter(out ticks); double elapsed = (((double)ticks / (double)_tickFrequency) * 1000.0) - _currentBlockInstance.PassStartTime; // add to this stack's total time _currentBlockInstance.TotalTime += elapsed; _currentBlockInstance.InstanceOf.TotalTime += elapsed; // inrement this stack's sub time from the parent up if (_currentBlockInstance.Parent != null) { _currentBlockInstance.Parent.SubTime += elapsed; _currentBlockInstance.Parent.InstanceOf.SubTime += elapsed; } // pop the current block instance from the stack _currentBlockInstance = _currentBlockInstance.Parent; } // process flags: check if we if we are ready to start/stop profiling or dump our data if (_stackDepth == 0) { // if we were waiting on a chance to dump, do so now if (_wantsToDump && _isProfiling) { // dump the profile _DumpProfile(); // turn the 'wants to dump' flag off _wantsToDump = false; } // now check for switch to profiling or not profiling if (_isProfiling != _wantsToProfile) { // get the desired profiling value _isProfiling = _wantsToProfile; #if XBOX if (_isProfiling) _timer.Start(); #endif // XBOX // make sure that if we're going to start profiling we have a tick frequency! if (_isProfiling && _tickFrequency == 0) QueryPerformanceFrequency(out _tickFrequency); } } #endif // TORQUE_PROFILE }