- 1 名前:名無しさん@お腹いっぱい。 mailto:sage [04/06/29 22:31]
- dragonfly bsd どうよ
なんか面白そうだが。
- 115 名前:名無しさん@お腹いっぱい。 mailto:sage [04/08/11 22:28]
- 軽量カーネルスレッドモデル
DragonFlyはその中核部分に軽量カーネルスレッド(LWKT)を用います。 システムのプロセスは全てスレッドと結びついていて、カーネルのみの プロセスのほとんどは事実上純粋なスレッドです。たとえば、pageout デーモンは純粋なスレッドでプロセスコンテクストを持ちません。 LWKTモデルはアーキテクチャによらないいくつかの鍵となる特徴があります。 これらの特徴はCPU間の競合を除く、あるいは減らすために設計されています。 1.システムの各CPUは自己完結のLWKTスケジューラを持ちます。スレッドは意図的に CPUに結びついていて、いくつかの特殊な状況下でのみ他のCPUへ移動することが できます。特定のCPU上のLWKTスケジューリング処理はそのCPU上でのみ直接 実行されます。これは、LWKTスケジューラ本体がスケジュール追加、除去、 CPU内でのスレッド間スイッチを、ロックを一切せずに処理できるということです。 単純なクリティカルセクションの除いてはMPロックもなにもなしにです。 2. スレッドはカーネルで動作中は他のCPUにプリエンプティブに移動されることは ありません。スレッドはブロックされている間はCPU間を移動しません。 ユーザランドスケジューラはユーザモードで実行しているスレッドを移動できます。 スレッドは非割り込みスレッドへプリエンプティブにスイッチすることは ありません(この間FreeBSD初心者スレで出た話題のやつね)。割り込みスレッドが カレントスレッドをプリエンプトする場合、割り込みスレッドが終了または ブロックした時点でプリエンプトされた方のスレッドはスケジュール状態によらず 復元されます。たとえば、あるスレッドはlwkt_deschedule_self()を呼んだあと、 実際に(別のスレッドへ)スイッチする前にプリエンプトされる可能性があります。 これは問題ありません。なぜなら割り込みスレッドが完了またはブロックしたあと そのスレッドに直接制御が戻るからです。
- 116 名前:名無しさん@お腹いっぱい。 mailto:sage [04/08/11 22:51]
- 3. 上の(2)により、スレッドはCPUごとのglobaldata構造体を通じて得た
情報をロックなしにキャッシュすることができます。また、その情報が 割り込みスレッドによって変更されないと分かっている場合は、 クリティカルセクションに入る必要がありません。これによって、 いろいろな種類のデータのCPUごとのキャッシュ(訳注: 「の」の連続だ) を、事実上オーバヘッドなしに持つことができます。 4. あるCPUが他のCPUに属するスレッドをスケジュールしようとする場合は、 ターゲットCPUにIPIベースのメッセージを発行して、処理を実行します。 このメッセージはデフォルトで非同期で、このためIPIはレイテンシを 伴うことがありますが必ずしもCPUサイクルを浪費するとは限りません。 このIPIの処理はクリティカルセクションに入ったスレッドによってブロック されます。実際、LWKTスケジューラはそうします。クリティカルセクションの 出入りは安価な処理と考えられるので、ロックやバスロック命令を必要と しません。 5. IPIメッセージサブシステムはFIFOあふれによるデッドロックに対し、 送信キューの停滞が解消するのを待つ間、受信キューをスピンして処理する ことで対処します。IPIメッセージサブシステムはこのような状況下で 特にスレッドのスイッチを行いません。これによって、まれにスピンが 発生する場合があってもソフトウェアはこれをノンブロッキングAPIのように 扱うことができます。
- 117 名前:名無しさん@お腹いっぱい。 mailto:sage [04/08/11 22:59]
- これらの鍵となる特徴に加え、LWKTモデルでは高速割込みプリエンプション
とスレッド割込みプリエンプションを両立します。高速割り込みはカレント スレッドがクリティカルセクションに入っていない場合はプリエンプトできます。 スレッド割込みもカレントスレッドをプリエンプトできます。LWKTシステムは、 スレッド割込みにスイッチしたあとそれがブロックまたは完了した場合に もとのスレッドに戻ります。IPI関数は高速割り込みと非常に似たやり方で 動作し、同じくtrapframe機能を持ちます。これはDragonFlyのSYSTIMERS APIで hardclock()やstatclock()の割込みを全てのCPUに分配するために多く用いられて います。
- 118 名前:名無しさん@お腹いっぱい。 mailto:sage [04/08/11 23:15]
- IPIメッセージサブシステム
LWKTモデルはCPU間通信のための非同期メッセージシステムを実装します。 基本的には、関数ポインタとデータ引数を引数として関数を呼び出すと ターゲットCPUにそれを渡り、ターゲットCPUはそれを非同期に実行します。 これは非同期モデルなので呼び側は同期完了を待ちません。このため性能が 非常に向上し、ターゲットCPUへのオーバヘッドもおおまかには割り込み と同等程度です。 IPIメッセージは高速割り込みのように動作します...つまり(クリティカル セクションに左右されますが)ターゲットCPUで動いているものは何でも プリエンプトし、実行し、そのあともともと動いていたものに復帰します。 このためIPI関数はいかなる理由であってもブロックすることは許されません。 IPIメッセージはスレッドをスケジュールしたり他のCPUに属しているメモリを 解放するといった処理をするのに用いられます。 IPIメッセージ処理は少なくとも6個の主なLWKTサブシステムで多用されています。 それらには、CPUごとのスレッドスケジューラ、slab allocator、メッセージ サブシステムが含まれています。IPIメッセージ処理はDragonFlyに本来的に 適応したサブシステムなので、Big Giant Lockを必要とせず、使用してもいません。 全てのIPIベースの関数は従ってMPセーフである必要があります(そうなっています)。
- 119 名前:名無しさん@お腹いっぱい。 mailto:sage [04/08/12 09:25]
- これって、ひとつの資源に対して単一のCPU&スレッドを張り付けることで、排他制御をシンプルにする
というおおざっぱな理解であってる? スレッド切替が頻繁に発生してパフォーマンスで劣るんじゃないかとか、 スレッドの優先度制御をどうするかとか、いろいろ問題もありそうだけど、 おらワクワクしてきたぞ。
- 120 名前:名無しさん@お腹いっぱい。 mailto:sage [04/08/12 12:25]
- IPIベースのCPU同期サブシステム
LWKTモデルは、汎用でマシンに依存しないCPU同期APIが備わっています。 このAPIによって、デリケートなデータ構造にアクセスしている状態の ターゲットCPUを既知の状態に移行させることができます。このインタフェイスは 主にMMUのページテーブルを更新するのに使用されています。たとえば、 もし適切なロックを確保していたとしても、ページテーブルエントリの モディファイビットをテスト、クリアしたあとにページテーブルエントリを 削除するのは安全ではありません。これは、他のCPUで動作しているユーザランド プロセスがそのページを読み書きする可能性があるからで、その場合向こう側のCPUが TLBを書き戻すのとページテーブルエントリをクリアしようとする処理の間に レース状態が生じます。適切な解決は、ページテーブルエントリへ書き戻す 可能性のあるCPU(つまりpmapのpm_activeマスクでセットされている全CPU)を まず既知の状態に移行し、変更処理をしてから、各CPUのTLBを無効化するリクエストに よってCPUを解放するという方法です。 DragonFlyに備わっているAPIにはデッドロックがありません。複数のCPU同期処理が 並行に動作することが可能で、これはCPU同期イベントの主導権を握っているスレッド にもあてはまります。これは柔軟なしくみですが、CPU同期インタフェイスは制御 された環境で動作するため、コールバック関数はIPIメッセージサブシステムで 用いられるものとちょうど同じように動作する傾向にあります。
- 121 名前:名無しさん@お腹いっぱい。 mailto:sage えっちねた板の連貼りみたいだ [04/08/12 14:21]
- 同期トークン
同期トークンはいくつものスレッドが同時につかめます。トークンをつかんでいる スレッドは、同一のトークンをつかんでいる他のスレッドが同時には実行しない ことが保証されます。 一つのスレッドは同期トークンをいくつでもつかむことができます。 あるスレッドは、イールドまたはブロック条件を通じて同期トークンを つかむことがありますが、そのスレッドが(ブロックあるいはイールドされて) 実行中でない間、それらのトークンをつかんでいる他のスレッドが実行する 可能性があることを考慮に入れる必要があります。 理論上、同期トークンの機構から起きるデッドロック状態で解決できないものは ありません。しかし、初期の実装ではトークンを同時につかんだ場合にライブロック の問題が起きる可能性があります。 同期トークンは、同一のトークンをつかもうとする割り込みが他のスレッドを プリエンプトしてしまうことから保護するのにも使われます。これはBig Giant Lock (BGL; MPロックともいう)とは若干違った作用があります。BGLは同一CPUの割り込みを インターロックすることはありません。重要なことは、プリエンプションによって 一時的に他のスレッドへのスイッチが起きることがあるとしても、トークンの原子性 (?atomicity)プリエンプティブ条件によって維持されるということです。トークンの 原子性(?atomicity)を維持するためにspl()レベルやクリティカルセクションに入る 必要はありません。 同期トークンはプリエンプティブは割り込みが起きるのをさまたげることはありません が、割込みをブロックして再スケジュールさせることがあります。スレッド化されて いない高速割り込みやIPIメッセージング割り込みはトークンをつかうことが できません。それは処理に必要なスレッドコンテキストを持っていないからです。 そのかわり、これらのサブシステムはクリティカルセクションを使うことで 排他制御をします。
|

|