ruby-trunk-changes r64105 - r64124

今日はなんと専任の timer thread をなくすという大きな変更がありました。

normal: r64105 2018-07-30 05:28:56 +0900

SIGCHLD 関連のテストでシグナル受信を待つのに sleep つきの 10回のループで待ってたのを pipe を使ってより確実に待つようにしています。MJIT 環境下では待ち時間が足りないことがあったみたいです。

svn: r64106 2018-07-30 05:28:57 +0900

version.h の日付更新。

normal: r64107 2018-07-30 05:47:33 +0900

timer thread を廃止するという内部的には特大の変更です。あまりちゃんと読めてないのですが、まず timer thread を起動することはなく、定期的な preemption は rb_vm_t::gvl::timer というのが追加されていて、GVL 獲得待ちの thread のうち 1つが timer thread のかわりになるようになってて、一定時間で wakeup して割り込みをかけるようにしています。なんだけど、これだと2つの Thread がブロックせずに実行を続けてる場合に定期的に切り替わらないんじゃないかな…? またシグナル処理は timer thread がなくなったのでその他の thread で sigmask を外して直接シグナルハンドラを実行してメインスレッドにイベント送信するようになってて、そのため少し前の SIGCHLD の処理の変更のための仕組みもちょっといじられています。このシグナル処理もだいじょうぶなのかなぁとちょっと心配ですね。大丈夫かなぁこれ…という感じですが今日はこの後このコミットの追加修正がしばらく続いています。たぶん安定させるまでしばらくかかるでしょう。 [ruby-core:88088] [Misc #14937]

normal: r64108 2018-07-30 07:19:15 +0900

r64107 の ubf_select() という IO の block をする時の割り込み用関数の不具合修正。 thread に SIGVTALRM で割り込みをかける前に rb_vm_t::gvl::timer に timer thread の役割を果たす thread がいない状態だったら GVL 待ちの thread を1つ起こして timer thread 候補にさせるようにしています。 ubf_wakeup_thread() は thread がブロックしてるシステムコールから確実にかえってくるとはかぎらないので繰り返し起こすためとのこと。この参照されてるチケット自分のものだった。 [ruby-core:88088] [Misc #14937] [Bug #5343]

normal: r64109 2018-07-30 07:54:44 +0900

thread.c の ruby_ppoll() の定義位置を移動? 行を移動してるだけにみえるんだけどコミットログによると pthread_pthread.c がこの関数に依存しているため、プラットフォーム毎のソースを #include で取り込む前に移動しているとのこと。そういえば thread_pthread.c とか thread_win32.c とかって #include で取り込まれてるんでしたっけ。

normal: r64110 2018-07-30 09:31:08 +0900

r64109 の追加修正。 そもそも ruby_ppoll() の定義を thread_pthread.c に移動しています。 [ruby-core:88173] [Bug #14950]

normal: r64111 2018-07-30 11:28:00 +0900

r64108 の再々修正。 thread_pthread.c の rb_sigwait_sleep() で ubf で割り込み処理待ちの thread が存在していたら ppoll(2) にタイムアウトをつけて定期的リトライをするようにしています。これも割り込みしても thread がブロックから抜けないかもしれない([Bug #5343] の議論をみると…自分でもすっかり忘れてるんだけど、シグナルの喪失もあるのかも)というのに対応するためと思われます。 [ruby-core:88088] [Misc #14937] [Bug #5343]

shyouhei: r64112 2018-07-30 12:23:32 +0900

mjit.c に配列の初期化子に変数を含んでいて古いコンパイラで対応できない書きかたがあったので、初期化後に代入する記法に変更しています。

normal: r64113 2018-07-30 13:28:28 +0900

r64108 および r64111 の再修正で rb_sigwait_sleep() で必要な初期化が分岐の一方でしか行われてなかったのを修正しています。 [ruby-core:88088] [Misc #14937] [Bug #5343]

normal: r64114 2018-07-30 14:51:01 +0900

thread_pthread.c の gvl_destroy() で rb_vm_t::gvl::switch_wait_cond, switch_cond, lock などの mutex や condition variable の破棄をしてたのを if(0) の分岐内にいれて実行しないようにしています。コミットログのコメントは VM 終了時に他の thread が使う可能性があるので、ってことかな。

normal: r64115 2018-07-30 14:51:06 +0900

r64108、r64111 あたりの続きで ubf でブロック状態の thread への割り込みを繰り返すため、ppoll(2) などのタイムアウトを計算する処理を sigwait_timeout() という関数に切り出して、ここで ubf リストが空じゃなかったら最低の時間粒度 TIME_QUANTUM_USEC を返させるようにしています。つまりこれって timer thread の time slice のための割り込みと同じだから timer thread 相当になる thread がなくても割り込むようにするためってことですかね。そうすると rb_vm_t::gvl::timer はもういらなくならないのかな? [ruby-core:88088] [Misc #14937] [Bug #5343]

normal: r64116 2018-07-30 15:02:22 +0900

thread_pthread.c の rb_sigwait_sleep() で th が NULL になる可能性があるので参照前のチェックを追加しています。 MJIT から使う時に NULL になる場合があるようです。

normal: r64117 2018-07-30 15:35:08 +0900

SIGCHLD の独自処理で rb_execute_context_t::sleep_cond を GVL 用と SIGCHLD 用に使いまわしているので、利用前に rb_sleep_cond_get() で取得して使い終わったら struct waitpid_state のメンバーはクリアするようにしています。 [ruby-core:88183]

shyouhei: r64118 2018-07-30 16:07:48 +0900

ソースコード内の一部でどうしても消せない警告を preprocessor の #pragma を使って警告オプションの挙動を局所的に変更して抑制する手法がところどころ使われてるので、これをまとめて COMPILER_WARNING_PUSH/COMPILER_WARNING_IGNORED/COMPILER_WARNING_POP といったマクロに定義して使いまわすようにしています。ただしマクロは internal.h に定義しているので include/ruby/ruby.h では使えない(非公開マクロにしたかったため)のでそこは置き換えてないとのこと。

shyouhei: r64119 2018-07-30 16:53:24 +0900

r64118 の再修正。#pragma による局所的な警告オプションの変更は関数内の一部分で指定すると古いgccコンパイル失敗することがあるみたいなので、関数全体を囲むようにしています。

normal: r64120 2018-07-30 17:05:22 +0900

r63754 で bootstraptest/runner.rb で pipe を使って子プロセスの終了を検出するようにした変更が BASERUBY で実行されるため新しめの IO#read_nonblock がない場合に動かないため r63757 で revert されてたのを、そのような環境では従来通り sleep による待ちを使うように対応してリトライしています。

shyouhei: r64121 2018-07-30 17:21:01 +0900

r64118 で追加したマクロ COMPILER_WARNING_IGNORED の定義部分で IGNORED のところが小文字になってしまっていたので修正しています。

shyouhei: r64122 2018-07-30 17:22:50 +0900

さらに r64118 で COMPILER_WARNING_ERROR() と COMPILER_WARNING_IGNORED() の引数の数に間違いがあったのも修正しています。

nobu: r64123 2018-07-30 17:45:19 +0900

thread_pthread.c で定数マクロ USE_NATIVE_SLEEP_COND の定義を削除しています。thread.c で既に定義されているから、とのことですが thread.c ではデフォルトで (0) に定義しているけどここは (1) なのでこれわざとだったんじゃないかな…。

normal: r64124 2018-07-30 18:54:41 +0900

r64117 のところで書いてたように native_thread_data_t::sleep_cond は GVL の操作用と SIGCHLD の独自実装のためのリスト操作用で使いまわされていてまぎらわしかったので、共用体として cond.intr と cond.gvlq と別の名前で参照するようにしています。また共用体が使えるのは glibcFreeBSD の時だけでその他の環境では別のメモリ上の実体を持つようにただのネストした構造体として宣言するようにしています。