yarv-dev:629
From: SASADA Koichi <ko1 atdot.net>
Date: Fri, 30 Sep 2005 20:41:18 +0900
Subject: [yarv-dev:629] check interrupt timing
ささだです。
ジャイアントロックを用いたスレッドを実現したんですが、スケジューリング
その他をハンドリングするタイミングを考えています。
少しまとめますと、
1. timer 用スレッド
こいつはプロセスに一つ作る。時間がきたら VM の割り込みフラグを 1 にする。
2. ruby 用スレッド
こいつは Thread.new するたびに一つずつ作る。
実行するスレッドは VM が一つ持っているグローバルなロック(GVL: Global
VM Lock)を獲得して実行する。そのため、他のスレッドとの並列実行はしな
い。また、任意のタイミングでのスレッドの切り替えも行われない。
スレッドのスケジューリングは OS(ないし、スレッドライブラリ)に全て任
せる。VM レベルの実装は、GVL をいったん手放せばよい(実行待ちのスレッド
はロック獲得試行中なので、そのどれかにロックが渡され、そのどれかのスレッ
ドの実行が再開する)。
実際、コード量は大変少ない。
void
yarv_thraed_schedule()
{
if(GET_VM()->thread_critical == 0){
yarv_thread_t *th = GET_THREAD();
yarv_save_machine_context(th);
native_mutex_unlock(&GET_VM()->global_interpreter_lock);
native_mutex_lock(&GET_VM()->global_interpreter_lock);
yarv_set_current_running_thread(th);
}
}
(現在スケジューラにある大量の select 関係の処理がないからすっきりしただ
けかも)
各スレッドは実行中に VM の割り込みフラグを監視して、イベントがあったこ
とを察知した場合にスケジューリングをする(他のスレッドに CPU 実行権を渡
す)。
3. 見落とし?
「こういう場合どうするんだ」というネタがあれば教えてください。一応、今
の Ruby の仕様は十分満足できると思うのですが、インタプリタ + ネイティブ
スレッドで問題になりそうなケースがあれば、教えてください。
-------------------------------------------------------------------------
で、その監視のタイミングなのですが、rb_eval() (今の Ruby 評価機)では
node ごとにチェックしているが、チェックの間隔が短すぎるとオーバヘッドが
大きくなるし、長すぎる(もしくはチェックしないタイミングが任意に引き伸ば
せる)とスレッドスケジューリングが
現在はフレームを巻き戻すときにのみ行っています。
が、今後は
・PC を巻き戻すジャンプ(もしくは、ただ単にジャンプ)命令でチェック
・(ローカル変数への代入など)メソッド呼び出し以外の命令が閾値以上連続す
る場合にチェックするだけの命令を挿入
という対処をしようかなぁ、と思っています。
これに関して、何か知見のある方はいらっしゃいませんか。
--
SASADA Koichi at atdot dot net
--
ML: yarv-dev quickml.atdot.net
使い方: http://www.atdot.net/~ko1/quickml
-> 629 2005-09-30 20:41 [ko1 atdot.net ] check interrupt timing 630 2005-09-30 21:07 ┣[ko1 atdot.net ] 637 2005-10-02 11:26 ┗[shiro lava.net ] 639 2005-10-02 18:24 ┗[ko1 atdot.net ]