diff --git a/ext/stackprof/extconf.rb b/ext/stackprof/extconf.rb index 742ff463..c5386ef0 100644 --- a/ext/stackprof/extconf.rb +++ b/ext/stackprof/extconf.rb @@ -5,7 +5,8 @@ return end -if have_func('rb_postponed_job_register_one') && +if (have_func('rb_postponed_job_preregister') || + have_func('rb_postponed_job_register_one')) && have_func('rb_profile_frames') && have_func('rb_tracepoint_new') && have_const('RUBY_INTERNAL_EVENT_NEWOBJ') diff --git a/ext/stackprof/stackprof.c b/ext/stackprof/stackprof.c index 36033812..ab6238ad 100644 --- a/ext/stackprof/stackprof.c +++ b/ext/stackprof/stackprof.c @@ -26,6 +26,16 @@ #define FAKE_FRAME_MARK INT2FIX(1) #define FAKE_FRAME_SWEEP INT2FIX(2) +#ifdef HAVE_RB_POSTPONED_JOB_PREREGISTER +static rb_postponed_job_handle_t job_record_gc, job_sample_and_record, job_record_buffer; + +# define preregister_job(job) (job = rb_postponed_job_preregister(0, stackprof_##job, (void*)0)) +# define trigger_job(job) rb_postponed_job_trigger(job) +#else +# define preregister_job(job, func) ((void*)0) +# define trigger_job(job) rb_postponed_job_register_one(0, stackprof_##job, (void*)0) +#endif + static const char *fake_frame_cstrs[] = { "(garbage collection)", "(marking)", @@ -225,7 +235,7 @@ stackprof_start(int argc, VALUE *argv, VALUE self) sigaction(mode == sym_wall ? SIGALRM : SIGPROF, &sa, NULL); timer.it_interval.tv_sec = 0; - timer.it_interval.tv_usec = NUM2LONG(interval); + timer.it_interval.tv_usec = NUM2UINT(interval); timer.it_value = timer.it_interval; setitimer(mode == sym_wall ? ITIMER_REAL : ITIMER_PROF, &timer, 0); } else if (mode == sym_custom) { @@ -813,16 +823,16 @@ stackprof_signal_handler(int sig, siginfo_t *sinfo, void *ucontext) capture_timestamp(&_stackprof.gc_start_timestamp); } _stackprof.unrecorded_gc_samples++; - rb_postponed_job_register_one(0, stackprof_job_record_gc, (void*)0); + trigger_job(job_record_gc); } else { if (stackprof_use_postponed_job) { - rb_postponed_job_register_one(0, stackprof_job_sample_and_record, (void*)0); + trigger_job(job_sample_and_record); } else { // Buffer a sample immediately, if an existing sample exists this will // return immediately stackprof_buffer_sample(); // Enqueue a job to record the sample - rb_postponed_job_register_one(0, stackprof_job_record_buffer, (void*)0); + trigger_job(job_record_buffer); } } pthread_mutex_unlock(&lock); @@ -899,7 +909,7 @@ stackprof_atfork_parent(void) if (STACKPROF_RUNNING()) { if (_stackprof.mode == sym_wall || _stackprof.mode == sym_cpu) { timer.it_interval.tv_sec = 0; - timer.it_interval.tv_usec = NUM2LONG(_stackprof.interval); + timer.it_interval.tv_usec = NUM2UINT(_stackprof.interval); timer.it_value = timer.it_interval; setitimer(_stackprof.mode == sym_wall ? ITIMER_REAL : ITIMER_PROF, &timer, 0); } @@ -1010,5 +1020,9 @@ Init_stackprof(void) rb_define_singleton_method(rb_mStackProf, "sample", stackprof_sample, 0); rb_define_singleton_method(rb_mStackProf, "use_postponed_job!", stackprof_use_postponed_job_l, 0); + preregister_job(job_record_gc); + preregister_job(job_sample_and_record); + preregister_job(job_record_buffer); + pthread_atfork(stackprof_atfork_prepare, stackprof_atfork_parent, stackprof_atfork_child); }