diff --git a/windows/GNUmakeinc.mk b/windows/GNUmakeinc.mk index c3723f7c..fe40521c 100644 --- a/windows/GNUmakeinc.mk +++ b/windows/GNUmakeinc.mk @@ -47,5 +47,6 @@ endif ifeq ($(PROFILE),1) osCFILES += windows/profiler.c - osCFLAGS += -DLIBUIPROFILING + osCFLAGS += -finstrument-functions + osLDFLAGS += -finstrument-functions endif diff --git a/windows/init.c b/windows/init.c index e2ca3232..38d10994 100644 --- a/windows/init.c +++ b/windows/init.c @@ -80,16 +80,6 @@ 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) diff --git a/windows/profiler.c b/windows/profiler.c index 7a0e01fc..9573de20 100644 --- a/windows/profiler.c +++ b/windows/profiler.c @@ -3,41 +3,33 @@ static FILE *fprof = NULL; -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) +__attribute__((no_instrument_function)) static void init(void) { + if (fprof != NULL) + return; fprof = fopen("profiler.out", "w"); if (fprof == NULL) { fprintf(stderr, "error opening profiler output file\n"); abort(); } - if (CreateThread(NULL, 0, profilerThread, thread, 0, NULL) == NULL) - complain("error creating profiler thread"); +} + +__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); }