📄 profile.c
字号:
pEntry = GetEntryPointer(dwProfileCount);
dwProfileCount++; // inc profile count
//
// Record an entry point
//
pEntry->ra = ra;
pEntry->pte = pCurProc->oe.tocptr;
} else {
//
// No place to record this hit. Let's remember how many we dropped.
//
dwBufRecDropped++;
}
} else {
//
// No buffer. Just lookup the symbol now.
//
dwProfileCount++;
ProfilerSymbolHit(ra,pCurProc->oe.tocptr);
}
}
/*
* ClearProfileHits - zero all profiler counters
*
*/
void ClearProfileHits(void) {
unsigned int iMod=0;
PROFentry *profptr;
SYMentry *symptr;
unsigned int iSym;
if (!pTOC->ulProfileLen) // if no profile section
return; // just return
// profptr-> first profile entry
profptr= (PROFentry *)pTOC->ulProfileOffset;
while (iMod++ < pTOC->nummods) {
profptr->ulHits=0; // clear module hit count
if (profptr->ulNumSym) { // if there are symbols for this module
iSym=profptr->ulNumSym; // clear symbol hits
symptr=(SYMentry*)profptr->ulHitAddress;
while (iSym) {
symptr->ulFuncHits=0;
iSym--;
symptr++;
}
}
profptr++;
}
dwBufRecDropped = 0;
}
//---------------------------------------------------------------------------
// GetSymbol - searches symbol table for passed symbol number
//
// Input: lpSym - pointer to start of symbol buffer
// dwSymNum - symbol number to lookup
//
// Output: returns pointer to symbol
//---------------------------------------------------------------------------
static LPBYTE GetSymbol(LPBYTE lpSym, DWORD dwSymNum)
{
while (dwSymNum > 0) {
while (*lpSym++);
dwSymNum--;
}
return lpSym;
}
//---------------------------------------------------------------------------
// ProfilerReport -display hit report
//
//
//---------------------------------------------------------------------------
void ProfilerReport(void)
{
DWORD loop, loop2, loop3; // index
PROFentry *pProf; // profile section pointer
DWORD dwSymCount=0; // number of symbols hit
ULONG ulPercent; // hit percentage
DWORD dwNumModules; // number of modules
SYMentry *pSym; // symbol address/hit pointer
SYMentry *pHits=NULL; // hit sorting structure pointer
SYMentry symTemp; // sorting temp
LPBYTE lpSymData=0; // symbol data pointer
ULONG ulTotalPercent; // total percent of modules
ULONG ulTotalHits;
TOCentry *tocptr;
DWORD dwHits[200],dwMods[200],dwNumHits=0,dwTemp;
PPROFBUFENTRY pEntry;
if (dwProfileCount) // if profile size==0, profiling disabled
{
if (bProfileBuffer) { // if profiling to buffer, lookup symbols now
PROFILEMSG(1,(TEXT("ProfileReport: Looking up symbols for %u hits.\r\n"),dwProfileCount));
for (loop=0; loop<dwProfileCount; loop++) {
if (loop%10000 == 0) // display a . every 10000 hits, so user knows we are working
PROFILEMSG(1,(TEXT(".")));
pEntry = GetEntryPointer(loop);
ProfilerSymbolHit(pEntry->ra, pEntry->pte);
}
PROFILEMSG(1,(TEXT("\r\n")));
}
pProf= (PROFentry *)pTOC->ulProfileOffset;
lpSymData= (LPBYTE)pProf->ulSymAddress;
dwNumModules= pTOC->nummods;
// display hits by module and count number of symbols hit
PROFILEMSG(1,(TEXT("Total samples recorded = %lu\r\n"),dwProfileCount));
if (dwBufRecDropped) {
PROFILEMSG(1,(TEXT("Total samples dropped = %lu\r\n"),dwBufRecDropped));
}
PROFILEMSG(1,(TEXT("Module Hits Percent\r\n")));
PROFILEMSG(1,(TEXT("------------ ---------- -------\r\n")));
ulTotalPercent=0;
ulTotalHits=0;
if (dwProfileCount) { // if any samples were collected
// sort the samples
pProf= (PROFentry *)pTOC->ulProfileOffset;
for (loop=0; loop<dwNumModules; loop++) {
if (pProf->ulHits){ // if there were any hits
dwHits[dwNumHits]= pProf->ulHits;
dwMods[dwNumHits]=loop;
dwNumHits++;
}
pProf++;
}
for (loop=1; loop<dwNumHits; loop++) {
for (loop2=dwNumHits-1; loop2 >= loop; loop2--) {
if (dwHits[loop2-1] < dwHits[loop2]) {
dwTemp= dwHits[loop2-1];
dwHits[loop2-1]= dwHits[loop2];
dwHits[loop2]= dwTemp;
dwTemp= dwMods[loop2-1];
dwMods[loop2-1]= dwMods[loop2];
dwMods[loop2]= dwTemp;
}
}
}
// for each profile entry
for (loop=0; loop<dwNumHits; loop++) {
tocptr = (TOCentry *)(pTOC+1);
tocptr+= dwMods[loop];
pProf= (PROFentry *)pTOC->ulProfileOffset;
pProf+= dwMods[loop];
if (pProf->ulHits) { // if there were any hits
// display module name, hits, percentage
ulPercent= pProf->ulHits;
ulPercent*=1000;
ulPercent/=dwProfileCount;
ulTotalPercent+= ulPercent;
ulTotalHits+= pProf->ulHits;
PROFILEMSG(1,(TEXT("%-12a %10lu %5lu.%1d\r\n"),
tocptr->lpszFileName,pProf->ulHits, ulPercent / 10,ulPercent % 10));
// inc total number of symbols
pSym= (SYMentry *)pProf->ulHitAddress;
// for each symbol hit
for (loop2=0; loop2<pProf->ulNumSym; loop2++) {
if (pSym->ulFuncHits) {
ulPercent= pSym->ulFuncHits;
ulPercent*=100;
ulPercent/=dwProfileCount;
dwSymCount++;
}
pSym++;
}
}
}
ulTotalPercent= 1000-ulTotalPercent;
ulTotalHits= dwProfileCount-ulTotalHits;
if (ulTotalHits)
PROFILEMSG(1,(TEXT("%-12a %10lu %5lu.%1d\r\n"),
"UNKNOWN",ulTotalHits,ulTotalPercent/10,ulPercent%10));
if (!dwSymCount) {
PROFILEMSG(1,(TEXT("No symbols found.\r\n")));
goto profile_exit;
}
// allocate memory for sorting
pHits=(SYMentry *)VirtualAlloc(NULL,dwSymCount*sizeof(SYMentry),MEM_COMMIT|MEM_RESERVE,PAGE_READWRITE);
if (pHits == NULL) {
PROFILEMSG(1,(TEXT("ProfileStop: Sort memory allocation size %u failed.\r\n"),dwSymCount*sizeof(SYMentry)));
goto profile_exit;
}
// build a table of offsets for each symbol
// so it can be sorted
dwSymCount=0;
pProf= (PROFentry *)pTOC->ulProfileOffset;
for (loop=0; loop<dwNumModules; loop++) {
if (pProf->ulHits) {
pSym= (SYMentry *)pProf->ulHitAddress;
// for each symbol hit
for (loop2=0; loop2<pProf->ulNumSym; loop2++) {
if (pSym->ulFuncHits) {
ulPercent= pSym->ulFuncHits;
ulPercent*=100;
ulPercent/=dwProfileCount;
pHits[dwSymCount].ulFuncAddress=pSym->ulFuncAddress;
pHits[dwSymCount++].ulFuncHits=pSym->ulFuncHits;
}
pSym++;
}
}
pProf++;
}
// sort the symbols (decreasing hits)
for (loop=1; loop<dwSymCount; loop++) {
for (loop2=dwSymCount-1; loop2 >= loop; loop2--) {
if ((unsigned int)pHits[loop2-1].ulFuncHits < (unsigned int)pHits[loop2].ulFuncHits) {
symTemp.ulFuncHits=pHits[loop2-1].ulFuncHits;
symTemp.ulFuncAddress=pHits[loop2-1].ulFuncAddress;
pHits[loop2-1].ulFuncHits=pHits[loop2].ulFuncHits;
pHits[loop2-1].ulFuncAddress=pHits[loop2].ulFuncAddress;
pHits[loop2].ulFuncHits=symTemp.ulFuncHits;
pHits[loop2].ulFuncAddress=symTemp.ulFuncAddress;
}
}
}
// display hit list
PROFILEMSG(1,(TEXT("Hits Percent Address Module Routine\r\n")));
PROFILEMSG(1,(TEXT("---------- ------- -------- ------------:---------------------\r\n")));
// for each symbol
for (loop=0; loop<dwSymCount && loop < NUM_SYMBOLS; loop++) {
// find profile entry for this symbol
pProf= (PROFentry *)pTOC->ulProfileOffset;
tocptr = (TOCentry *)(pTOC+1);
for (loop2=0; loop2<dwNumModules; loop2++) {
pSym= (SYMentry *)pProf->ulHitAddress;
// for each symbol hit
for (loop3=0; loop3<pProf->ulNumSym; loop3++) {
if (pSym->ulFuncHits == pHits[loop].ulFuncHits &&
pSym->ulFuncAddress == pHits[loop].ulFuncAddress) {
ulPercent= pHits[loop].ulFuncHits;
ulPercent*=100;
ulPercent/=dwProfileCount;
PROFILEMSG(1,(TEXT("%10d %7d %8.8lx %-12a:%a\r\n"),pHits[loop].ulFuncHits,
ulPercent ,pHits[loop].ulFuncAddress, tocptr->lpszFileName,
GetSymbol((LPBYTE)pProf->ulSymAddress,loop3)));
goto next_sym;
}
pSym++;
}
pProf++;
tocptr++;
}
next_sym:;
}
}
profile_exit:
if (pHits)
VirtualFree(pHits,0,MEM_DECOMMIT|MEM_FREE);
}
return;
}
//---------------------------------------------------------------------------
// GetEPC - Get exception program counter
//
// Output: returns EPC, zero if cpu not supported
//---------------------------------------------------------------------------
DWORD GetEPC(void) {
return( GetThreadIP(pCurThread) );
}
// enable profiler syscall
//#define NKPROF
#include "..\kernel\profiler.c"
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -