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:
2025-11-29 20:17:20 +09:00
parent 5d3cd64a25
commit dd97ddec92
11602 changed files with 1446576 additions and 0 deletions

View File

@@ -0,0 +1,70 @@
#pragma once
class CDLLModule
{
public:
CDLLModule() : m_hDLL(NULL)
{
}
virtual ~CDLLModule() //destructor, free the library
{
Release();
}
//////////////////////////////////////////////////////////////////
// See if dll been loaded, returning true dose not mean that all
// functions of the dll is valid.
BOOL IsLoaded(void)
{
return m_hDLL != NULL;
}
VOID Release()
{
if( m_hDLL )
::FreeLibrary( m_hDLL );
m_hDLL = NULL;
}
/////////////////////////////////////////////////////////
// pure virtual, must implemented in derived class
// used macros to generate the implementation
virtual BOOL Init( LPCTSTR szDll ) = 0;
protected:
HMODULE m_hDLL;
};
//////////////////////////////////////////////////////////////////////
// macros to implement the Init function
#define DECLARE_DLL_FUNCTION(ret, cc, func, params) \
ret (cc *func)params;
#define BEGIN_DLL_INIT() \
BOOL Init( LPCTSTR szDll ) \
{ \
if( m_hDLL ) \
::FreeLibrary( m_hDLL ); \
m_hDLL = ::LoadLibrary( szDll ); \
BOOL bOk = FALSE;
#define INIT_DLL_TWIN_FUNCTION(ret, cc, func, params, origin) \
if( m_hDLL ) { \
func = (ret (cc* )params) GetProcAddress( m_hDLL, origin ); \
} else \
func = NULL; \
if( func ) \
bOk = TRUE;
#define END_DLL_INIT() \
return bOk; \
}
#define INIT_DLL_FUNCTION(ret, cc, func, params) \
if( m_hDLL ) { \
func = (ret (cc* )params)GetProcAddress( m_hDLL, #func ); \
} else \
func = NULL; \
if( func ) \
bOk = TRUE;

View File

@@ -0,0 +1,21 @@
#ifndef _CUSTOM_DEBUG_MACROS_
#define _CUSTOM_DEBUG_MACROS_
#define _QUOTE(x) # x
#define QUOTE(x) _QUOTE(x)
#define __FILE__LINE__ __FILE__ "(" QUOTE(__LINE__) ") : "
#define NOTE(x) message(x)
#define FILE_LINE message(__FILE__LINE__)
#define TODO(x) message(__FILE__LINE__"\n"\
" -------------------------------------------------\n"\
"| TODO : " x "\n"\
" -------------------------------------------------\n")
#define FIXME(x) message(__FILE__LINE__"\n"\
" -------------------------------------------------\n"\
"| FIXME : " x "\n"\
" -------------------------------------------------\n")
#define todo(x) message(__FILE__LINE__" TODO : " x "\n")
#define fixme(x) message(__FILE__LINE__" FIXME : " x "\n")
#define note(x) message(__FILE__LINE__" NOTE : " x "\n")
#endif

View File

@@ -0,0 +1,82 @@
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <lmerr.h>
#include <stdlib.h>
#include <winsock2.h>
#include <windows.h>
#include "DebugUtils.h"
//
// Set application-name for prefix of log filename
//
void DbgUtils::SetProgramName(TCHAR* pszOutBuffer, int nBufferSize, TCHAR* pszProgramName)
{
if(0 == pszProgramName)
{
TCHAR szDrive[MAX_PATH], szDir[MAX_PATH], szFilename[MAX_PATH], szExt[MAX_PATH];
// Figure out what the report file will be named, and store it away
GetModuleFileName(0, pszOutBuffer, nBufferSize);
PTSTR pszDot = pszOutBuffer;
// Look for the '.' before the "EXE" extension. Replace '.' to '\0'
if((pszDot = _tcsrchr( pszDot, _T('.'))))
{
*pszDot = 0;
}
_tsplitpath(pszOutBuffer, szDrive, szDir, szFilename, szExt);
_tcsncpy(pszOutBuffer, szFilename, nBufferSize);
}
else
{
_tcsncpy(pszOutBuffer, pszProgramName, nBufferSize);
}
}
DbgUtils::CConvertErrorToText& DbgUtils::CConvertErrorToText::GetInstance()
{
static CConvertErrorToText convertErrorToText;
return convertErrorToText;
}
DbgUtils::CConvertErrorToText::CConvertErrorToText()
: m_hNetMsg(LoadLibraryEx(TEXT("netmsg.dll"), NULL, LOAD_LIBRARY_AS_DATAFILE))
{
}
DbgUtils::CConvertErrorToText::~CConvertErrorToText()
{
if(0 != m_hNetMsg)
{
FreeLibrary(m_hNetMsg);
}
}
unsigned long DbgUtils::CConvertErrorToText::GetErrorTextBuffer(TCHAR* lpMessage,
unsigned long dwBufferLen,
unsigned long dwLastError)
{
unsigned long dwFormatFlags = FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM;
LPCVOID lpModule = 0;
if (dwLastError >= NERR_BASE && dwLastError <= MAX_NERR && 0 != m_hNetMsg)
{
lpModule = m_hNetMsg;
dwFormatFlags |= FORMAT_MESSAGE_FROM_HMODULE;
}
return FormatMessage(dwFormatFlags, lpModule, dwLastError,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), lpMessage, dwBufferLen, 0);
}

View File

@@ -0,0 +1,29 @@
#ifndef _DEBUG_UTILS_H_
#define _DEBUG_UTILS_H_
#include <tchar.h>
namespace DbgUtils
{
class CConvertErrorToText;
void SetProgramName(TCHAR* pszOutBuffer, int nBufferSize, TCHAR* pszProgamName = 0);
};
class DbgUtils::CConvertErrorToText
{
public:
unsigned long GetErrorTextBuffer(TCHAR* lpMessage,
unsigned long dwBufferLen, unsigned long dwLastError);
static CConvertErrorToText& GetInstance();
private:
CConvertErrorToText();
~CConvertErrorToText();
HMODULE m_hNetMsg;
};
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,174 @@
#pragma once
#include <dbghelp.h>
#include <cstdio>
#include "DLLModule.h"
#pragma comment(lib, "dbghelp.lib")
class CDBGFuncClass : public CDLLModule
{
public :
DECLARE_DLL_FUNCTION( BOOL, WINAPI, MiniDumpWriteDump, ( HANDLE, unsigned long, HANDLE, MINIDUMP_TYPE, CONST PMINIDUMP_EXCEPTION_INFORMATION, CONST PMINIDUMP_USER_STREAM_INFORMATION, CONST PMINIDUMP_CALLBACK_INFORMATION ) )
DECLARE_DLL_FUNCTION( BOOL, WINAPI, SymEnumSymbols, ( HANDLE, ULONG64, PCSTR, PSYM_ENUMERATESYMBOLS_CALLBACK, PVOID ) )
DECLARE_DLL_FUNCTION( ULONG, WINAPI, SymSetContext, ( HANDLE, PIMAGEHLP_STACK_FRAME, PIMAGEHLP_CONTEXT ) )
DECLARE_DLL_FUNCTION( BOOL, WINAPI, SymFromAddr, ( HANDLE, DWORD64, PDWORD64, PSYMBOL_INFO ) )
DECLARE_DLL_FUNCTION( BOOL, WINAPI, StackWalk, ( unsigned long, HANDLE, HANDLE, LPSTACKFRAME, PVOID, PREAD_PROCESS_MEMORY_ROUTINE, PFUNCTION_TABLE_ACCESS_ROUTINE, PGET_MODULE_BASE_ROUTINE, PTRANSLATE_ADDRESS_ROUTINE ) )
// DECLARE_DLL_FUNCTION( BOOL, WINAPI, StackWalk64, ( unsigned long, HANDLE, HANDLE, LPSTACKFRAME64, PVOID, PREAD_PROCESS_MEMORY_ROUTINE64, PFUNCTION_TABLE_ACCESS_ROUTINE64, PGET_MODULE_BASE_ROUTINE64, PTRANSLATE_ADDRESS_ROUTINE64 ) )
DECLARE_DLL_FUNCTION( BOOL, WINAPI, SymGetLineFromAddr, ( HANDLE, unsigned long, PDWORD, PIMAGEHLP_LINE ) ) // ImageHlp
DECLARE_DLL_FUNCTION( BOOL, WINAPI, SymGetLineFromAddr64, ( HANDLE, DWORD64, PDWORD, PIMAGEHLP_LINE64 ) )
DECLARE_DLL_FUNCTION( PVOID, WINAPI, SymFunctionTableAccess, ( HANDLE, unsigned long ) ) // ImageHlp
// DECLARE_DLL_FUNCTION( PVOID, WINAPI, SymFunctionTableAccess64, ( HANDLE, DWORD64 ) )
DECLARE_DLL_FUNCTION( DWORD64,WINAPI, SymGetModuleBase64, ( HANDLE, DWORD64 ) )
DECLARE_DLL_FUNCTION( BOOL, WINAPI, SymInitialize, ( HANDLE, PSTR, BOOL ) )
DECLARE_DLL_FUNCTION( unsigned long, WINAPI, SymSetOptions, ( unsigned long ) )
DECLARE_DLL_FUNCTION( BOOL, WINAPI, SymCleanup, ( HANDLE ) )
DECLARE_DLL_FUNCTION( unsigned long, WINAPI, SymGetModuleBase, ( HANDLE, unsigned long ) )
// DECLARE_DLL_FUNCTION( DWORD64,WINAPI, SymGetModuleBase64, ( HANDLE, DWORD64 ) )
DECLARE_DLL_FUNCTION( BOOL, WINAPI, SymGetTypeInfo, ( HANDLE, DWORD64, ULONG, IMAGEHLP_SYMBOL_TYPE_INFO, PVOID ) )
public:
BEGIN_DLL_INIT()
INIT_DLL_FUNCTION( BOOL, WINAPI, MiniDumpWriteDump, ( HANDLE, unsigned long, HANDLE, MINIDUMP_TYPE, CONST PMINIDUMP_EXCEPTION_INFORMATION, CONST PMINIDUMP_USER_STREAM_INFORMATION, CONST PMINIDUMP_CALLBACK_INFORMATION ) )
INIT_DLL_FUNCTION( BOOL, WINAPI, SymEnumSymbols, ( HANDLE, ULONG64, PCSTR, PSYM_ENUMERATESYMBOLS_CALLBACK, PVOID ) )
INIT_DLL_FUNCTION( ULONG, WINAPI, SymSetContext, ( HANDLE, PIMAGEHLP_STACK_FRAME, PIMAGEHLP_CONTEXT ) )
INIT_DLL_FUNCTION( BOOL, WINAPI, SymFromAddr, ( HANDLE, DWORD64, PDWORD64, PSYMBOL_INFO ) )
INIT_DLL_FUNCTION( BOOL, WINAPI, StackWalk, ( unsigned long, HANDLE, HANDLE, LPSTACKFRAME, PVOID, PREAD_PROCESS_MEMORY_ROUTINE, PFUNCTION_TABLE_ACCESS_ROUTINE, PGET_MODULE_BASE_ROUTINE, PTRANSLATE_ADDRESS_ROUTINE ) )
// INIT_DLL_FUNCTION( BOOL, WINAPI, StackWalk64, ( unsigned long, HANDLE, HANDLE, LPSTACKFRAME64, PVOID, PREAD_PROCESS_MEMORY_ROUTINE64, PFUNCTION_TABLE_ACCESS_ROUTINE64, PGET_MODULE_BASE_ROUTINE64, PTRANSLATE_ADDRESS_ROUTINE64 ) )
INIT_DLL_FUNCTION( BOOL, WINAPI, SymGetLineFromAddr, ( HANDLE, unsigned long, PDWORD, PIMAGEHLP_LINE ) ) // ImageHlp
INIT_DLL_FUNCTION( BOOL, WINAPI, SymGetLineFromAddr64, ( HANDLE, DWORD64, PDWORD, PIMAGEHLP_LINE64 ) )
INIT_DLL_FUNCTION( PVOID, WINAPI, SymFunctionTableAccess, ( HANDLE, unsigned long ) )
// INIT_DLL_FUNCTION( PVOID, WINAPI, SymFunctionTableAccess64, ( HANDLE, DWORD64 ) )
INIT_DLL_FUNCTION( DWORD64,WINAPI, SymGetModuleBase64, ( HANDLE, DWORD64 ) )
INIT_DLL_FUNCTION( BOOL, WINAPI, SymInitialize, ( HANDLE, PSTR, BOOL ) )
INIT_DLL_FUNCTION( unsigned long, WINAPI, SymSetOptions, ( unsigned long ) )
INIT_DLL_FUNCTION( BOOL, WINAPI, SymCleanup, ( HANDLE ) )
INIT_DLL_FUNCTION( unsigned long, WINAPI, SymGetModuleBase, ( HANDLE, unsigned long ) )
// INIT_DLL_FUNCTION( DWORD64,WINAPI, SymGetModuleBase64, ( HANDLE, DWORD64 ) )
INIT_DLL_FUNCTION( BOOL, WINAPI, SymGetTypeInfo, ( HANDLE, DWORD64, ULONG, IMAGEHLP_SYMBOL_TYPE_INFO, PVOID ) )
END_DLL_INIT()
};
enum BasicType // Stolen from CVCONST.H in the DIA 2.0 SDK
{
btNoType = 0,
btVoid = 1,
btChar = 2,
btWChar = 3,
btInt = 6,
btUInt = 7,
btFloat = 8,
btBCD = 9,
btBool = 10,
btLong = 13,
btULong = 14,
btCurrency = 25,
btDate = 26,
btVariant = 27,
btComplex = 28,
btBit = 29,
btBSTR = 30,
btHresult = 31
};
class CExceptionReport
{
public:
static CExceptionReport& GetInstance();
typedef int (WINAPI *UserFunc)(TCHAR* szBuffer, const int nBufferSize);
enum Features
{
CATCH_EXCEPTION = (1 << 0),
USE_MINIDUMP = (1 << 1),
USE_REPORT = (1 << 2)
};
void Enable(unsigned long dwEnableFeature);
void Disable(unsigned long dwDisableFeature);
void SetDumpLevel(MINIDUMP_TYPE eMiniDumpType) { m_eMiniDumpType = eMiniDumpType; }
void SetUserFunc(UserFunc lpUserFunc) { m_lpUserFunc = lpUserFunc; }
void WriteExceptionReport(PEXCEPTION_POINTERS pExceptionInfo);
static void SetProgramName(TCHAR* pszOutBuffer, int nBufferSize, TCHAR* pszProgramName);
static int WriteBasicInfo(TCHAR* szBuffer_Out, const int nBufferSize, PEXCEPTION_RECORD pExceptionRecord);
static int WriteRegistersInfo(TCHAR* szBuffer_Out, const int nBufferSize, PCONTEXT pContext);
static int WriteMemoryDump(TCHAR* szBuffer_Out, const int nBufferSize, PCONTEXT pContext,
unsigned int nMaxIPDump = 16, unsigned int nMaxStackDump = 1024);
static int WriteStackDetails(TCHAR* szBuffer_Out, const int nBufferSize,
PCONTEXT pContext, BOOL bWriteVariables, BOOL& bHasSymbol_Out, const int nStackDepth = 256);
static int Dump(TCHAR* szBuffer_Out, const int nBufferSize,
DWORD64 pData, unsigned long dwSize, BOOL bAlign);
CDBGFuncClass& GetDBGFuncClass() { return m_DBGHELP; }
private:
CExceptionReport();
~CExceptionReport();
void CloseLogFile();
LONG ProcessException(PEXCEPTION_POINTERS lpExceptionInfo);
LONG ProcessSecondException(PEXCEPTION_POINTERS lpExceptionInfo);
static LONG WINAPI UnhandledExceptionFilter(PEXCEPTION_POINTERS lpExceptionInfo) { return CExceptionReport::GetInstance().ProcessException(lpExceptionInfo); }
static LONG WINAPI UnhandledSecondExceptionFilter(PEXCEPTION_POINTERS lpExceptionInfo) { return CExceptionReport::GetInstance().ProcessSecondException(lpExceptionInfo); }
static void StoreCoreDump(void);
static LPTSTR GetExceptionString( unsigned long dwCode );
static BOOL GetLogicalAddress(PVOID addr, PTSTR szModule, unsigned long len, unsigned long& section, unsigned long& offset );
static BOOL CALLBACK EnumerateSymbolsCallback(PSYMBOL_INFO,ULONG, PVOID);
static BOOL FormatSymbolValue(PSYMBOL_INFO, STACKFRAME *, TCHAR * pszBuffer, unsigned nBufferSize);
static int DumpTypeIndex(TCHAR* szBuffer_Out,
const int nBufferSize, DWORD64 modBase, unsigned long dwTypeIndex,
unsigned int nestingLevel, DWORD_PTR offset, BOOL & bHandled);
static int FormatOutputValue(TCHAR* pszCurrBuffer,
const int nBufferSize, BasicType basicType, DWORD64 length, PVOID pAddress);
static BasicType GetBasicType(unsigned long typeIndex, DWORD64 modBase);
// ---------------------------------------------------------------------
// Data
enum
{
SHIFT_NUM = 4,
BYTES_PER_LINE = 16,
MAX_TEMP_VALUE = 5,
MAX_LOG_BUFFER = 65535 // 64-kb log buffer
};
CDBGFuncClass m_DBGHELP;
UserFunc m_lpUserFunc;
LPTOP_LEVEL_EXCEPTION_FILTER m_OldFilter;
TCHAR m_szLogPrefixName[MAX_PATH];
TCHAR m_szModuleName[MAX_PATH];
TCHAR m_szTempBuffer[MAX_PATH];
TCHAR m_szLogBuffer[MAX_LOG_BUFFER];
CONTEXT m_tempContext;
SYSTEMTIME m_tempSystemTime;
MINIDUMP_EXCEPTION_INFORMATION m_miniDumpInfo;
FILE* m_logFile;
BOOL m_bHasSymbol;
unsigned long m_dwFeaturesFlag;
MINIDUMP_TYPE m_eMiniDumpType;
};

View File

@@ -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;
}

View File

@@ -0,0 +1,196 @@
#ifndef _FUNCTION_PERFORMANCE_CHECK_H_
#define _FUNCTION_PERFORMANCE_CHECK_H_
#include <winsock2.h>
#include <windows.h>
#include <map>
#include "../../Thread/Lock.h"
#include "../../Pattern/Singleton.h"
#define _USING_REALCLOCK
#if defined(_USING_REALCLOCK) && _M_IX86 >= 500
#define RealClock(Large_Integer_In) \
{ __asm rdtsc __asm mov Large_Integer_In.HighPart, edx __asm mov Large_Integer_In.LowPart, eax }
#define ClockSnapShot(Large_Integer_Out, UniqueVariableName) \
LARGE_INTEGER SnapShot##UniqueVariableName; \
RealClock(SnapShot##UniqueVariableName); \
Large_Integer_Out = SnapShot##UniqueVariableName
#define ClockPerSec(Large_Integer_Frequency_Out, UniqueVariableName) \
LARGE_INTEGER Start##UniqueVariableName, Stop##UniqueVariableName; \
RealClock(Start##UniqueVariableName) \
Sleep(1000); \
RealClock(Stop##UniqueVariableName) \
Large_Integer_Frequency_Out.QuadPart = \
Stop##UniqueVariableName.QuadPart - Start##UniqueVariableName.QuadPart - 57UL
#else
#define ClockSnapShot(Large_Integer_Out, UniqueVariableName) \
QueryPerformanceCounter(&Large_Integer_Out)
#define ClockPerSec(Large_Integer_Frequency_Out, UniqueVariableName) \
QueryPerformanceFrequency(&Large_Integer_Frequency_Out)
#endif
// ------------------------------------------------------------------------------------------------
// <20><> <20>Լ<EFBFBD><D4BC><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD>.
// identifiler<65><72> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>ԵǹǷ<C7B9>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><>Ģ<EFBFBD><C4A2> <20><><EFBFBD><EFBFBD><EFBFBD>ϰ<EFBFBD> <20><> <20><>.
// blockName<6D><65> <20>ݵ<EFBFBD><DDB5><EFBFBD> <20><><EFBFBD>ڿ<EFBFBD> <20><><EFBFBD>ͷ<EFBFBD><CDB7><EFBFBD> <20><> <20><>.
#define DeclareBlockTimingCheck(blockName, identifiler) \
CPerformanceInstrument blockInstrument##identifiler(blockName);
#define BlockTimingCheckStart(identifiler) \
blockInstrument##identifiler.Start();
#define BlockTimingCheckStop(identifiler) \
blockInstrument##identifiler.Stop();
// ------------------------------------------------------------------------------------------------
// <20><> <20>Լ<EFBFBD><D4BC><EFBFBD><EFBFBD><EFBFBD> <20>Ѱ<EFBFBD><D1B0><EFBFBD> <20><> <20><> <20><><EFBFBD><EFBFBD>.
#define FunctionTimingCheck \
CPerformanceInstrument functionInstrument(__FUNCTION__); \
CAutoInstrument autofunctionInstrument(functionInstrument);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>Ϸ<EFBFBD> <20><><EFBFBD><EFBFBD>. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ʱ<EFBFBD>ȭ<EFBFBD>Ѵ<EFBFBD>.
#define GetFunctionTimingResult(fileName) \
CPerformanceCheck::GetInstance().PrintAllTime(fileName);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>Ϸ<EFBFBD> <20><><EFBFBD><EFBFBD>. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʱ<EFBFBD>ȭ<EFBFBD><C8AD><EFBFBD><EFBFBD> <20>ʴ´<CAB4>.
#define GetFunctionTimingResultNoReset(fileName) \
CPerformanceCheck::GetInstance().PrintAllTime(fileName, false);
class CPerformanceCheck
{
public:
static CPerformanceCheck& GetInstance();
typedef void (*FnPrintUserMessage) (FILE* fDescriptor);
void SetUserMessageFunc(FnPrintUserMessage fnPreFix = 0, FnPrintUserMessage fnPostFix = 0);
void AddTime(const char* szfunctionName, double fEstimateTime);
bool PrintAllTime(const char* fileName, bool bReset = true);
private:
CPerformanceCheck();
~CPerformanceCheck();
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
struct Instrument
{
double m_fProcessTime;
double m_fMinTime;
double m_fMaxTime;
unsigned long m_dwHashKey;
unsigned long m_dwCalled;
const char* m_szFunctionName;
Instrument(unsigned long dwHashKey, double fProcessTime, const char* szFunctionName)
: m_dwHashKey(dwHashKey), m_fProcessTime(fProcessTime), m_dwCalled(1),
m_fMinTime(fProcessTime), m_fMaxTime(fProcessTime),
m_szFunctionName(szFunctionName) { }
Instrument()
: m_fProcessTime(0.0f), m_fMinTime(0.0f), m_fMaxTime(0.0f),
m_dwCalled(1), m_dwHashKey(0),
m_szFunctionName(NULL) { }
void Initialize()
{
m_fProcessTime = m_fMinTime = m_fMaxTime = 0.0f;
m_dwCalled = 0;
}
};
typedef CCSLock PerformanceCheckLock;
typedef std::multimap<unsigned long, Instrument> PerformanceTable;
PerformanceCheckLock m_TableLock;
CACHE_PAD(PerformanceCheckLockPad, sizeof(PerformanceCheckLock));
LARGE_INTEGER m_Frequency;
double m_fFrequency;
PerformanceTable m_InstrumentTable;
FnPrintUserMessage m_fnPreFix;
FnPrintUserMessage m_fnPostFix;
};
class CPerformanceInstrument
{
public:
CPerformanceInstrument(char* szfunctionName)
: m_szfunctionName(szfunctionName)
{
m_startTime.QuadPart = 0;
CPerformanceCheck::GetInstance().AddTime(m_szfunctionName, 0);
}
CPerformanceInstrument()
: m_szfunctionName(0)
{
m_startTime.QuadPart = 0;
}
void SetName(char* szfunctionName) { m_szfunctionName = szfunctionName; }
~CPerformanceInstrument() { }
inline void Start();
inline void Stop();
private:
LARGE_INTEGER m_startTime;
LARGE_INTEGER m_stopTime;
char* m_szfunctionName;
};
inline void CPerformanceInstrument::Start()
{
m_stopTime.QuadPart = 0;
ClockSnapShot(m_startTime, startTime);
}
inline void CPerformanceInstrument::Stop()
{
ClockSnapShot(m_stopTime, stopTime);
if(0 == m_stopTime.QuadPart) { ++m_stopTime.QuadPart; }
CPerformanceCheck::GetInstance().AddTime(m_szfunctionName,
static_cast<double>(m_stopTime.QuadPart - m_startTime.QuadPart));
}
class CAutoInstrument
{
public:
CAutoInstrument(CPerformanceInstrument& PerformanceInstrument)
: m_PerformanceInstrument(PerformanceInstrument) { m_PerformanceInstrument.Start(); }
~CAutoInstrument() { m_PerformanceInstrument.Stop(); }
private:
CPerformanceInstrument& m_PerformanceInstrument;
};
#endif