|
25 | 25 | #define FAKE_FRAME_MARK INT2FIX(1)
|
26 | 26 | #define FAKE_FRAME_SWEEP INT2FIX(2)
|
27 | 27 |
|
28 |
| -/* |
29 |
| - * As of Ruby 3.0, it should be safe to read stack frames at any time |
30 |
| - * See https://github.com/ruby/ruby/commit/0e276dc458f94d9d79a0f7c7669bde84abe80f21 |
31 |
| - */ |
32 |
| -#if RUBY_API_VERSION_MAJOR < 3 |
33 |
| - #define USE_POSTPONED_JOB |
34 |
| -#endif |
35 |
| - |
36 | 28 | static const char *fake_frame_cstrs[] = {
|
37 | 29 | "(garbage collection)",
|
38 | 30 | "(marking)",
|
39 | 31 | "(sweeping)",
|
40 | 32 | };
|
41 | 33 |
|
| 34 | +static int stackprof_use_postponed_job = 1; |
| 35 | + |
42 | 36 | #define TOTAL_FAKE_FRAMES (sizeof(fake_frame_cstrs) / sizeof(char *))
|
43 | 37 |
|
44 | 38 | #ifdef _POSIX_MONOTONIC_CLOCK
|
@@ -701,15 +695,13 @@ stackprof_job_record_gc(void *data)
|
701 | 695 | stackprof_record_gc_samples();
|
702 | 696 | }
|
703 | 697 |
|
704 |
| -#ifdef USE_POSTPONED_JOB |
705 | 698 | static void
|
706 | 699 | stackprof_job_sample_and_record(void *data)
|
707 | 700 | {
|
708 | 701 | if (!_stackprof.running) return;
|
709 | 702 |
|
710 | 703 | stackprof_sample_and_record();
|
711 | 704 | }
|
712 |
| -#endif |
713 | 705 |
|
714 | 706 | static void
|
715 | 707 | stackprof_job_record_buffer(void *data)
|
@@ -740,15 +732,15 @@ stackprof_signal_handler(int sig, siginfo_t *sinfo, void *ucontext)
|
740 | 732 | _stackprof.unrecorded_gc_samples++;
|
741 | 733 | rb_postponed_job_register_one(0, stackprof_job_record_gc, (void*)0);
|
742 | 734 | } else {
|
743 |
| -#ifdef USE_POSTPONED_JOB |
744 |
| - rb_postponed_job_register_one(0, stackprof_job_sample_and_record, (void*)0); |
745 |
| -#else |
746 |
| - // Buffer a sample immediately, if an existing sample exists this will |
747 |
| - // return immediately |
748 |
| - stackprof_buffer_sample(); |
749 |
| - // Enqueue a job to record the sample |
750 |
| - rb_postponed_job_register_one(0, stackprof_job_record_buffer, (void*)0); |
751 |
| -#endif |
| 735 | + if (stackprof_use_postponed_job) { |
| 736 | + rb_postponed_job_register_one(0, stackprof_job_sample_and_record, (void*)0); |
| 737 | + } else { |
| 738 | + // Buffer a sample immediately, if an existing sample exists this will |
| 739 | + // return immediately |
| 740 | + stackprof_buffer_sample(); |
| 741 | + // Enqueue a job to record the sample |
| 742 | + rb_postponed_job_register_one(0, stackprof_job_record_buffer, (void*)0); |
| 743 | + } |
752 | 744 | }
|
753 | 745 | pthread_mutex_unlock(&lock);
|
754 | 746 | }
|
@@ -826,9 +818,24 @@ stackprof_atfork_child(void)
|
826 | 818 | stackprof_stop(rb_mStackProf);
|
827 | 819 | }
|
828 | 820 |
|
| 821 | +static VALUE |
| 822 | +stackprof_use_postponed_job_l(VALUE self) |
| 823 | +{ |
| 824 | + stackprof_use_postponed_job = true; |
| 825 | + return Qnil; |
| 826 | +} |
| 827 | + |
829 | 828 | void
|
830 | 829 | Init_stackprof(void)
|
831 | 830 | {
|
| 831 | + /* |
| 832 | + * As of Ruby 3.0, it should be safe to read stack frames at any time, unless YJIT is enabled |
| 833 | + * See https://github.com/ruby/ruby/commit/0e276dc458f94d9d79a0f7c7669bde84abe80f21 |
| 834 | + */ |
| 835 | + #if RUBY_API_VERSION_MAJOR < 3 |
| 836 | + stackprof_use_postponed_job = false; |
| 837 | + #endif |
| 838 | + |
832 | 839 | size_t i;
|
833 | 840 | #define S(name) sym_##name = ID2SYM(rb_intern(#name));
|
834 | 841 | S(object);
|
@@ -890,6 +897,7 @@ Init_stackprof(void)
|
890 | 897 | rb_define_singleton_method(rb_mStackProf, "stop", stackprof_stop, 0);
|
891 | 898 | rb_define_singleton_method(rb_mStackProf, "results", stackprof_results, -1);
|
892 | 899 | rb_define_singleton_method(rb_mStackProf, "sample", stackprof_sample, 0);
|
| 900 | + rb_define_singleton_method(rb_mStackProf, "use_postponed_job!", stackprof_use_postponed_job_l, 0); |
893 | 901 |
|
894 | 902 | pthread_atfork(stackprof_atfork_prepare, stackprof_atfork_parent, stackprof_atfork_child);
|
895 | 903 | }
|
0 commit comments