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.
302 lines
7.3 KiB
302 lines
7.3 KiB
/*********************************************************************************
|
|
/* File:
|
|
/* ORDERPRO.CPP
|
|
/* Author:
|
|
/* Max-H. Windisch, SDE-T
|
|
/* Date:
|
|
/* October 1996
|
|
/* Summary:
|
|
/* Utility for sorting results generated by profile.h:
|
|
/* 1) sorts all nodes by start time (requires "history" profiling)
|
|
/* 2) extracts the time difference between two specified nodes
|
|
/*
|
|
/* (c) Copyright 1996 Microsoft-Softimage Inc.
|
|
/********************************************************************************/
|
|
|
|
|
|
|
|
// includes
|
|
#define MAX_PROFILING_ENABLED
|
|
#include <iomanip.h>
|
|
|
|
#pragma warning(push, 3)
|
|
#include <list>
|
|
#include <vector>
|
|
#include <stack>
|
|
#include <map>
|
|
#include <set>
|
|
#include <algorithm>
|
|
#pragma warning (pop)
|
|
|
|
#include <profile.h>
|
|
//namespace std
|
|
//{
|
|
// #include <set.h>
|
|
//}
|
|
|
|
|
|
|
|
// global markers
|
|
CString g_oThreadId( "@@ThreadId=" );
|
|
CString g_oRange( "@@Range=[origin(" );
|
|
CString g_oRangeDuration( ",duration(" );
|
|
CString g_oDeltaToPrevious( "@@DeltaToPrev=" );
|
|
|
|
|
|
|
|
// the profiling line
|
|
class CProfLine
|
|
{
|
|
protected:
|
|
DWORD m_dwThreadId;
|
|
CMaxLargeInteger m_oStartStamp;
|
|
CString m_oLine;
|
|
|
|
public:
|
|
CProfLine(
|
|
DWORD dwThreadId = 0,
|
|
const CMaxLargeInteger &roStamp = CMaxLargeInteger(),
|
|
const CString &roLine = CString() )
|
|
: m_dwThreadId( dwThreadId )
|
|
, m_oStartStamp( roStamp )
|
|
, m_oLine( roLine )
|
|
{
|
|
};
|
|
|
|
bool operator <( const CProfLine &o ) const
|
|
{
|
|
return m_oStartStamp < o.m_oStartStamp;
|
|
};
|
|
|
|
void FOutput( ostream &os, const CProfLine &roPrevious ) const
|
|
{
|
|
CMaxLargeInteger frequency;
|
|
|
|
CMaxLargeInteger dtp = m_oStartStamp - roPrevious.m_oStartStamp;
|
|
::QueryPerformanceFrequency( frequency );
|
|
os << "[" << g_oThreadId << setw( 4 ) << m_dwThreadId << ", ";
|
|
os << g_oDeltaToPrevious << setw( 14 ) << dtp.dFInSecondsF( frequency ) << "s]";
|
|
os << m_oLine << endl;
|
|
};
|
|
};
|
|
|
|
|
|
|
|
// the file parsers base class
|
|
class CResultParser
|
|
{
|
|
protected:
|
|
ifstream m_is;
|
|
|
|
public:
|
|
CResultParser( const CString &roInputFileName )
|
|
: m_is( (PCTSTR)roInputFileName ){};
|
|
|
|
virtual void FExecute()
|
|
{
|
|
FParse();
|
|
FOutputResults();
|
|
};
|
|
|
|
protected:
|
|
virtual void FParse()
|
|
{
|
|
const unsigned long len = 400;
|
|
CString line;
|
|
LPTSTR buf;
|
|
int i = 0;
|
|
|
|
while ( !m_is.eof() )
|
|
{
|
|
buf = line.GetBufferSetLength( len );
|
|
m_is.getline( buf, len );
|
|
line.ReleaseBuffer( -1 );
|
|
|
|
FProcessLine( line, i++ );
|
|
}
|
|
};
|
|
|
|
virtual void FProcessLine( const CString &roLine, int nLineNumber ) = 0;
|
|
virtual void FOutputResults() = 0;
|
|
|
|
protected:
|
|
bool bFGetThreadIdFromLine( const CString &roLine, DWORD &dwThreadId )
|
|
{
|
|
int i;
|
|
|
|
if ( ( i = roLine.Find( g_oThreadId ) ) >= 0 )
|
|
{
|
|
CString s = roLine.Mid( i + g_oThreadId.GetLength() );
|
|
dwThreadId = atoi( s );
|
|
cout << "new thread=" << dwThreadId << endl;
|
|
return true;
|
|
}
|
|
// Note: don't touch dwThreadId
|
|
return false;
|
|
};
|
|
|
|
bool bFGetRangeFromLine( const CString &roLine, CMaxLargeInteger &roStart, CMaxLargeInteger &roDuration )
|
|
{
|
|
int i;
|
|
CString s1;
|
|
|
|
if ( ( i = roLine.Find( g_oRange ) ) >= 0 )
|
|
{
|
|
s1 = roLine.Mid( i + g_oRange.GetLength() );
|
|
FExtractLargeInteger( s1, roStart );
|
|
if ( ( i = roLine.Find( g_oRangeDuration ) ) >= 0 )
|
|
{
|
|
s1 = roLine.Mid( i + g_oRangeDuration.GetLength() );
|
|
FExtractLargeInteger( s1, roDuration );
|
|
}
|
|
return true;
|
|
}
|
|
// Note: don't touch roStart or roDuration
|
|
return false;
|
|
};
|
|
|
|
void FExtractLargeInteger( const CString &roLineSegment, CMaxLargeInteger &roL )
|
|
{
|
|
int delim1 = roLineSegment.Find( ';' );
|
|
CString s2 = roLineSegment.Left( delim1 );
|
|
int delim2 = roLineSegment.Find( ')' );
|
|
CString s3 = roLineSegment.Mid( delim1 + 1, delim2 - delim1 - 1 );
|
|
roL = CMaxLargeInteger( atoi( s2 ), atoi( s3 ) );
|
|
};
|
|
};
|
|
|
|
|
|
|
|
// the sorting parser
|
|
class CSortByStartTime
|
|
: public CResultParser
|
|
{
|
|
protected:
|
|
typedef std::less<CProfLine> PLCompare;
|
|
typedef std::set<CProfLine, PLCompare> PLSet;
|
|
|
|
protected:
|
|
PLSet m_oSet;
|
|
DWORD m_dwThreadId;
|
|
CString m_oOutputFileName;
|
|
|
|
public:
|
|
CSortByStartTime( const CString &roInputFileName, const CString &roOutputFileName )
|
|
: CResultParser( roInputFileName )
|
|
, m_dwThreadId( 0 )
|
|
, m_oOutputFileName( roOutputFileName ){};
|
|
|
|
protected:
|
|
virtual void FProcessLine( const CString &roLine, int )
|
|
{
|
|
CMaxLargeInteger l1, l2;
|
|
|
|
if ( bFGetThreadIdFromLine( roLine, m_dwThreadId ) );
|
|
else if ( bFGetRangeFromLine( roLine, l1, l2 ) )
|
|
m_oSet.insert( CProfLine( m_dwThreadId, l1, roLine ) );
|
|
};
|
|
|
|
virtual void FOutputResults()
|
|
{
|
|
ofstream os( m_oOutputFileName, ios::out | ios::ate );
|
|
PLSet::const_iterator j, k;
|
|
for ( k = j = m_oSet.begin(); m_oSet.end() != j; j++ )
|
|
{
|
|
( *j ).FOutput( os, ( *k ) );
|
|
k = j;
|
|
}
|
|
cout << "Done!" << endl;
|
|
};
|
|
};
|
|
|
|
|
|
|
|
// the delta parser
|
|
class CComputeDelta
|
|
: public CResultParser
|
|
{
|
|
protected:
|
|
int m_nLine1, m_nLine2;
|
|
CString m_oLine1, m_oLine2;
|
|
|
|
public:
|
|
CComputeDelta( const CString &roInputFileName, int nLine1, int nLine2 )
|
|
: CResultParser( roInputFileName )
|
|
, m_nLine1( nLine1 )
|
|
, m_nLine2( nLine2 ){};
|
|
|
|
protected:
|
|
virtual void FProcessLine( const CString &roLine, int nLineNumber )
|
|
{
|
|
if ( nLineNumber == m_nLine1 )
|
|
m_oLine1 = roLine;
|
|
if ( nLineNumber == m_nLine2 )
|
|
m_oLine2 = roLine;
|
|
};
|
|
|
|
virtual void FOutputResults()
|
|
{
|
|
CMaxLargeInteger l1, l2, l3, l4;
|
|
|
|
if ( bFGetRangeFromLine( m_oLine1, l1, l2 ) && bFGetRangeFromLine( m_oLine2, l3, l4 ) )
|
|
{
|
|
CMaxLargeInteger frequency;
|
|
|
|
::QueryPerformanceFrequency( frequency );
|
|
|
|
l3 = l3 + l4;
|
|
cout << endl;
|
|
cout << "Delta in seconds between the lines below was " << CMaxLargeInteger( l3 - l1 ).dFInSecondsF( frequency ) << endl;
|
|
cout << endl;
|
|
cout << m_oLine1 << endl;
|
|
cout << endl;
|
|
cout << m_oLine2 << endl;
|
|
}
|
|
else
|
|
cout << "No result." << endl;
|
|
cout << "Done!" << endl;
|
|
};
|
|
};
|
|
|
|
|
|
|
|
// the little app
|
|
int __cdecl main( int argc, char *argv[] )
|
|
{
|
|
bool bHandled = true;
|
|
cout << "MINIPROFILER output flattener." << endl;
|
|
|
|
// try to handle the command
|
|
if ( argc >= 4 )
|
|
{
|
|
CString command( argv[ 1 ] );
|
|
command.MakeLower();
|
|
|
|
if ( CString( "sort" ) == command )
|
|
CSortByStartTime( CString( argv[ 2 ] ), CString( argv[ 3 ] ) ).FExecute();
|
|
else if ( CString( "diff" ) == command && argc >= 5 )
|
|
CComputeDelta( CString( argv[ 2 ] ), atoi( argv[ 3 ] ), atoi( argv[ 4 ] ) ).FExecute();
|
|
else
|
|
bHandled = false;
|
|
}
|
|
else
|
|
bHandled = false;
|
|
|
|
// give some help if the command was not handled
|
|
if ( !bHandled )
|
|
{
|
|
cout << endl;
|
|
cout << "Please enter one of the following sets of arguments:" << endl;
|
|
cout << endl;
|
|
cout << " 1) the keyword <sort> + the input_result_file + the output_result_file" << endl;
|
|
cout << " comment: outputs a file where nodes are sorted by start time;" << endl;
|
|
cout << " requires an input file generated with history" << endl;
|
|
cout << endl;
|
|
cout << " 2) the keyword <diff> + the input_result_file + line_number_1 + line_number_2" << endl;
|
|
cout << " comment: returns the delta t covered by those 2 lines" << endl;
|
|
cout << endl;
|
|
return 0;
|
|
}
|
|
|
|
return 0;
|
|
}
|