⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 profiler.c

📁 wince下的源代码集合打包
💻 C
📖 第 1 页 / 共 2 页
字号:
/*++Copyright (c) 1995-2000 Microsoft Corporation.  All rights reserved.Module Name:  Abstract:   This file implements the NK kernel profiler support.Functions:Notes: --*/#define C_ONLY#include "kernel.h"#include "romldr.h"#include "xtime.h"#include <profiler.h>#define PROFILEMSG(cond,printf_exp)   \   ((cond)?(NKDbgPrintfW printf_exp),1:0)#ifdef KCALL_PROFILE#include "kcall.h"KPRF_t KPRFInfo[MAX_KCALL_PROFILE];#ifdef NKPROF#define KCALL_NextThread	10	// Next thread's entry in array#endif#endifint (*PProfileInterrupt)(void)=NULL;	// pointer to profiler ISR, 										// set in platform profiler codeBOOL bProfileTimerRunning=FALSE;		// this variable is used in OEMIdle(), so must be defined even in a non-profiling kernel#ifdef NKPROFBOOL bProfileObjCall=FALSE;				// object call profiling flag//volatile BOOL bProfileKCall=FALSE;		// kcall profiling flagBOOL bProfileKCall=FALSE;		// kcall profiling flagBOOL bProfileBuffer=FALSE;				// profile to buffer flagextern void SC_DumpKCallProfile(DWORD bReset);extern BOOL ProfilerAllocBuffer(void);extern BOOL ProfilerFreeBuffer(void);#endif#ifdef WINCECODETESTextern void CT_Profile(DWORD Start);#endif// SC_ProfileSyscall - profiler syscall supportvoid SC_ProfileSyscall(LPXT lpXt){#ifdef NKPROF	static int scPauseContinueCalls = 0;	static BOOL bStart = FALSE;	if (lpXt->dwOp == XTIME_PROFILE_DATA)	{		if(!lpXt->dwTime[0])			// if starting profiling		{			if(lpXt->dwTime[2] & PROFILE_CONTINUE)			{				if(bStart)				{					++scPauseContinueCalls;					// start profiler timer on 0 to 1 transition					if(1 == scPauseContinueCalls)					{						OEMProfileTimerEnable(lpXt->dwTime[1]);						bProfileTimerRunning = TRUE;					}				}			}			else if(lpXt->dwTime[2] & PROFILE_PAUSE)			{				if(bStart)				{					--scPauseContinueCalls;					// start profiler timer on 1 to 0 transition					if(!scPauseContinueCalls)					{						OEMProfileTimerDisable();						bProfileTimerRunning = FALSE;					}				}			}			else 			{				OEMProfileTimerDisable();		// disable profiler timer				bProfileTimerRunning = FALSE;				bStart = TRUE;				++scPauseContinueCalls;								dwProfileCount=0;			// clear profile count				ClearProfileHits();			// reset all profile counts												// check object call profile flag				if (lpXt->dwTime[2] & PROFILE_OBJCALL)					bProfileObjCall=TRUE;				else					bProfileObjCall=FALSE;				// check kcall profile flag				if (lpXt->dwTime[2] & PROFILE_KCALL)				{					bProfileKCall=TRUE;					return;				}				else				{					bProfileKCall=FALSE;				}				// check profile to buffer flag				if (lpXt->dwTime[2] & PROFILE_BUFFER)				{					bProfileBuffer=TRUE;					if (!ProfilerAllocBuffer())					{						bProfileBuffer=FALSE;					}				}				else				{					bProfileBuffer=FALSE;				}												if (bProfileObjCall)				{					// We don't need special timers for this case.					return;				}											// start profiler timer				if(!(lpXt->dwTime[2] & PROFILE_STARTPAUSED))				{					// start profiler timer					OEMProfileTimerEnable(lpXt->dwTime[1]);					bProfileTimerRunning = TRUE;				}			}			}			else		{			if(bProfileTimerRunning)			{				OEMProfileTimerDisable();		// disable profiler timer				bProfileTimerRunning = FALSE;			}						// stopping profile			bStart = FALSE;			if (bProfileKCall)			// if profile KCALL enabled			{                bProfileKCall=FALSE;				// dump the KCall profile data				SC_DumpKCallProfile(TRUE);			}			else						// else display profile hit report			{				ProfilerReport();			}			if(bProfileBuffer)			{				ProfilerFreeBuffer();				bProfileBuffer = FALSE;			}			bProfileObjCall = FALSE;			scPauseContinueCalls = 0;		}	}#endif#ifdef WINCECODETEST	if (lpXt->dwOp == XTIME_CODETEST)	{		// Start/Stop CodeTEST profiling		CT_Profile(lpXt->dwTime[0]);	}#endif}void SC_TurnOnProfiling(void) {	DEBUGMSG(ZONE_ENTRY,(L"SC_TurnOnProfiling entry\r\n"));	SET_PROFILE(pCurThread);#if SHx	ProfileFlag = 1;	// profile status#endif	DEBUGMSG(ZONE_ENTRY,(L"SC_TurnOnProfiling exit\r\n"));}void SC_TurnOffProfiling(void) {	DEBUGMSG(ZONE_ENTRY,(L"SC_TurnOffProfiling entry\r\n"));	CLEAR_PROFILE(pCurThread);#if SHx	ProfileFlag = 0;	// profile status#endif	DEBUGMSG(ZONE_ENTRY,(L"SC_TurnOffProfiling exit\r\n"));}#ifdef KCALL_PROFILEvoid GetKCallProfile(KPRF_t *pkprf, int loop, BOOL bReset) {	KCALLPROFON(26);	memcpy(pkprf,&KPRFInfo[loop],sizeof(KPRF_t));	if (bReset && (loop != 26))		memset(&KPRFInfo[loop],0,sizeof(KPRF_t));	KCALLPROFOFF(26);	if (bReset && (loop == 26))		memset(&KPRFInfo[loop],0,sizeof(KPRF_t));}#endif//// Convert the number of ticks to microseconds.//static DWORD local_ScaleDown(DWORD dwIn){    LARGE_INTEGER liFreq;    SC_QueryPerformanceFrequency(&liFreq);	return ((DWORD) (((__int64) dwIn * 1000000) / liFreq.LowPart));}void SC_DumpKCallProfile(DWORD bReset) {#ifdef KCALL_PROFILE	extern DWORD local_ScaleDown(DWORD);	int loop;	KPRF_t kprf;	DWORD min = 0xffffffff, max = 0, total = 0, calls = 0;#ifdef NKPROF	calls = local_ScaleDown(1000);    PROFILEMSG(1,(L"Resolution: %d.%3.3d usec per tick\r\n",calls/1000,calls%1000));	KCall((PKFN)GetKCallProfile,&kprf,KCALL_NextThread,bReset);	PROFILEMSG(1,(L"NextThread: Calls=%u Min=%u Max=%u Ave=%u\r\n",		kprf.hits,local_ScaleDown(kprf.min),		local_ScaleDown(kprf.max),kprf.hits ? local_ScaleDown(kprf.total)/kprf.hits : 0));	for (loop = 0; loop < MAX_KCALL_PROFILE; loop++) {		if (loop != KCALL_NextThread) {			KCall((PKFN)GetKCallProfile,&kprf,loop,bReset);			if (kprf.max > max)				max = kprf.max;			total+=kprf.total;			calls+= kprf.hits;		}	}	PROFILEMSG(1,(L"Other Kernel calls: Max=%u Avg=%u\r\n",max,calls ? local_ScaleDown(total)/calls : 0));#else	calls = local_ScaleDown(1000);	PROFILEMSG(1,(L"Resolution: %d.%3.3d usec per tick\r\n",calls/1000,calls%1000));	PROFILEMSG(1,(L"Index Entrypoint                        Calls      uSecs    Min    Max    Ave\r\n"));	for (loop = 0; loop < MAX_KCALL_PROFILE; loop++) {		KCall((PKFN)GetKCallProfile,&kprf,loop,bReset);		PROFILEMSG(1,(L"%5d %-30s %8d %10d %6d %6d %6d\r\n",			loop, pKCallName[loop], kprf.hits,local_ScaleDown(kprf.total),local_ScaleDown(kprf.min),			local_ScaleDown(kprf.max),kprf.hits ? local_ScaleDown(kprf.total)/kprf.hits : 0));		if (kprf.min && (kprf.min < min))			min = kprf.min;		if (kprf.max > max)			max = kprf.max;		calls += kprf.hits;		total += kprf.total;	}	PROFILEMSG(1,(L"\r\n"));	PROFILEMSG(1,(L"      %-30s %8d %10d %6d %6d %6d\r\n",		L"Summary", calls,local_ScaleDown(total),local_ScaleDown(min),local_ScaleDown(max),calls ? local_ScaleDown(total)/calls : 0));#endif#endif}#ifdef CELOG//------------------------------------------------------------------------------//------------------------------------------------------------------------------// CELOG RESYNC API:  This function generates a series of calls to CeLogData, // to log all currently-existing processes and threads.//// This buffer is used during resync to minimize stack usageBYTE g_pCeLogSyncBuffer[(MAX_PATH * sizeof(WCHAR))                        + max(sizeof(CEL_PROCESS_CREATE), sizeof(CEL_THREAD_CREATE))];// Helper func to generate a celog process create event, minimizing stack usage.// At most one of lpProcNameA, lpProcNameW can be non-null!_inline void CELOG_SyncProcess(HANDLE hProcess, LPSTR lpProcNameA, LPWSTR lpProcNameW){    PCEL_PROCESS_CREATE pcl = (PCEL_PROCESS_CREATE) &g_pCeLogSyncBuffer;    WORD wLen = 0;    pcl->hProcess = hProcess;    if (lpProcNameW) {        wLen = strlenW(lpProcNameW) + 1;        kstrcpyW(pcl->szName, lpProcNameW);     } else if (lpProcNameA) {        wLen = strlen(lpProcNameA) + 1;        KAsciiToUnicode(pcl->szName, lpProcNameA, MAX_PATH);    }    CELOGDATA(TRUE, CELID_PROCESS_CREATE, (PVOID) pcl, (WORD) (sizeof(CEL_PROCESS_CREATE) + (wLen * sizeof(WCHAR))), 0, CELZONE_PROCESS);}// Helper func to generate a celog thread create event, minimizing stack usage._inline void CELOG_SyncThread(PTHREAD pThread, HANDLE hProcess){    if (pThread) {        PCEL_THREAD_CREATE pcl = (PCEL_THREAD_CREATE) &g_pCeLogSyncBuffer;        WORD wLen = 0;        pcl->hProcess = hProcess;        pcl->hThread  = pThread->hTh;                // Look up the thread's function name and module handle.        GetThreadName(pThread, &(pcl->hModule), pcl->szName);        if (pcl->szName[0] != 0) {            wLen = strlenW(pcl->szName) + 1;        }                CELOGDATA(TRUE, CELID_THREAD_CREATE, (PVOID) pcl,                   (WORD)(sizeof(CEL_THREAD_CREATE) + (wLen * sizeof(WCHAR))),                  0, CELZONE_THREAD);    }}BOOL CeLogReSync(){    DWORD   dwProc;        // KCall so nobody changes ProcArray out from under us    if (!InSysCall()) {        return KCall((PKFN)CeLogReSync);    }        KCALLPROFON(74);    // Since we're in a KCall, we must limit stack usage, so we can't call     // CELOG_ProcessCreate or CELOG_ThreadCreate -- instead use CELOG_Sync*.        for (dwProc = 0; dwProc < 32; dwProc++) {        if (ProcArray[dwProc].dwVMBase) {            THREAD* pThread;                        // Log the process name.  Since we are in a KCall, we must use the             // table of contents for everything besides nk.exe, because we            // cannot reach into the memory owned by other processes.            if (dwProc == 0) {                // NK.EXE                                CELOG_SyncProcess(ProcArray[dwProc].hProc, NULL,                                  ProcArray[dwProc].lpszProcName);            } else if ((ProcArray[dwProc].oe.filetype == FT_ROMIMAGE)                       && (ProcArray[dwProc].oe.tocptr)) {                // Get the name from the TOC                                CELOG_SyncProcess(ProcArray[dwProc].hProc,                                  ProcArray[dwProc].oe.tocptr->lpszFileName, NULL);                        } else {                // We can't do anything if the process isn't nk.exe and isn't                // in the table of contents.                                CELOG_SyncProcess(ProcArray[dwProc].hProc, NULL, NULL);            }            // Log the existence of each of the process' threads as a ThreadCreate            pThread = ProcArray[dwProc].pTh;            while (pThread != NULL) {                CELOG_SyncThread(pThread, pThread->pOwnerProc->hProc);                pThread = pThread->pNextInProc;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -