This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: PATCH: PR libc/2268: Wrong frequency setting for ITIMER_PROF
- From: "H. J. Lu" <hjl at lucon dot org>
- To: GNU C Library <libc-alpha at sources dot redhat dot com>
- Cc: roland at redhat dot com
- Date: Fri, 3 Feb 2006 16:10:22 -0800
- Subject: Re: PATCH: PR libc/2268: Wrong frequency setting for ITIMER_PROF
- References: <20060203225420.GA30984@lucon.org>
On Fri, Feb 03, 2006 at 02:54:20PM -0800, H. J. Lu wrote:
> Hi Roland,
>
> There are some minor issues with your change. We want SIGPROF
> delivered as soon as possible. So we should keep
>
> timer.it_value.tv_usec = 1;
>
> Also we may want to guard against __profile_frequency.
>
>
Hi Roland,
There is another issue. If 1000000 can't be divided by
__profile_frequency () evenly, frequency in gmon data will be
incorrect. I am enclosing my original patch for reference.
H.J.
---
2006-02-03 H.J. Lu <hongjiu.lu@intel.com>
PR libc/2268
* gmon/gmon.c (write_hist): Use __libc_profile_frequency
instead of __profile_frequency ().
* include/libc-internal.h (__libc_profile_frequency): New.
* sysdeps/posix/profil.c: Include <libc-internal.h>.
(__libc_profile_frequency): Defined.
(__profil): Set __libc_profile_frequency and ITIMER_PROF
frequency with __profile_frequency ().
--- libc/gmon/gmon.c.freq 2005-08-03 11:37:05.000000000 -0700
+++ libc/gmon/gmon.c 2006-02-03 12:44:25.000000000 -0800
@@ -195,7 +195,7 @@ write_hist (fd)
*(char **) thdr.high_pc = (char *) _gmonparam.highpc;
*(int32_t *) thdr.hist_size = (_gmonparam.kcountsize
/ sizeof (HISTCOUNTER));
- *(int32_t *) thdr.prof_rate = __profile_frequency ();
+ *(int32_t *) thdr.prof_rate = __libc_profile_frequency;
strncpy (thdr.dimen, "seconds", sizeof (thdr.dimen));
thdr.dimen_abbrev = 's';
--- libc/include/libc-internal.h.freq 2003-02-22 14:46:31.000000000 -0800
+++ libc/include/libc-internal.h 2006-02-03 12:51:56.000000000 -0800
@@ -17,6 +17,9 @@ extern void __libc_global_ctors (void);
extern int __profile_frequency (void);
libc_hidden_proto (__profile_frequency)
+/* The actual profiling frequency used by__profil. */
+extern int __libc_profile_frequency attribute_hidden;
+
/* Hooks for the instrumenting functions. */
extern void __cyg_profile_func_enter (void *this_fn, void *call_site);
extern void __cyg_profile_func_exit (void *this_fn, void *call_site);
--- libc/sysdeps/posix/profil.c.freq 2005-12-16 12:36:07.000000000 -0800
+++ libc/sysdeps/posix/profil.c 2006-02-03 12:51:38.000000000 -0800
@@ -28,6 +28,9 @@
#include <gmon/profil.c>
#else
+#include <libc-internal.h>
+
+int __libc_profile_frequency attribute_hidden;
static u_short *samples;
static size_t nsamples;
@@ -111,7 +114,26 @@ __profil (u_short *sample_buffer, size_t
timer.it_value.tv_sec = 0;
timer.it_value.tv_usec = 1;
- timer.it_interval = timer.it_value;
+
+ timer.it_interval.tv_sec = 0;
+ if (__libc_profile_frequency != 0)
+ timer.it_interval.tv_usec = __libc_profile_frequency;
+ else
+ {
+ /* We try to fire ITIMER_PROF at __profile_frequency (). */
+ int profile_frequency = __profile_frequency ();
+ if (profile_frequency > 1000000)
+ {
+ timer.it_interval.tv_usec = 1;
+ profile_frequency = 1000000;
+ }
+ else
+ {
+ timer.it_interval.tv_usec = 1000000 / profile_frequency;
+ profile_frequency = 1000000 / timer.it_interval.tv_usec;
+ }
+ __libc_profile_frequency = profile_frequency;
+ }
return __setitimer (ITIMER_PROF, &timer, otimer_ptr);
}
weak_alias (__profil, profil)