diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2013-06-18 09:45:37 +0000 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2013-06-18 09:45:37 +0000 |
commit | 943072f45ca34caf7b55db16f412bed94f7c27bc (patch) | |
tree | e796b9b0b1179779b5388554aa81d3198206ecb5 /winsup/cygwin/profil.c | |
parent | c38196884232bb12c0c4e04d1d31f6cbe1aca446 (diff) | |
download | newlib-943072f45ca34caf7b55db16f412bed94f7c27bc.zip newlib-943072f45ca34caf7b55db16f412bed94f7c27bc.tar.gz newlib-943072f45ca34caf7b55db16f412bed94f7c27bc.tar.bz2 |
* Makefile.in (VPATH): Drop CONFIG_DIR.
(EXTRA_DLL_OFILES): Remove.
(DLL_OFILES): Remove EXTRA_DLL_OFILES.
(ASFLAGS): Define as -D_WIN64 on x86_64.
(GMON_OFILES): Add mcountFunc.o.
($(srcdir)/$(TLSOFFSETS_H)): Use target_cpu rather than CONFIG_DIR.
* configure.ac (CONFIG_DIR): Remove definition.
* configure: Regenerate.
* gcrt0.c: Use latest version from Mingw-w64 project.
* gmon.c: Ditto.
* gmon.h: Ditto.
* mcount.c: Ditto.
* mcountFunc.S: Ditto, new file.
* profil.c: Ditto.
* profil.h: Ditto.
* config: Remove entire directory.
Diffstat (limited to 'winsup/cygwin/profil.c')
-rw-r--r-- | winsup/cygwin/profil.c | 82 |
1 files changed, 57 insertions, 25 deletions
diff --git a/winsup/cygwin/profil.c b/winsup/cygwin/profil.c index 4af7d3a..eb41c08 100644 --- a/winsup/cygwin/profil.c +++ b/winsup/cygwin/profil.c @@ -1,6 +1,6 @@ /* profil.c -- win32 profil.c equivalent - Copyright 1998, 1999, 2000, 2001, 2003, 2009, 2010, 2012 Red Hat, Inc. + Copyright 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. This file is part of Cygwin. @@ -8,11 +8,20 @@ Cygwin license. Please consult the file "CYGWIN_LICENSE" for details. */ -#include "winlean.h" +/* + * This file is taken from Cygwin distribution. Please keep it in sync. + * The differences should be within __MINGW32__ guard. + */ + +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#include <windows.h> +#include <stdio.h> #include <sys/types.h> #include <errno.h> - -#include <profil.h> +#include <math.h> +#include "profil.h" #define SLEEPTIME (1000 / PROF_HZ) @@ -21,24 +30,25 @@ static struct profinfo prof; /* Get the pc for thread THR */ -static uintptr_t +static size_t get_thrpc (HANDLE thr) { CONTEXT ctx; - uintptr_t pc; + size_t pc; int res; res = SuspendThread (thr); if (res == -1) - return (uintptr_t) -1; + return (size_t) - 1; ctx.ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER; - pc = (uintptr_t) -1; - if (GetThreadContext (thr, &ctx)) -#ifdef __x86_64__ - pc = ctx.Rip; -#else + pc = (size_t) - 1; + if (GetThreadContext (thr, &ctx)) { +#ifndef _WIN64 pc = ctx.Eip; +#else + pc = ctx.Rip; #endif + } ResumeThread (thr); return pc; } @@ -58,18 +68,17 @@ print_prof (struct profinfo *p) /* Everytime we wake up use the main thread pc to hash into the cell in the profile buffer ARG. */ -static DWORD CALLBACK +static void CALLBACK profthr_func (LPVOID); + +static void CALLBACK profthr_func (LPVOID arg) { struct profinfo *p = (struct profinfo *) arg; - uintptr_t pc; - size_t idx; - - SetThreadPriority(p->profthr, THREAD_PRIORITY_TIME_CRITICAL); + size_t pc, idx; for (;;) { - pc = (uintptr_t) get_thrpc (p->targthr); + pc = (size_t) get_thrpc (p->targthr); if (pc >= p->lowpc && pc < p->highpc) { idx = PROFIDX (pc, p->lowpc, p->scale); @@ -78,9 +87,10 @@ profthr_func (LPVOID arg) #if 0 print_prof (p); #endif - Sleep (SLEEPTIME); + /* Check quit condition, WAIT_OBJECT_0 or WAIT_TIMEOUT */ + if (WaitForSingleObject (p->quitevt, SLEEPTIME) == WAIT_OBJECT_0) + return; } - return 0; } /* Stop profiling to the profiling buffer pointed to by P. */ @@ -90,7 +100,8 @@ profile_off (struct profinfo *p) { if (p->profthr) { - TerminateThread (p->profthr, 0); + SignalObjectAndWait (p->quitevt, p->profthr, INFINITE, FALSE); + CloseHandle (p->quitevt); CloseHandle (p->profthr); } if (p->targthr) @@ -114,14 +125,34 @@ profile_on (struct profinfo *p) return -1; } - p->profthr = CreateThread (0, 0, profthr_func, (void *) p, 0, &thrid); + p->quitevt = CreateEvent (NULL, TRUE, FALSE, NULL); + + if (!p->quitevt) + { + CloseHandle (p->quitevt); + p->targthr = 0; + errno = EAGAIN; + return -1; + } + + p->profthr = CreateThread (0, 0, (DWORD (WINAPI *)(LPVOID)) profthr_func, + (void *) p, 0, &thrid); + if (!p->profthr) { CloseHandle (p->targthr); + CloseHandle (p->quitevt); p->targthr = 0; errno = EAGAIN; return -1; } + + /* Set profiler thread priority to highest to be sure that it gets the + processor as soon it request it (i.e. when the Sleep terminate) to get + the next data out of the profile. */ + + SetThreadPriority (p->profthr, THREAD_PRIORITY_TIME_CRITICAL); + return 0; } @@ -139,7 +170,7 @@ profile_on (struct profinfo *p) */ int profile_ctl (struct profinfo * p, char *samples, size_t size, - size_t offset, unsigned int scale) + size_t offset, u_int scale) { size_t maxbin; @@ -155,7 +186,7 @@ profile_ctl (struct profinfo * p, char *samples, size_t size, memset (samples, 0, size); memset (p, 0, sizeof *p); maxbin = size >> 1; - prof.counter = (uint16_t *) samples; + prof.counter = (u_short *) samples; prof.lowpc = offset; prof.highpc = PROFADDR (maxbin, offset, scale); prof.scale = scale; @@ -171,7 +202,8 @@ profile_ctl (struct profinfo * p, char *samples, size_t size, The word pointed to by this address is incremented. Buf is unused. */ int -profil (char *samples, size_t size, size_t offset, unsigned int scale) +profil (char *samples, size_t size, size_t offset, u_int scale) { return profile_ctl (&prof, samples, size, offset, scale); } + |