From: "osyoyu (Daisuke Aritomo) via ruby-core" <ruby-core@...> Date: 2024-01-22T12:03:26+00:00 Subject: [ruby-core:116365] [Ruby master Bug#20197] Postponed job invocations are significantly reduced in Ruby 3.3 Issue #20197 has been updated by osyoyu (Daisuke Aritomo). Thank you for your investigation and throughout explanation! I now understand what was happening. > This PR will I think fix the issue with your reproduction: https://github.com/ruby/ruby/pull/9633. Applying this patch worked perfectly on my environment too. > Are you able to share some more details about your use-case for postponed_job by the way? I was actually working on my own Ruby profiler https://github.com/osyoyu/pf2 , and was using postponed_job to run `rb_profile_thread_frames()`, just like StackProf's original implementation. The `rb_postponed_job_trigger` call could be found in `TimerThreadScheduler`. https://github.com/osyoyu/pf2/blob/v0.2.0/ext/pf2/src/timer_thread_scheduler.rs#L82 (As @byroot pointed out, I'm aware that postponed_job isn't strictly required here; I could send a signal to the target pthread, and call `rb_profile_thread_frames()` in the signal handler. But that's probably an another story) > This seems like a fair bit of extra complexity to carry around though if there isn't a use-case which requires it. From the perspective of a sampling profiler developer, I think it's safe not to implement this technique. I'm `trigger`ing postponed jobs periodically (e.g. every 10 ms or so), and one trigger flag being effectively "ignored" (due to be getting registered in a thread which just entered a long sleep) is negligible, as long as subsequent triggers get fired. ---------------------------------------- Bug #20197: Postponed job invocations are significantly reduced in Ruby 3.3 https://bugs.ruby-lang.org/issues/20197#change-106385 * Author: osyoyu (Daisuke Aritomo) * Status: Open * Priority: Normal * Assignee: kjtsanaktsidis (KJ Tsanaktsidis) * ruby -v: ruby 3.3.0 (2023-12-25 revision 5124f9ac75) [x86_64-linux] * Backport: 3.0: UNKNOWN, 3.1: UNKNOWN, 3.2: UNKNOWN, 3.3: UNKNOWN ---------------------------------------- The number of postponed job invocations has been significantly reduced in Ruby 3.3. While my understanding is that postponed jobs provide no guarantee of how soon registered callbacks will fire, I believe the current rate is too low for practical usage, especially for profilers such as StackProf. A git bisect led me to https://github.com/ruby/ruby/commit/1f0304218cf00e05a4a126196676ba221ebf91f6 which obviously seems to be related, but I'm not sure why. ## Repro ### Expected The job fires (nearly) immediately after being triggered. In the following example, the job is triggered every 100 ms. ``` % ruby bin/test.rb # runs for 3 seconds count: 1 count: 2 (snip) count: 29 ``` ### Actual The job gets fired only once. ``` % ruby bin/test.rb count: 1 ``` ### Code ```ruby require 'mycext' time = Time.now th = Thread.new do loop do sleep 0.01 break if Time.now - time > 3 # run for 3 seconds end end th.join ``` ```c #include <pthread.h> #include <stdio.h> #include <time.h> #include "ruby.h" #include "ruby/debug.h" int called_count; void postponed_job(void *ptr) { called_count++; printf("count: %d\n", called_count); } _Noreturn void * pthread_main(void *_) { while (1) { rb_postponed_job_register_one(0, postponed_job, NULL); // Sleep for 100 ms struct timespec ts; ts.tv_sec = 0; ts.tv_nsec = 100 * 1000 * 1000; nanosleep(&ts, NULL); } } RUBY_FUNC_EXPORTED void Init_mycext(void) { called_count = 0; pthread_t pthread; pthread_create(&pthread, NULL, pthread_main, NULL); } ``` -- https://bugs.ruby-lang.org/ ______________________________________________ ruby-core mailing list -- ruby-core@ml.ruby-lang.org To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org ruby-core info -- https://ml.ruby-lang.org/mailman3/postorius/lists/ruby-core.ml.ruby-lang.org/