aboutsummaryrefslogtreecommitdiff
path: root/winsup/cygwin/profil.c
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2013-06-18 09:45:37 +0000
committerCorinna Vinschen <corinna@vinschen.de>2013-06-18 09:45:37 +0000
commit943072f45ca34caf7b55db16f412bed94f7c27bc (patch)
treee796b9b0b1179779b5388554aa81d3198206ecb5 /winsup/cygwin/profil.c
parentc38196884232bb12c0c4e04d1d31f6cbe1aca446 (diff)
downloadnewlib-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.c82
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);
}
+