Gwinel / gperftools

Automatically exported from code.google.com/p/gperftools
BSD 3-Clause "New" or "Revised" License
0 stars 0 forks source link

add realtime profiling support to cpuprofiler #184

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
Following patch adds a CPUPROFILE_REALTIME env flag to use ITIMER_REAL and 
SIGALRM for 
profiling: 
http://github.com/tmm1/perftools.rb/raw/8f9b826cfc221a396506110f73de17e87f273d3e
/patche
s/perftools-realtime.patch

Original issue reported on code.google.com by themaste...@gmail.com on 4 Nov 2009 at 2:21

GoogleCodeExporter commented 9 years ago
Patch attached.

Original comment by themaste...@gmail.com on 4 Nov 2009 at 2:21

Attachments:

GoogleCodeExporter commented 9 years ago
I've applied the patch (or more exactly, the functionality from the patch), but 
one
of the unittests we use to test the heap-profiler handler breaks with the new
functionality.  I don't know if it's problems with the actual code or the test. 
 In
any case, we'll try to figure it out, and then get this ready for the next 
release.

Original comment by csilv...@gmail.com on 5 Nov 2009 at 7:11

GoogleCodeExporter commented 9 years ago

Original comment by csilv...@gmail.com on 5 Nov 2009 at 7:11

GoogleCodeExporter commented 9 years ago
I'm curious to see your version of the patch.

Original comment by themaste...@gmail.com on 5 Nov 2009 at 7:18

GoogleCodeExporter commented 9 years ago
It's functionally the same:
---
==== //depot/google3/base/profile-handler.cc#2 - /home/csilvers/google3/base/pro
file-handler.cc ====
--- /tmp/g4-500/cache/depot/google3/base/profile-handler.cc#2   2009-11-04 11:57
:28.000000000 -0500
+++ /home/csilvers/google3/base/profile-handler.cc      2009-11-04 12:21:56.2512
44000 -0500
@@ -56,18 +56,18 @@
   // Registers a callback routine to receive profile timer ticks. The returned
   // token is to be used when unregistering this callback and must not be
   // deleted by the caller. Registration of the first callback enables the
-  // SIGPROF handler.
+  // SIGPROF handler (or SIGALRM if using ITIMER_REAL).
   ProfileHandlerToken* RegisterCallback(ProfileHandlerCallback callback,
                                         void* callback_arg);

   // Unregisters a previously registered callback. Expects the token returned
   // by the corresponding RegisterCallback routine. Unregistering the last
-  // callback disables the SIGPROF handler.
+  // callback disables the SIGPROF handler (or SIGALRM if using ITIMER_REAL).
   void UnregisterCallback(ProfileHandlerToken* token)
       NO_THREAD_SAFETY_ANALYSIS;

   // Unregisters all the callbacks, stops the timer if shared, disables the
-  // SIGPROF handler and clears the timer_sharing_ state.
+  // SIGPROF (or SIGALRM) handler and clears the timer_sharing_ state.
   void Reset();

   // Gets the current state of profile handler.
@@ -94,12 +94,15 @@
   // Initializes the ProfileHandler singleton via GoogleOnceInit.
   static void Init();

-  // Counts the number of SIGPROF interrupts received.
+  // The number of SIGPROF (or SIGALRM for ITIMER_REAL) interrupts received.
   int64 interrupts_ GUARDED_BY(signal_lock_);

-  // SIGPROF interrupt frequency, read-only after construction.
+  // SIGPROF/SIGALRM interrupt frequency, read-only after construction.
   int32 frequency_;

+  // ITIMER_PROF (which uses SIGPROF), or ITIMER_REAL (which uses SIGALRM)
+  int timer_type_;
+
   // Counts the number of callbacks registered.
   int32 callback_count_ GUARDED_BY(control_lock_);

@@ -163,7 +166,7 @@
   // Disables (ignores) the timer interrupt signal.
   void DisableHandler() EXCLUSIVE_LOCKS_REQUIRED(control_lock_);

-  // SIGPROF handler. Iterate over and call all the registered callbacks.
+  // SIGPROF/SIGALRM handler. Iterate over and call all the registered callback
s.
   static void SignalHandler(int sig, siginfo_t* sinfo, void* ucontext);

   DISALLOW_EVIL_CONSTRUCTORS(ProfileHandler);
@@ -189,6 +192,9 @@
       callback_count_(0),
       timer_sharing_(TIMERS_UNTOUCHED) {
   SpinLockHolder cl(&control_lock_);
+
+  timer_type_ = (getenv("CPUPROFILE_REALTIME") ? ITIMER_REAL : ITIMER_PROF);
+
   // Get frequency of interrupts (if specified)
   char junk;
   const char* fr = getenv("CPUPROFILE_FREQUENCY");
@@ -341,18 +347,18 @@
   timer.it_interval.tv_sec = 0;
   timer.it_interval.tv_usec = 1000000 / frequency_;
   timer.it_value = timer.it_interval;
-  setitimer(ITIMER_PROF, &timer, 0);
+  setitimer(timer_type_, &timer, 0);
 }

 void ProfileHandler::StopTimer() {
   struct itimerval timer;
   memset(&timer, 0, sizeof timer);
-  setitimer(ITIMER_PROF, &timer, 0);
+  setitimer(timer_type_, &timer, 0);
 }

 bool ProfileHandler::IsTimerRunning() {
   struct itimerval current_timer;
-  RAW_CHECK(0 == getitimer(ITIMER_PROF, ¤t_timer), strerror(errno));
+  RAW_CHECK(0 == getitimer(timer_type_, ¤t_timer), strerror(errno));
   return (current_timer.it_value.tv_sec != 0 ||
           current_timer.it_value.tv_usec != 0);
 }
@@ -362,7 +368,8 @@
   sa.sa_sigaction = SignalHandler;
   sa.sa_flags = SA_RESTART | SA_SIGINFO;
   sigemptyset(&sa.sa_mask);
-  RAW_CHECK(sigaction(SIGPROF, &sa, NULL) == 0, strerror(errno));
+  const int signal_number = (timer_type_ == ITIMER_PROF ? SIGPROF : SIGALRM);
+  RAW_CHECK(sigaction(signal_number, &sa, NULL) == 0, strerror(errno));
 }

 void ProfileHandler::DisableHandler() {
@@ -370,7 +377,8 @@
   sa.sa_handler = SIG_IGN;
   sa.sa_flags = SA_RESTART;
   sigemptyset(&sa.sa_mask);
-  RAW_CHECK(sigaction(SIGPROF, &sa, NULL) == 0, strerror(errno));
+  const int signal_number = (timer_type_ == ITIMER_PROF ? SIGPROF : SIGALRM);
+  RAW_CHECK(sigaction(signal_number, &sa, NULL) == 0, strerror(errno));
 }

 void ProfileHandler::SignalHandler(int sig, siginfo_t* sinfo, void* ucontext) {
---

I also updated the documentation. :-)

Original comment by csilv...@gmail.com on 5 Nov 2009 at 7:41

GoogleCodeExporter commented 9 years ago
Cool, was just curious. Thanks!

Original comment by themaste...@gmail.com on 5 Nov 2009 at 7:50

GoogleCodeExporter commented 9 years ago
This is in perftools 1.5, just released.

Original comment by csilv...@gmail.com on 20 Jan 2010 at 11:09