Restructure repository to include all source folders
Move git root from Client/ to src/ to track all source code: - Client: Game client source (moved to Client/Client/) - Server: Game server source - GameTools: Development tools - CryptoSource: Encryption utilities - database: Database scripts - Script: Game scripts - rylCoder_16.02.2008_src: Legacy coder tools - GMFont, Game: Additional resources 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,194 @@
|
||||
#include "stdafx.h"
|
||||
#include <utility>
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
|
||||
#include "DebugUtils.h"
|
||||
#include "PerformanceCheck.h"
|
||||
|
||||
|
||||
CPerformanceCheck& CPerformanceCheck::GetInstance()
|
||||
{
|
||||
static CPerformanceCheck performanceCheck;
|
||||
return performanceCheck;
|
||||
}
|
||||
|
||||
|
||||
CPerformanceCheck::CPerformanceCheck()
|
||||
: m_fnPreFix(0), m_fnPostFix(0)
|
||||
{
|
||||
ClockPerSec(m_Frequency, Frequency);
|
||||
m_fFrequency = static_cast<double>(m_Frequency.QuadPart);
|
||||
}
|
||||
|
||||
CPerformanceCheck::~CPerformanceCheck()
|
||||
{
|
||||
PerformanceCheckLock::Syncronize sync(m_TableLock);
|
||||
m_InstrumentTable.clear();
|
||||
}
|
||||
|
||||
void CPerformanceCheck::SetUserMessageFunc(FnPrintUserMessage fnPreFix, FnPrintUserMessage fnPostFix)
|
||||
{
|
||||
m_fnPreFix = fnPreFix;
|
||||
m_fnPostFix = fnPostFix;
|
||||
}
|
||||
|
||||
inline unsigned long perf_sdbmHash(const unsigned char *str)
|
||||
{
|
||||
unsigned long hash = 0;
|
||||
int c;
|
||||
|
||||
while (c = *str++) { hash = c + (hash << 6) + (hash << 16) - hash; }
|
||||
return hash;
|
||||
}
|
||||
|
||||
void CPerformanceCheck::AddTime(const char* szfunctionName, double fEstimateTime)
|
||||
{
|
||||
unsigned long dwHashedKey = perf_sdbmHash(reinterpret_cast<const unsigned char*>(szfunctionName));
|
||||
|
||||
PerformanceCheckLock::Syncronize sync(m_TableLock);
|
||||
|
||||
fEstimateTime /= m_fFrequency;
|
||||
|
||||
std::pair<PerformanceTable::iterator, PerformanceTable::iterator> itrPair =
|
||||
m_InstrumentTable.equal_range(dwHashedKey);
|
||||
|
||||
for(;itrPair.first != itrPair.second; ++itrPair.first)
|
||||
{
|
||||
Instrument& instrument = itrPair.first->second;
|
||||
if(0 == strcmp(szfunctionName, instrument.m_szFunctionName))
|
||||
{
|
||||
// <20><><EFBFBD>̺<EFBFBD><CCBA><EFBFBD><EFBFBD><EFBFBD> ã<><C3A3> <20><><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD> <20><><EFBFBD>Ѵ<EFBFBD>.
|
||||
instrument.m_fProcessTime += fEstimateTime;
|
||||
if(instrument.m_fMinTime > fEstimateTime) { instrument.m_fMinTime = fEstimateTime; }
|
||||
if(instrument.m_fMaxTime < fEstimateTime) { instrument.m_fMaxTime = fEstimateTime; }
|
||||
++instrument.m_dwCalled;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// <20><><EFBFBD>̺<EFBFBD><CCBA><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʴ<EFBFBD> <20><><EFBFBD><EFBFBD>, <20>о<EFBFBD> <20>ִ´<D6B4>.
|
||||
m_InstrumentTable.insert(std::make_pair(dwHashedKey, Instrument(dwHashedKey, fEstimateTime, szfunctionName)));
|
||||
}
|
||||
|
||||
|
||||
bool CPerformanceCheck::PrintAllTime(const char* fileName, bool bReset)
|
||||
{
|
||||
if(m_InstrumentTable.empty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
char strLogPath[MAX_PATH];
|
||||
char strLogFileName[MAX_PATH];
|
||||
|
||||
DbgUtils::SetProgramName(strLogPath, MAX_PATH, 0);
|
||||
|
||||
// create the directory if it doesn't exist
|
||||
if (INVALID_FILE_ATTRIBUTES == GetFileAttributes(strLogPath))
|
||||
{
|
||||
if (!CreateDirectory(strLogPath, 0))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// create log file name in good order
|
||||
unsigned long dwSpinCount = 0;
|
||||
unsigned long dwMaxFileSize = 50 * 1024 * 1024;
|
||||
|
||||
while(true)
|
||||
{
|
||||
_sntprintf(strLogFileName, MAX_PATH, "%s/PerformanceLog-%s-%05d.log",
|
||||
strLogPath, fileName, dwSpinCount);
|
||||
|
||||
HANDLE hLogFile = CreateFile(strLogFileName, GENERIC_WRITE,
|
||||
FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0 );
|
||||
|
||||
if(INVALID_HANDLE_VALUE == hLogFile)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned long dwHighValue = 0;
|
||||
unsigned long dwFileSize = GetFileSize(hLogFile, &dwHighValue);
|
||||
|
||||
CloseHandle(hLogFile);
|
||||
|
||||
if(dwHighValue == 0 && dwFileSize < dwMaxFileSize)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
++dwSpinCount;
|
||||
}
|
||||
|
||||
// create log file
|
||||
PerformanceCheckLock::Syncronize sync(m_TableLock);
|
||||
|
||||
FILE* logFile = fopen(strLogFileName, "at");
|
||||
|
||||
if(0 == logFile)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if(0 != m_fnPreFix)
|
||||
{
|
||||
m_fnPreFix(logFile);
|
||||
}
|
||||
|
||||
fprintf(logFile,
|
||||
" Average : Minimum : Maximum : Total : # : Profile Name\n"
|
||||
"------------------------------------------------------------------------------------------------\n" );
|
||||
|
||||
double fTotalAvgTime = 0;
|
||||
|
||||
PerformanceTable::iterator pos;
|
||||
PerformanceTable::iterator end;
|
||||
|
||||
for(pos = m_InstrumentTable.begin(),
|
||||
end = m_InstrumentTable.end();
|
||||
pos != end; ++pos)
|
||||
{
|
||||
const Instrument& instrument = pos->second;
|
||||
|
||||
if(0 == instrument.m_szFunctionName)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const double fAvgTime = (0.0f == instrument.m_fProcessTime) ?
|
||||
0.0f : (instrument.m_fProcessTime / instrument.m_dwCalled); // Average
|
||||
|
||||
fTotalAvgTime += fAvgTime;
|
||||
|
||||
fprintf(logFile, " %3.6f %3.6f %3.6f %8.1f %10d %s\n",
|
||||
fAvgTime, instrument.m_fMinTime, instrument.m_fMaxTime,
|
||||
instrument.m_fProcessTime, instrument.m_dwCalled, instrument.m_szFunctionName);
|
||||
}
|
||||
|
||||
fprintf(logFile, "\n\n Total AvgTime : %3.6f\n\n\n", fTotalAvgTime);
|
||||
|
||||
if(0 != m_fnPostFix)
|
||||
{
|
||||
m_fnPostFix(logFile);
|
||||
}
|
||||
|
||||
fclose(logFile);
|
||||
|
||||
if(bReset)
|
||||
{
|
||||
for(pos = m_InstrumentTable.begin(),
|
||||
end = m_InstrumentTable.end();
|
||||
pos != end; ++pos)
|
||||
{
|
||||
pos->second.Initialize();
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user