Issue #5130 has been updated by Jeremy Evans.


Motohiro KOSAKI wrote:
> First, we can't apply your nor Eric's patch because it's racy. Your patch care following scenario.
> 
>  1) thread-A create thread-B
>  2) thread-A call terminate_all
>  3) thread-B start
> 
> but, it doesn't care following scenario.
> 
>  1) thread-A create thread-B
>  2) thread-B start
>  (just after)
>  3) thread-A call terminate_all

True.  As my earlier message says, the patch only reduces the chance losing the race.
 
> Moreover, we shouldn't need a special care about thread starting. it should works as well.
> I don't plan to apply your ugly bandaid patch.

Fair enough.  I certainly agree that my patch is an ugly bandaid.

> Second, your analysis is not accurate.  The complete opnebsd failed scenario is here.
> (OMG, I needed to install openbsd).
> 
> thread-A                                      thread-B
> ---------------------------------------
> -> gvl_yield
>   vm->gvl.wait_yield = 1;
>   -> sched_yield
>                                                      -> gvl_yield
>                                                         -> cond_wait(switch_wait_cond)    # wait until waking up sched_yield()
>                                                               -> task-state change to COND_WAIT
>   <- sched_yield
>   vm->gvl.wait_yield = 0;
>   -> pthread_cond_broadcast()
>       -> task-state of thread-B change to RUNNING
> <- gvl_yield
> 
> -> gvl_yield
>   vm->gvl.wait_yield = 1;
>   -> sched_yield
>                                                        <- cond_wait(switch_wait_cond)
>                                                        
>                                                        *** Oh, wait_yield is 1. try to sleep again.
>                                                        
>                                                        -> cond_wait(switch_wait_cond)
> 
> That's all.
> rb_thread_terminate_all() called rb_thread_schedule() repeatedly. and waking-up cond_wait(switch_wait_cond) failed
> repeatedly. OpenBSD's user land pthread library makes semi deterministic scheduling. and then, the test code can't
> bail out forever.

So the underlying problem is that wait_yield is always set to 1 when thread 2 wakes up, which causes thread 2 to sleep again?  Is that a bug in ruby or OpenBSD?
 
> btw, sched_yield()  works as expected on OpenBSD. then, I don't change sched_yield() call at least now.

That's good.

Thank you for taking the time to look into the issue in more detail.  If I can be of any help, please let me know.
----------------------------------------
Backport #5130: Thread.pass sticks on OpenBSD
http://redmine.ruby-lang.org/issues/5130

Author: Yui NARUSE
Status: Assigned
Priority: Normal
Assignee: Yuki Sonoda
Category: 
Target version: 


=begin
On OpenBSD 4.9, following script will stick.

 ./miniruby -ve'Thread.new{Thread.pass}'
=end



-- 
http://redmine.ruby-lang.org