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

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

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

H.J. Lu-27
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.


H.J.
----
2006-02-03  H.J. Lu  <[hidden email]>

        PR libc/2268
        * sysdeps/posix/profil.c (__profil): Check __profile_frequency.

--- sysdeps/posix/profil.c.freq 2006-02-03 14:40:29.000000000 -0800
+++ sysdeps/posix/profil.c 2006-02-03 14:45:09.000000000 -0800
@@ -112,8 +112,13 @@ __profil (u_short *sample_buffer, size_t
     return -1;
 
   timer.it_value.tv_sec = 0;
-  timer.it_value.tv_usec = 1000000 / __profile_frequency ();
-  timer.it_interval = timer.it_value;
+  timer.it_value.tv_usec = 1;
+  timer.it_interval.tv_sec = 0;
+  int profile_frequency = __profile_frequency ();
+  if (profile_frequency > 1000000)
+    timer.it_interval.tv_usec = 1;
+  else
+    timer.it_interval.tv_usec = 1000000 / profile_frequency;
   return __setitimer (ITIMER_PROF, &timer, otimer_ptr);
 }
 weak_alias (__profil, profil)
Reply | Threaded
Open this post in threaded view
|

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

H.J. Lu-27
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  <[hidden email]>

        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)