Attempted to improve the profiler a bit, making it more like a real profiler. It doesn't quite work yet.

This commit is contained in:
Pietro Gagliardi 2015-05-10 23:02:16 -04:00
parent c0c6b4fed6
commit a342998263
3 changed files with 42 additions and 25 deletions

View File

@ -47,6 +47,5 @@ endif
ifeq ($(PROFILE),1)
osCFILES += windows/profiler.c
osCFLAGS += -finstrument-functions
osLDFLAGS += -finstrument-functions
osCFLAGS += -DLIBUIPROFILING
endif

View File

@ -80,6 +80,16 @@ const char *uiInit(uiInitOptions *o)
HCURSOR hDefaultCursor;
NONCLIENTMETRICSW ncm;
#ifdef LIBUIPROFILING
extern void initprofiler(HANDLE);
HANDLE real;
if (DuplicateHandle(GetCurrentProcess(), GetCurrentThread(),
GetCurrentProcess(), &real,
0, FALSE, DUPLICATE_SAME_ACCESS) == 0)
return loadLastError("getting the current thread's handle for initializing the profiler");
initprofiler(real);
#endif
options = *o;
if (initAlloc() == 0)

View File

@ -3,33 +3,41 @@
static FILE *fprof = NULL;
__attribute__((no_instrument_function)) static void init(void)
static DWORD WINAPI profilerThread(LPVOID th)
{
HANDLE thread = (HANDLE) th;
LARGE_INTEGER counter;
CONTEXT ctxt;
// TODO check for errors
if (SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL) == 0)
complain("error setting thread priority in profilerThread()");
for (;;) {
if (SuspendThread(thread) == (DWORD) (-1))
complain("error suspending thread in profilerThread()");
QueryPerformanceCounter(&counter);
ZeroMemory(&ctxt, sizeof (CONTEXT));
ctxt.ContextFlags = CONTEXT_CONTROL;
if (GetThreadContext(thread, &ctxt) == 0)
complain("error getting thread context in profilerThread()");
fprintf(fprof, "%I64X %I64d\n",
(DWORD64) (ctxt.Eip),
counter.QuadPart);
fflush(fprof);
if (ResumeThread(thread) == (DWORD) (-1))
complain("error resuming thread in profilerThread()");
Sleep(100);
}
return 0;
}
void initprofiler(HANDLE thread)
{
if (fprof != NULL)
return;
fprof = fopen("profiler.out", "w");
if (fprof == NULL) {
fprintf(stderr, "error opening profiler output file\n");
abort();
}
}
__attribute__((no_instrument_function)) void __cyg_profile_func_enter(void *this_fn, void *call_site)
{
LARGE_INTEGER counter;
init();
QueryPerformanceCounter(&counter);
fprintf(fprof, "enter %p %I64d\n", this_fn, counter.QuadPart);
fflush(fprof);
}
__attribute__((no_instrument_function)) void __cyg_profile_func_exit(void *this_fn, void *call_site)
{
LARGE_INTEGER counter;
init();
QueryPerformanceCounter(&counter);
fprintf(fprof, "leave %p %I64d\n", this_fn, counter.QuadPart);
fflush(fprof);
if (CreateThread(NULL, 0, profilerThread, thread, 0, NULL) == NULL)
complain("error creating profiler thread");
}