Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $Workfile: $
// $Date: $
//
//-----------------------------------------------------------------------------
// $Log: $
//
// $NoKeywords: $
//=============================================================================//
#include <string.h>
#include <stdlib.h>
#include "basetypes.h"
#include "measure_section.h"
#include "convar.h"
// Static members
CMeasureSection *CMeasureSection::s_pSections = 0; int CMeasureSection::s_nCount = 0; double CMeasureSection::m_dNextResort = 0.0;
ConVar measure_resort( "measure_resort", "1.0", 0, "How often to re-sort profiling sections\n" ); ConVar game_speeds( "game_speeds","0" ); extern ConVar host_speeds;
//-----------------------------------------------------------------------------
// Purpose: Creates a profiling section
// Input : *name - name of the section ( allocated on stack hopefully )
//-----------------------------------------------------------------------------
CMeasureSection::CMeasureSection( const char *name ) { // Just point at name since it's static
m_pszName = name; // Clear accumulators
Reset(); SortReset(); m_dMaxTime.Init();
// Link into master list
m_pNext = s_pSections; s_pSections = this; // Update count
s_nCount++; }
//-----------------------------------------------------------------------------
// Purpose: Destroys the object
//-----------------------------------------------------------------------------
CMeasureSection::~CMeasureSection( void ) { m_pNext = NULL; s_nCount--; }
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CMeasureSection::UpdateMax( void ) { if (m_dMaxTime.IsLessThan(m_dAccumulatedTime)) { m_dMaxTime.Init(); CCycleCount::Add(m_dMaxTime,m_dAccumulatedTime,m_dMaxTime); } }
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CMeasureSection::Reset( void ) { m_dAccumulatedTime.Init(); }
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CMeasureSection::SortReset( void ) { m_dTotalTime.Init(); }
//-----------------------------------------------------------------------------
// Purpose:
// Output : const char
//-----------------------------------------------------------------------------
const char *CMeasureSection::GetName( void ) { return m_pszName; }
//-----------------------------------------------------------------------------
// Purpose:
// Output :
//-----------------------------------------------------------------------------
CCycleCount const& CMeasureSection::GetTotalTime( void ) { return m_dTotalTime; }
//-----------------------------------------------------------------------------
// Purpose:
// Output :
//-----------------------------------------------------------------------------
CCycleCount const& CMeasureSection::GetTime( void ) { return m_dAccumulatedTime; }
//-----------------------------------------------------------------------------
// Purpose:
// Output :
//-----------------------------------------------------------------------------
CCycleCount const& CMeasureSection::GetMaxTime( void ) { return m_dMaxTime; }
//-----------------------------------------------------------------------------
// Purpose: Accumulates a timeslice
// Input : time -
//-----------------------------------------------------------------------------
void CMeasureSection::AddTime( CCycleCount const &rCount ) { CCycleCount::Add(m_dAccumulatedTime, rCount, m_dAccumulatedTime); CCycleCount::Add(m_dTotalTime, rCount, m_dTotalTime); }
//-----------------------------------------------------------------------------
// Purpose:
// Output : CMeasureSection
//-----------------------------------------------------------------------------
CMeasureSection *CMeasureSection::GetNext( void ) { return m_pNext; }
//-----------------------------------------------------------------------------
// Purpose:
// Output : CMeasureSection
//-----------------------------------------------------------------------------
CMeasureSection *CMeasureSection::GetList( void ) { return s_pSections; }
//-----------------------------------------------------------------------------
// Purpose: Compares accumulated time for two sections
// Input : ppms1 -
// ppms2 -
// Output : static int
//-----------------------------------------------------------------------------
static int SectionCompare( const void* ppms1,const void* ppms2 ) { CMeasureSection* pms1 = *(CMeasureSection**)ppms1; CMeasureSection* pms2 = *(CMeasureSection**)ppms2;
if ( pms1->GetTotalTime().IsLessThan(pms2->GetTotalTime()) ) return 1; else return -1; }
//-----------------------------------------------------------------------------
// Purpose: Sorts sections by time usage
//-----------------------------------------------------------------------------
void CMeasureSection::SortSections( void ) { // Not enough to be sortable
if ( s_nCount <= 1 ) return;
CMeasureSection *sortarray[ 128 ]; CMeasureSection *ms;
memset(sortarray,sizeof(CMeasureSection*)*128,0); ms = GetList(); int i; int c = 0; while ( ms ) { sortarray[ c++ ] = ms; ms = ms->GetNext(); }
// Sort the array alphabetically
qsort( sortarray, c , sizeof( CMeasureSection * ), SectionCompare );
// Fix next pointers
for ( i = 0; i < c-1; i++ ) { sortarray[ i ]->m_pNext = sortarray[ i + 1 ]; } sortarray[i]->m_pNext = NULL;
// Point head of list at it
s_pSections = sortarray[ 0 ]; }
//-----------------------------------------------------------------------------
// Purpose: Creates an instance for timing a section
// Input : *ms -
//-----------------------------------------------------------------------------
CMeasureSectionInstance::CMeasureSectionInstance( CMeasureSection *ms ) { // Remember where to put accumulated time
m_pMS = ms;
if ( host_speeds.GetInt() < 3 && !game_speeds.GetInt()) return; // Get initial timestamp
m_Timer.Start(); }
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CMeasureSectionInstance::~CMeasureSectionInstance( void ) { if ( host_speeds.GetInt() < 3 && !game_speeds.GetInt()) return;
// Get final timestamp
m_Timer.End();
// Add time to section
m_pMS->AddTime( m_Timer.GetDuration() ); }
//-----------------------------------------------------------------------------
// Purpose: Re-sort all data and determine whether sort keys should be reset too ( after
// re-doing sort if needed ).
//-----------------------------------------------------------------------------
void ResetTimeMeasurements( void ) { #if defined( _DEBUG ) || defined( FORCE_MEASURE )
bool sort_reset = false;
// Time to redo sort?
if ( measure_resort.GetFloat() > 0.0 && GetRealTime() >= CMeasureSection::m_dNextResort ) { // Redo it
CMeasureSection::SortSections(); // Set next time
CMeasureSection::m_dNextResort = GetRealTime() + measure_resort.GetFloat(); // Flag to reset sort accumulator, too
sort_reset = true; }
// Iterate through the sections now
CMeasureSection *p = CMeasureSection::GetList(); while ( p ) { // Reset regular accum.
p->Reset(); // Reset sort accum less often
if ( sort_reset ) { p->SortReset(); } p = p->GetNext(); } #endif
}
|