スレッド対応

マルチスレッド対応のrefactor中。nmoshのスレッド対応はこれが3周め(multivm、id:higeponによるconcurrent、これ)。

  • スレッドの名前付け


スレッドに名前を付けられるようにする。↑のスクリーンショットでは、"Mosh VM1"のように名前が付いている。
実は殆どのプラットフォームではthreadに名前を付けることができる。(Win32: http://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx 、 pthread: http://stackoverflow.com/questions/2369738/can-i-set-the-name-of-a-thread-in-pthreads-linux )
ただ、この手のAPIには共通部分が少ないのが泣き所で、常識的なOSの共通集合を取ると"呼び出し元のスレッドの名前を設定"しか残らない。
スレッドの名前付けは負荷解析が必要になってしまった場合と、FFIしてきた関数が死ぬようなケースで有用。基本的にネイティブコード側のデバッガではScheme側のバックトレースなんて親切なものは出ないので。。
Win32のスレッドはアタッチする"前"に名前をつけないといけないようだ。。Win32ではいわゆるSEHを使ってデバッガに特殊なメッセージを送ることで実装している。

  • メインスレッドの特別扱い

↑のスクリーンショットにも有るように、Win32とMacにはメインスレッドとそうでないスレッドに明確な区別が有る。特にMacではUIスレッドをメインスレッドにするいい方法が無いので、メインスレッドに何を置くかが地味に重要になる。Win32でも、GDIオブジェクトは基本的にスレッドローカルなので、これらのプラットフォームではUIスレッドはメインスレッドの原則がある。
メインスレッドはグローバル変数theVMに格納されているVMインスタンスを実行しているスレッド と定義する。通常にシチュエーションでは、このVMmosh_init関数で作られる。

  • スレッド優先度/CPU affinityの操作

今回のrefactorの最大の目的は、スレッド優先度の処理。が、いわゆるpthreadプラットフォームではプロセス内で高優先度スレッドを作る良い方法が無い(= 高優先スレッドはroot権限が必要)。
Win32やMacでは高優先スレッドは通常のユーザでも作ることができる。Macの場合はMachのスレッドAPIを使ってプロセス内の任意のスレッドをリアルタイム優先度にできる。
LinuxBSDでは、予め設定しておく必要が有る。例えば、Linuxの場合ならrlimitとしてRLIMIT_RTPRIOが有り、これが非ゼロなら指定された最大値の幅で優先度を使うことが出来る。
CPUアフィニティはもっと難しい。nmoshが採用しているBoehmGCはParallel markを有効にしているならマルチスレッドでmarkするので、あるVMスレッドが動作するCPUを固定できない