Project

General

Profile

Bug #20197

Updated by osyoyu (Daisuke Aritomo) 10 months ago

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 fires only once. 

 ``` 
 % ruby bin/test.rb 
 count: 1 
 count: 2 
 (snip) 
 count: 29 
 ``` 

 ### 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); 
 } 
 ```

Back