Closed GoogleCodeExporter closed 9 years ago
Patch attached.
Original comment by themaste...@gmail.com
on 4 Nov 2009 at 2:21
Attachments:
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
Original comment by csilv...@gmail.com
on 5 Nov 2009 at 7:11
I'm curious to see your version of the patch.
Original comment by themaste...@gmail.com
on 5 Nov 2009 at 7:18
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
Cool, was just curious. Thanks!
Original comment by themaste...@gmail.com
on 5 Nov 2009 at 7:50
This is in perftools 1.5, just released.
Original comment by csilv...@gmail.com
on 20 Jan 2010 at 11:09
Original issue reported on code.google.com by
themaste...@gmail.com
on 4 Nov 2009 at 2:21