> ささだです. > > (2011/05/08 20:23), KOSAKI Motohiro wrote: > > Ruby VM internal > > に詳しい方々に質問です。現在、thread->interrupt_flagはどうやって排他制御されるデザインになっていますでしょうか? > > 詳しいかどうかは疑問ですが,th->interrupt_flag を作りました. そういうのを詳しい人というのです :-) > > 基本的に,th->interrupt_flag を弄る人は GVL 取ってるので,排他制御出来 > てると思ってたんだけど,まずい? timer threadさんがとってなくて、彼にはGVLを取るという選択肢はなさそうだ。 というのが first impression でした。 > GVL 取ってないのは timer_thread だけど,timer_thread が設定する時 > に,or を設定しようとして,そこでまずいことが起こる可能性があるのか > な.timer_thread_lock ってのも,昔は取っていなかったような(覚えていない). > > timer_thread の flag は,実は lost してもあんまり問題ない(ちょっとス > ケジューリングが遅れるだけ)ってんで現在の仕様にしている(ロックを取らな > い)のですが,他が設定したものを reset してしまう可能性がある(具体的に > は signal 回りとバッティングする),といのはまずいかもしれませんね.どう > しよ. はい、わたしが心配していたのは後者の方です。 > > (1) 落としてもまぁ巡り巡って何とかなる系と,(2) 落としちゃいけない系を > 分けますかねえ. > > (1) > #define RUBY_VM_SET_TIMER_INTERRUPT(th) ((th)->interrupt_flag |= 0x01) > #define RUBY_VM_SET_FINALIZER_INTERRUPT(th) ((th)->interrupt_flag |= 0x04) > > (2) > #define RUBY_VM_SET_INTERRUPT(th) ((th)->interrupt_flag |= 0x02) わたしは timer interrupt だけ分けるのも、ありだと思いましたがどうでしょうか。 理由は 1)タイマースレッドだけがGVLを持つことが無理 2)タイマー割り込みだけは、どんな状況でもロストしても大事故は起きない の2つの特殊性があるからです。好都合なことに、タイマースレッドの cond_timedwait がtimer_lockを暗にreleaseし、そこでrelease barrierが張られるので、 > 今気づきましたが,結局「ちょっとシグナル配送が遅れる」だけなので,全部 > (1) に分類してもいいような気がしてきました.なので,現状は「大きな問題は > 起きないのではないか」派. こちらは理解が追いつかなかったので補足をお願いして良いですか? RUBY_VM_SET_INTERRUPT() がロストしたときに、後からフラグを立て直してくれる人は どなたでしょうか? たとえば、 thread.c#do_selectには以下のループがありますが #if defined(__CYGWIN__) || defined(_WIN32) (snip) BLOCKING_REGION({ do { result = rb_fd_select(n, read, write, except, wait); (snip) } } while (__th->interrupt_flag == 0); }, 0, 0); この場合、interrupt_flag が0 だと Rubyの世界に戻ってきてくれなさそうですが、 大丈夫でしょうか? また、タイマースレッドが定期的に起こしてくれるのはメインスレッドだけなので、 サブスレッドはRUBY_VM_CHECK_INTS() がfalseを返し続ける限り、 rb_threadptr_execute_interrupts_rec() まで来ないのではないのかという疑惑が あるのですが、どのルートで担保されてますでしょうか?