diff options
| author | Paul Eggert | 2012-09-29 23:19:33 -0700 |
|---|---|---|
| committer | Paul Eggert | 2012-09-29 23:19:33 -0700 |
| commit | d89460ed93e67852a95a597a7a1a7983e8828fb9 (patch) | |
| tree | 349021cb4c7dd7546ae3e354bee1ab2d0b4b48a5 /src | |
| parent | 65788e2e93a48015493514b7e8b712700d31a7a2 (diff) | |
| download | emacs-d89460ed93e67852a95a597a7a1a7983e8828fb9.tar.gz emacs-d89460ed93e67852a95a597a7a1a7983e8828fb9.zip | |
Profiler improvements: more-accurate timers, overflow checks.
* profiler.c: Don't include stdio.h, limits.h, sys/time.h,
signal.h, setjmp.h. Include systime.h instead.
(saturated_add): New function.
(record_backtrace, current_sample_interval): Use EMACS_INT, not size_t.
(record_backtrace, handle_profiler_signal): Saturate on fixnum overflow.
(profiler_timer, profiler_timer_ok) [HAVE_TIMER_SETTIME]:
New static vars.
(enum profiler_cpu_running): New enumn.
(profiler_cpu_running): Now of that enum type, not bool.
All uses changed to store the new value.
(handle_profiler_signal): Rename from sigprof_handler_1,
for consistency with other handlers. Do not check whether
cpu_log is a hash-table if garbage collecting, since it
doesn't matter in that case.
(deliver_profiler_signal): Rename from sigprof_handler,
for consistency with other handlers.
(setup_cpu_timer): New function, with much of what used to be in
Fprofiler_cpu_start. Check for out-of-range argument.
Prefer timer_settime if available, and prefer
thread cputime clocks, then process cputime clocks, then
monotonic clocks, to the old realtime clock. Use make_timeval
to round more-correctly when falling back to setitimer.
(Fprofiler_cpu_start): Use it.
(Fprofiler_cpu_stop): Prefer timer_settime if available.
Don't assume that passing NULL as the 2nd argument of setitimer
is the same as passing a pointer to all-zero storage.
Ignore SIGPROF afterwards.
(malloc_probe): Saturate at MOST_POSITIVE_FIXNUM.
* sysdep.c (emacs_sigaction_init): Also mask out SIGPROF in
non-fatal signal handlers. Ignore SIGPROF on startup.
* syssignal.h (PROFILER_CPU_SUPPORT): Define this macro here, not
in profiler.c, since sysdep.c now uses it.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 34 | ||||
| -rw-r--r-- | src/profiler.c | 189 | ||||
| -rw-r--r-- | src/sysdep.c | 5 | ||||
| -rw-r--r-- | src/syssignal.h | 4 |
4 files changed, 178 insertions, 54 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index fd4319eb4b0..97f955e7136 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,5 +1,39 @@ | |||
| 1 | 2012-09-30 Paul Eggert <eggert@cs.ucla.edu> | 1 | 2012-09-30 Paul Eggert <eggert@cs.ucla.edu> |
| 2 | 2 | ||
| 3 | Profiler improvements: more-accurate timers, overflow checks. | ||
| 4 | * profiler.c: Don't include stdio.h, limits.h, sys/time.h, | ||
| 5 | signal.h, setjmp.h. Include systime.h instead. | ||
| 6 | (saturated_add): New function. | ||
| 7 | (record_backtrace, current_sample_interval): Use EMACS_INT, not size_t. | ||
| 8 | (record_backtrace, handle_profiler_signal): Saturate on fixnum overflow. | ||
| 9 | (profiler_timer, profiler_timer_ok) [HAVE_TIMER_SETTIME]: | ||
| 10 | New static vars. | ||
| 11 | (enum profiler_cpu_running): New enumn. | ||
| 12 | (profiler_cpu_running): Now of that enum type, not bool. | ||
| 13 | All uses changed to store the new value. | ||
| 14 | (handle_profiler_signal): Rename from sigprof_handler_1, | ||
| 15 | for consistency with other handlers. Do not check whether | ||
| 16 | cpu_log is a hash-table if garbage collecting, since it | ||
| 17 | doesn't matter in that case. | ||
| 18 | (deliver_profiler_signal): Rename from sigprof_handler, | ||
| 19 | for consistency with other handlers. | ||
| 20 | (setup_cpu_timer): New function, with much of what used to be in | ||
| 21 | Fprofiler_cpu_start. Check for out-of-range argument. | ||
| 22 | Prefer timer_settime if available, and prefer | ||
| 23 | thread cputime clocks, then process cputime clocks, then | ||
| 24 | monotonic clocks, to the old realtime clock. Use make_timeval | ||
| 25 | to round more-correctly when falling back to setitimer. | ||
| 26 | (Fprofiler_cpu_start): Use it. | ||
| 27 | (Fprofiler_cpu_stop): Prefer timer_settime if available. | ||
| 28 | Don't assume that passing NULL as the 2nd argument of setitimer | ||
| 29 | is the same as passing a pointer to all-zero storage. | ||
| 30 | Ignore SIGPROF afterwards. | ||
| 31 | (malloc_probe): Saturate at MOST_POSITIVE_FIXNUM. | ||
| 32 | * sysdep.c (emacs_sigaction_init): Also mask out SIGPROF in | ||
| 33 | non-fatal signal handlers. Ignore SIGPROF on startup. | ||
| 34 | * syssignal.h (PROFILER_CPU_SUPPORT): Define this macro here, not | ||
| 35 | in profiler.c, since sysdep.c now uses it. | ||
| 36 | |||
| 3 | * sysdep.c (handle_fatal_signal): Bump backtrace size to 40. | 37 | * sysdep.c (handle_fatal_signal): Bump backtrace size to 40. |
| 4 | Suggested by Eli Zaretskii in | 38 | Suggested by Eli Zaretskii in |
| 5 | <http://lists.gnu.org/archive/html/emacs-devel/2012-09/msg00796.html>. | 39 | <http://lists.gnu.org/archive/html/emacs-devel/2012-09/msg00796.html>. |
diff --git a/src/profiler.c b/src/profiler.c index 44a12fc159c..489c68b7291 100644 --- a/src/profiler.c +++ b/src/profiler.c | |||
| @@ -18,13 +18,18 @@ You should have received a copy of the GNU General Public License | |||
| 18 | along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | 18 | along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ |
| 19 | 19 | ||
| 20 | #include <config.h> | 20 | #include <config.h> |
| 21 | #include <stdio.h> | ||
| 22 | #include <limits.h> | ||
| 23 | #include <sys/time.h> | ||
| 24 | #include <signal.h> | ||
| 25 | #include <setjmp.h> | ||
| 26 | #include "lisp.h" | 21 | #include "lisp.h" |
| 27 | #include "syssignal.h" | 22 | #include "syssignal.h" |
| 23 | #include "systime.h" | ||
| 24 | |||
| 25 | /* Return A + B, but return the maximum fixnum if the result would overflow. | ||
| 26 | Assume A and B are nonnegative and in fixnum range. */ | ||
| 27 | |||
| 28 | static EMACS_INT | ||
| 29 | saturated_add (EMACS_INT a, EMACS_INT b) | ||
| 30 | { | ||
| 31 | return min (a + b, MOST_POSITIVE_FIXNUM); | ||
| 32 | } | ||
| 28 | 33 | ||
| 29 | /* Logs. */ | 34 | /* Logs. */ |
| 30 | 35 | ||
| @@ -122,14 +127,12 @@ static void evict_lower_half (log_t *log) | |||
| 122 | } | 127 | } |
| 123 | } | 128 | } |
| 124 | 129 | ||
| 125 | /* Record the current backtrace in LOG. BASE is a special name for | 130 | /* Record the current backtrace in LOG. COUNT is the weight of this |
| 126 | describing which the backtrace come from. BASE can be nil. COUNT is | 131 | current backtrace: milliseconds for CPU counts, and the allocation |
| 127 | a number how many times the profiler sees the backtrace at the | 132 | size for memory logs. */ |
| 128 | time. ELAPSED is a elapsed time in millisecond that the backtrace | ||
| 129 | took. */ | ||
| 130 | 133 | ||
| 131 | static void | 134 | static void |
| 132 | record_backtrace (log_t *log, size_t count) | 135 | record_backtrace (log_t *log, EMACS_INT count) |
| 133 | { | 136 | { |
| 134 | struct backtrace *backlist = backtrace_list; | 137 | struct backtrace *backlist = backtrace_list; |
| 135 | Lisp_Object backtrace; | 138 | Lisp_Object backtrace; |
| @@ -162,8 +165,11 @@ record_backtrace (log_t *log, size_t count) | |||
| 162 | EMACS_UINT hash; | 165 | EMACS_UINT hash; |
| 163 | ptrdiff_t j = hash_lookup (log, backtrace, &hash); | 166 | ptrdiff_t j = hash_lookup (log, backtrace, &hash); |
| 164 | if (j >= 0) | 167 | if (j >= 0) |
| 165 | set_hash_value_slot (log, j, | 168 | { |
| 166 | make_number (count + XINT (HASH_VALUE (log, j)))); | 169 | EMACS_INT old_val = XINT (HASH_VALUE (log, j)); |
| 170 | EMACS_INT new_val = saturated_add (old_val, count); | ||
| 171 | set_hash_value_slot (log, j, make_number (new_val)); | ||
| 172 | } | ||
| 167 | else | 173 | else |
| 168 | { /* BEWARE! hash_put in general can allocate memory. | 174 | { /* BEWARE! hash_put in general can allocate memory. |
| 169 | But currently it only does that if log->next_free is nil. */ | 175 | But currently it only does that if log->next_free is nil. */ |
| @@ -195,29 +201,35 @@ record_backtrace (log_t *log, size_t count) | |||
| 195 | /* Sample profiler. */ | 201 | /* Sample profiler. */ |
| 196 | 202 | ||
| 197 | /* FIXME: Add support for the CPU profiler in W32. */ | 203 | /* FIXME: Add support for the CPU profiler in W32. */ |
| 198 | /* FIXME: the sigprof_handler suffers from race-conditions if the signal | ||
| 199 | is delivered to a thread other than the main Emacs thread. */ | ||
| 200 | 204 | ||
| 201 | #if defined SIGPROF && defined HAVE_SETITIMER | 205 | #ifdef PROFILER_CPU_SUPPORT |
| 202 | #define PROFILER_CPU_SUPPORT | 206 | |
| 207 | /* The profiler timer and whether it was properly initialized, if | ||
| 208 | POSIX timers are available. */ | ||
| 209 | #ifdef HAVE_TIMER_SETTIME | ||
| 210 | static timer_t profiler_timer; | ||
| 211 | static bool profiler_timer_ok; | ||
| 212 | #endif | ||
| 203 | 213 | ||
| 204 | /* True if sampling profiler is running. */ | 214 | /* Status of sampling profiler. */ |
| 205 | static bool profiler_cpu_running; | 215 | static enum profiler_cpu_running |
| 216 | { NOT_RUNNING, TIMER_SETTIME_RUNNING, SETITIMER_RUNNING } | ||
| 217 | profiler_cpu_running; | ||
| 206 | 218 | ||
| 219 | /* Hash-table log of CPU profiler. */ | ||
| 207 | static Lisp_Object cpu_log; | 220 | static Lisp_Object cpu_log; |
| 221 | |||
| 208 | /* Separate counter for the time spent in the GC. */ | 222 | /* Separate counter for the time spent in the GC. */ |
| 209 | static EMACS_INT cpu_gc_count; | 223 | static EMACS_INT cpu_gc_count; |
| 210 | 224 | ||
| 211 | /* The current sample interval in millisecond. */ | 225 | /* The current sample interval in milliseconds. */ |
| 212 | 226 | static EMACS_INT current_sample_interval; | |
| 213 | static int current_sample_interval; | ||
| 214 | 227 | ||
| 215 | /* Signal handler for sample profiler. */ | 228 | /* Signal handler for sample profiler. */ |
| 216 | 229 | ||
| 217 | static void | 230 | static void |
| 218 | sigprof_handler_1 (int signal) | 231 | handle_profiler_signal (int signal) |
| 219 | { | 232 | { |
| 220 | eassert (HASH_TABLE_P (cpu_log)); | ||
| 221 | if (backtrace_list && EQ (backtrace_list->function, Qautomatic_gc)) | 233 | if (backtrace_list && EQ (backtrace_list->function, Qautomatic_gc)) |
| 222 | /* Special case the time-count inside GC because the hash-table | 234 | /* Special case the time-count inside GC because the hash-table |
| 223 | code is not prepared to be used while the GC is running. | 235 | code is not prepared to be used while the GC is running. |
| @@ -225,27 +237,90 @@ sigprof_handler_1 (int signal) | |||
| 225 | not expect the ARRAY_MARK_FLAG to be set. We could try and | 237 | not expect the ARRAY_MARK_FLAG to be set. We could try and |
| 226 | harden the hash-table code, but it doesn't seem worth the | 238 | harden the hash-table code, but it doesn't seem worth the |
| 227 | effort. */ | 239 | effort. */ |
| 228 | cpu_gc_count += current_sample_interval; | 240 | cpu_gc_count = saturated_add (cpu_gc_count, current_sample_interval); |
| 229 | else | 241 | else |
| 230 | record_backtrace (XHASH_TABLE (cpu_log), current_sample_interval); | 242 | { |
| 243 | eassert (HASH_TABLE_P (cpu_log)); | ||
| 244 | record_backtrace (XHASH_TABLE (cpu_log), current_sample_interval); | ||
| 245 | } | ||
| 231 | } | 246 | } |
| 232 | 247 | ||
| 233 | static void | 248 | static void |
| 234 | sigprof_handler (int signal) | 249 | deliver_profiler_signal (int signal) |
| 250 | { | ||
| 251 | deliver_process_signal (signal, handle_profiler_signal); | ||
| 252 | } | ||
| 253 | |||
| 254 | static enum profiler_cpu_running | ||
| 255 | setup_cpu_timer (Lisp_Object sample_interval) | ||
| 235 | { | 256 | { |
| 236 | deliver_process_signal (signal, sigprof_handler_1); | 257 | struct sigaction action; |
| 258 | struct itimerval timer; | ||
| 259 | struct timespec interval; | ||
| 260 | |||
| 261 | if (! RANGED_INTEGERP (1, sample_interval, | ||
| 262 | (TYPE_MAXIMUM (time_t) < EMACS_INT_MAX / 1000 | ||
| 263 | ? (EMACS_INT) TYPE_MAXIMUM (time_t) * 1000 + 999 | ||
| 264 | : EMACS_INT_MAX))) | ||
| 265 | return NOT_RUNNING; | ||
| 266 | |||
| 267 | current_sample_interval = XINT (sample_interval); | ||
| 268 | interval = make_emacs_time (current_sample_interval / 1000, | ||
| 269 | current_sample_interval % 1000 * 1000000); | ||
| 270 | emacs_sigaction_init (&action, deliver_profiler_signal); | ||
| 271 | sigaction (SIGPROF, &action, 0); | ||
| 272 | |||
| 273 | #ifdef HAVE_TIMER_SETTIME | ||
| 274 | if (! profiler_timer_ok) | ||
| 275 | { | ||
| 276 | /* System clocks to try, in decreasing order of desirability. */ | ||
| 277 | static clockid_t const system_clock[] = { | ||
| 278 | #ifdef CLOCK_THREAD_CPUTIME_ID | ||
| 279 | CLOCK_THREAD_CPUTIME_ID, | ||
| 280 | #endif | ||
| 281 | #ifdef CLOCK_PROCESS_CPUTIME_ID | ||
| 282 | CLOCK_PROCESS_CPUTIME_ID, | ||
| 283 | #endif | ||
| 284 | #ifdef CLOCK_MONOTONIC | ||
| 285 | CLOCK_MONOTONIC, | ||
| 286 | #endif | ||
| 287 | CLOCK_REALTIME | ||
| 288 | }; | ||
| 289 | int i; | ||
| 290 | struct sigevent sigev; | ||
| 291 | sigev.sigev_value.sival_ptr = &profiler_timer; | ||
| 292 | sigev.sigev_signo = SIGPROF; | ||
| 293 | sigev.sigev_notify = SIGEV_SIGNAL; | ||
| 294 | |||
| 295 | for (i = 0; i < sizeof system_clock / sizeof *system_clock; i++) | ||
| 296 | if (timer_create (system_clock[i], &sigev, &profiler_timer) == 0) | ||
| 297 | { | ||
| 298 | profiler_timer_ok = 1; | ||
| 299 | break; | ||
| 300 | } | ||
| 301 | } | ||
| 302 | |||
| 303 | if (profiler_timer_ok) | ||
| 304 | { | ||
| 305 | struct itimerspec ispec; | ||
| 306 | ispec.it_value = ispec.it_interval = interval; | ||
| 307 | timer_settime (profiler_timer, 0, &ispec, 0); | ||
| 308 | return TIMER_SETTIME_RUNNING; | ||
| 309 | } | ||
| 310 | #endif | ||
| 311 | |||
| 312 | timer.it_value = timer.it_interval = make_timeval (interval); | ||
| 313 | setitimer (ITIMER_PROF, &timer, 0); | ||
| 314 | return SETITIMER_RUNNING; | ||
| 237 | } | 315 | } |
| 238 | 316 | ||
| 239 | DEFUN ("profiler-cpu-start", Fprofiler_cpu_start, Sprofiler_cpu_start, | 317 | DEFUN ("profiler-cpu-start", Fprofiler_cpu_start, Sprofiler_cpu_start, |
| 240 | 1, 1, 0, | 318 | 1, 1, 0, |
| 241 | doc: /* Start or restart the cpu profiler. | 319 | doc: /* Start or restart the cpu profiler. |
| 242 | The cpu profiler will take call-stack samples each SAMPLE-INTERVAL (expressed in milliseconds). | 320 | It takes call-stack samples each SAMPLE-INTERVAL milliseconds. |
| 243 | See also `profiler-log-size' and `profiler-max-stack-depth'. */) | 321 | See also `profiler-log-size' and `profiler-max-stack-depth'. */) |
| 244 | (Lisp_Object sample_interval) | 322 | (Lisp_Object sample_interval) |
| 245 | { | 323 | { |
| 246 | struct sigaction sa; | ||
| 247 | struct itimerval timer; | ||
| 248 | |||
| 249 | if (profiler_cpu_running) | 324 | if (profiler_cpu_running) |
| 250 | error ("Sample profiler is already running"); | 325 | error ("Sample profiler is already running"); |
| 251 | 326 | ||
| @@ -256,19 +331,9 @@ See also `profiler-log-size' and `profiler-max-stack-depth'. */) | |||
| 256 | profiler_max_stack_depth); | 331 | profiler_max_stack_depth); |
| 257 | } | 332 | } |
| 258 | 333 | ||
| 259 | current_sample_interval = XINT (sample_interval); | 334 | profiler_cpu_running = setup_cpu_timer (sample_interval); |
| 260 | 335 | if (! profiler_cpu_running) | |
| 261 | sa.sa_handler = sigprof_handler; | 336 | error ("Invalid sample interval"); |
| 262 | sa.sa_flags = SA_RESTART; | ||
| 263 | sigemptyset (&sa.sa_mask); | ||
| 264 | sigaction (SIGPROF, &sa, 0); | ||
| 265 | |||
| 266 | timer.it_interval.tv_sec = 0; | ||
| 267 | timer.it_interval.tv_usec = current_sample_interval * 1000; | ||
| 268 | timer.it_value = timer.it_interval; | ||
| 269 | setitimer (ITIMER_PROF, &timer, 0); | ||
| 270 | |||
| 271 | profiler_cpu_running = true; | ||
| 272 | 337 | ||
| 273 | return Qt; | 338 | return Qt; |
| 274 | } | 339 | } |
| @@ -279,12 +344,30 @@ DEFUN ("profiler-cpu-stop", Fprofiler_cpu_stop, Sprofiler_cpu_stop, | |||
| 279 | Return non-nil if the profiler was running. */) | 344 | Return non-nil if the profiler was running. */) |
| 280 | (void) | 345 | (void) |
| 281 | { | 346 | { |
| 282 | if (!profiler_cpu_running) | 347 | switch (profiler_cpu_running) |
| 283 | return Qnil; | 348 | { |
| 284 | profiler_cpu_running = false; | 349 | case NOT_RUNNING: |
| 350 | return Qnil; | ||
| 351 | |||
| 352 | case TIMER_SETTIME_RUNNING: | ||
| 353 | { | ||
| 354 | struct itimerspec disable; | ||
| 355 | memset (&disable, 0, sizeof disable); | ||
| 356 | timer_settime (profiler_timer, 0, &disable, 0); | ||
| 357 | } | ||
| 358 | break; | ||
| 285 | 359 | ||
| 286 | setitimer (ITIMER_PROF, 0, 0); | 360 | case SETITIMER_RUNNING: |
| 361 | { | ||
| 362 | struct itimerval disable; | ||
| 363 | memset (&disable, 0, sizeof disable); | ||
| 364 | setitimer (ITIMER_PROF, &disable, 0); | ||
| 365 | } | ||
| 366 | break; | ||
| 367 | } | ||
| 287 | 368 | ||
| 369 | signal (SIGPROF, SIG_IGN); | ||
| 370 | profiler_cpu_running = NOT_RUNNING; | ||
| 288 | return Qt; | 371 | return Qt; |
| 289 | } | 372 | } |
| 290 | 373 | ||
| @@ -307,7 +390,7 @@ Before returning, a new log is allocated for future samples. */) | |||
| 307 | (void) | 390 | (void) |
| 308 | { | 391 | { |
| 309 | Lisp_Object result = cpu_log; | 392 | Lisp_Object result = cpu_log; |
| 310 | /* Here we're making the log visible to Elisp , so it's not safe any | 393 | /* Here we're making the log visible to Elisp, so it's not safe any |
| 311 | more for our use afterwards since we can't rely on its special | 394 | more for our use afterwards since we can't rely on its special |
| 312 | pre-allocated keys anymore. So we have to allocate a new one. */ | 395 | pre-allocated keys anymore. So we have to allocate a new one. */ |
| 313 | cpu_log = (profiler_cpu_running | 396 | cpu_log = (profiler_cpu_running |
| @@ -319,7 +402,7 @@ Before returning, a new log is allocated for future samples. */) | |||
| 319 | cpu_gc_count = 0; | 402 | cpu_gc_count = 0; |
| 320 | return result; | 403 | return result; |
| 321 | } | 404 | } |
| 322 | #endif /* not defined PROFILER_CPU_SUPPORT */ | 405 | #endif /* PROFILER_CPU_SUPPORT */ |
| 323 | 406 | ||
| 324 | /* Memory profiler. */ | 407 | /* Memory profiler. */ |
| 325 | 408 | ||
| @@ -399,7 +482,7 @@ void | |||
| 399 | malloc_probe (size_t size) | 482 | malloc_probe (size_t size) |
| 400 | { | 483 | { |
| 401 | eassert (HASH_TABLE_P (memory_log)); | 484 | eassert (HASH_TABLE_P (memory_log)); |
| 402 | record_backtrace (XHASH_TABLE (memory_log), size); | 485 | record_backtrace (XHASH_TABLE (memory_log), min (size, MOST_POSITIVE_FIXNUM)); |
| 403 | } | 486 | } |
| 404 | 487 | ||
| 405 | void | 488 | void |
| @@ -415,7 +498,7 @@ to make room for new entries. */); | |||
| 415 | profiler_log_size = 10000; | 498 | profiler_log_size = 10000; |
| 416 | 499 | ||
| 417 | #ifdef PROFILER_CPU_SUPPORT | 500 | #ifdef PROFILER_CPU_SUPPORT |
| 418 | profiler_cpu_running = false; | 501 | profiler_cpu_running = NOT_RUNNING; |
| 419 | cpu_log = Qnil; | 502 | cpu_log = Qnil; |
| 420 | staticpro (&cpu_log); | 503 | staticpro (&cpu_log); |
| 421 | defsubr (&Sprofiler_cpu_start); | 504 | defsubr (&Sprofiler_cpu_start); |
diff --git a/src/sysdep.c b/src/sysdep.c index 4deb022fb90..b7141011d05 100644 --- a/src/sysdep.c +++ b/src/sysdep.c | |||
| @@ -1447,6 +1447,9 @@ emacs_sigaction_init (struct sigaction *action, signal_handler_t handler) | |||
| 1447 | #ifdef SIGDANGER | 1447 | #ifdef SIGDANGER |
| 1448 | sigaddset (&action->sa_mask, SIGDANGER); | 1448 | sigaddset (&action->sa_mask, SIGDANGER); |
| 1449 | #endif | 1449 | #endif |
| 1450 | #ifdef PROFILER_CPU_SUPPORT | ||
| 1451 | sigaddset (&action->sa_mask, SIGPROF); | ||
| 1452 | #endif | ||
| 1450 | #ifdef SIGWINCH | 1453 | #ifdef SIGWINCH |
| 1451 | sigaddset (&action->sa_mask, SIGWINCH); | 1454 | sigaddset (&action->sa_mask, SIGWINCH); |
| 1452 | #endif | 1455 | #endif |
| @@ -1837,7 +1840,7 @@ init_signals (bool dumping) | |||
| 1837 | #endif | 1840 | #endif |
| 1838 | sigaction (SIGTERM, &process_fatal_action, 0); | 1841 | sigaction (SIGTERM, &process_fatal_action, 0); |
| 1839 | #ifdef SIGPROF | 1842 | #ifdef SIGPROF |
| 1840 | sigaction (SIGPROF, &process_fatal_action, 0); | 1843 | signal (SIGPROF, SIG_IGN); |
| 1841 | #endif | 1844 | #endif |
| 1842 | #ifdef SIGVTALRM | 1845 | #ifdef SIGVTALRM |
| 1843 | sigaction (SIGVTALRM, &process_fatal_action, 0); | 1846 | sigaction (SIGVTALRM, &process_fatal_action, 0); |
diff --git a/src/syssignal.h b/src/syssignal.h index 5c0edaa591d..0bc856769ba 100644 --- a/src/syssignal.h +++ b/src/syssignal.h | |||
| @@ -29,6 +29,10 @@ extern void init_signals (bool); | |||
| 29 | #define FORWARD_SIGNAL_TO_MAIN_THREAD | 29 | #define FORWARD_SIGNAL_TO_MAIN_THREAD |
| 30 | #endif | 30 | #endif |
| 31 | 31 | ||
| 32 | #if defined SIGPROF && (defined HAVE_TIMER_SETTIME || defined HAVE_SETITIMER) | ||
| 33 | # define PROFILER_CPU_SUPPORT | ||
| 34 | #endif | ||
| 35 | |||
| 32 | extern sigset_t empty_mask; | 36 | extern sigset_t empty_mask; |
| 33 | 37 | ||
| 34 | typedef void (*signal_handler_t) (int); | 38 | typedef void (*signal_handler_t) (int); |