1 /* profil.c -- win32 profil.c equivalent
3 Copyright 1998, 1999, 2000, 2001, 2003, 2009 Red Hat, Inc.
5 This file is part of Cygwin.
7 This software is a copyrighted work licensed under the terms of the
8 Cygwin license. Please consult the file "CYGWIN_LICENSE" for
12 #include <sys/types.h>
17 #define SLEEPTIME (1000 / PROF_HZ)
19 /* global profinfo for profil() call */
20 static struct profinfo prof;
22 /* Get the pc for thread THR */
25 get_thrpc (HANDLE thr)
31 res = SuspendThread (thr);
34 ctx.ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER;
36 if (GetThreadContext (thr, &ctx))
42 /* Display cell of profile buffer */
45 print_prof (struct profinfo *p)
47 printf ("profthr %x\ttarget thr %x\n", p->profthr, p->targthr);
48 printf ("pc: %x - %x\n", p->lowpc, p->highpc);
49 printf ("scale: %x\n", p->scale);
54 /* Everytime we wake up use the main thread pc to hash into the cell in the
55 profile buffer ARG. */
58 profthr_func (LPVOID arg)
60 struct profinfo *p = (struct profinfo *) arg;
63 SetThreadPriority(p->profthr, THREAD_PRIORITY_TIME_CRITICAL);
67 pc = (u_long) get_thrpc (p->targthr);
68 if (pc >= p->lowpc && pc < p->highpc)
70 idx = PROFIDX (pc, p->lowpc, p->scale);
81 /* Stop profiling to the profiling buffer pointed to by P. */
84 profile_off (struct profinfo *p)
88 TerminateThread (p->profthr, 0);
89 CloseHandle (p->profthr);
92 CloseHandle (p->targthr);
96 /* Create a timer thread and pass it a pointer P to the profiling buffer. */
99 profile_on (struct profinfo *p)
103 /* get handle for this thread */
104 if (!DuplicateHandle (GetCurrentProcess (), GetCurrentThread (),
105 GetCurrentProcess (), &p->targthr, 0, FALSE,
106 DUPLICATE_SAME_ACCESS))
112 p->profthr = CreateThread (0, 0, profthr_func, (void *) p, 0, &thrid);
115 CloseHandle (p->targthr);
124 * start or stop profiling
126 * profiling goes into the SAMPLES buffer of size SIZE (which is treated
127 * as an array of u_shorts of size size/2)
129 * each bin represents a range of pc addresses from OFFSET. The number
130 * of pc addresses in a bin depends on SCALE. (A scale of 65536 maps
131 * each bin to two addresses, A scale of 32768 maps each bin to 4 addresses,
132 * a scale of 1 maps each bin to 128k addreses). Scale may be 1 - 65536,
133 * or zero to turn off profiling
136 profile_ctl (struct profinfo * p, char *samples, size_t size,
137 u_long offset, u_int scale)
150 memset (samples, 0, size);
151 memset (p, 0, sizeof *p);
153 prof.counter = (u_short *) samples;
155 prof.highpc = PROFADDR (maxbin, offset, scale);
158 return profile_on (p);
163 /* Equivalent to unix profil()
164 Every SLEEPTIME interval, the user's program counter (PC) is examined:
165 offset is subtracted and the result is multiplied by scale.
166 The word pointed to by this address is incremented. Buf is unused. */
169 profil (char *samples, size_t size, u_long offset, u_int scale)
171 return profile_ctl (&prof, samples, size, offset, scale);