📄 abramson.txt
字号:
Tracing Application Execution
by Tomer Abramson
Listing 1:
#include "TraceBuffer.h"
CTraceBuffer::CTraceBuffer() :
m_nInsertPos(-1),
m_nRetrievePos(-1)
{
memset(m_buffer, 0, sizeof(m_buffer));
m_hNumFreeEntriesSemaphore =
CreateSemaphore(NULL, TRACE_BUFFER_SIZE, TRACE_BUFFER_SIZE, NULL);
m_hNumItemsToCollectSemaphore =
CreateSemaphore(NULL, 0, TRACE_BUFFER_SIZE, NULL);
}
CTraceBuffer::~CTraceBuffer()
{
CloseHandle(m_hNumFreeEntriesSemaphore);
CloseHandle(m_hNumItemsToCollectSemaphore);
}
void CTraceBuffer::Insert(TraceLevel_En nTraceLevel, LPCTSTR lpszTrace)
{
long nPrevCount = 0;
long nInsertPos = 0;
DWORD dwTimeout = (nTraceLevel == eTraceLevelAbort ? INFINITE : 0);
// wait until there is a free position in the buffer
if (WAIT_OBJECT_0 !=
WaitForSingleObject(m_hNumFreeEntriesSemaphore, dwTimeout))
return;
nInsertPos = InterlockedIncrement(&m_nInsertPos);
TraceInfo& buffEntry = m_buffer[nInsertPos%TRACE_BUFFER_SIZE];
// insert the trace into the buff
strcpy(buffEntry.szTrace, lpszTrace);
buffEntry.nLevel = nTraceLevel;
buffEntry.dwThreadId = GetCurrentThreadId();
// after inserting new item incerement num of items to collect from buffer
ReleaseSemaphore(m_hNumItemsToCollectSemaphore, 1, &nPrevCount);
}
long CTraceBuffer::Retrieve(TraceInfo& traceInfo)
{
long nPrevNumFreeEntries = 0;
long nRetrievePos = 0;
// wait until there is at least one item to collect from buffer
if (WAIT_OBJECT_0 !=
WaitForSingleObject(m_hNumItemsToCollectSemaphore, 10000))
return 0;
nRetrievePos = InterlockedIncrement(&m_nRetrievePos);
// copy the trace info from the buffer
// don't use traceInfo =
m_buffer[nRetrievePos%TRACE_BUFFER_SIZE] - its slower!
strcpy(traceInfo.szTrace,
m_buffer[nRetrievePos%TRACE_BUFFER_SIZE].szTrace);
traceInfo.nLevel = m_buffer[nRetrievePos%TRACE_BUFFER_SIZE].nLevel;
traceInfo.dwThreadId = m_buffer[nRetrievePos%TRACE_BUFFER_SIZE].dwThreadId;
// after retrieving an item incerement num of free entries in buffer
ReleaseSemaphore(m_hNumFreeEntriesSemaphore, 1, &nPrevNumFreeEntries);
// return number traces left in buffer
return (TRACE_BUFFER_SIZE - (nPrevNumFreeEntries+1));
}
Listing 2:
#include "lightTraceAPI.h"
#include "cnvntionalTraceAPI.h"
#include "tracerThreadObj.h"
#include <iostream.h>
#define NUM_THREADS 64
HANDLE g_hRunThreadEvent = NULL;
// event for synchronizing threads
FILE* g_pCnvntionalTraceFile = NULL;
// log file for conventional trace
CRITICAL_SECTION g_cnvntlTraceFileCritSec;
// synchronize access to log file
// thread that produces traces
DWORD WINAPI ThreadProc(LPVOID pParam)
{
BOOL bLightTrace = (BOOL)pParam;
WaitForSingleObject(g_hRunThreadEvent, INFINITE);
for (int i = 0; i < 250; i++)
{
if (bLightTrace)
LightTrace(eTraceLevelInfo, "trace number %d", i);
else
CnvntionalTrace(eTraceLevelInfo, "trace number %d", i);
}
return 0;
};
// tester function
void TestTrace(BOOL bLightTrace)
{
DWORD dwThreadId = 0;
DWORD dwStart = 0;
DWORD dwEnd = 0;
HANDLE hThread[NUM_THREADS];
ResetEvent(g_hRunThreadEvent);
for (int i = 0; i < NUM_THREADS; i++)
{
hThread[i] = CreateThread(NULL, 0,
ThreadProc, (LPVOID)bLightTrace, 0, &dwThreadId);
SetThreadPriority(hThread[i], THREAD_PRIORITY_HIGHEST);
}
Sleep(1000);
dwStart = GetTickCount();
SetEvent(g_hRunThreadEvent);
WaitForMultipleObjects(NUM_THREADS,hThread,TRUE,INFINITE);
dwEnd = GetTickCount();
if (bLightTrace)
cout << "Light trace results =
" << dwEnd - dwStart << " tick counts" << endl;
else
cout << "Conventional trace results =
" << dwEnd - dwStart << " tick counts" << endl;
}
void main()
{
TracerThread tracerThread;
// init global params
g_hRunThreadEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
InitializeCriticalSection(&g_cnvntlTraceFileCritSec);
g_pCnvntionalTraceFile = fopen("cnventionalTrace.txt", "w");
// run tracer thread (for light trace)
tracerThread.Run();
Sleep(2000);
// test
TestTrace(FALSE); // conventional trace
TestTrace(TRUE); // light trace
// cleanup before exit
DeleteCriticalSection(&g_cnvntlTraceFileCritSec);
fclose(g_pCnvntionalTraceFile);
}
1
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -