This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: PATCH: PR libc/2268: Wrong frequency setting for ITIMER_PROF


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)


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]