xv6から始めるSPIN入門	

           @oraccha
 2012-09-02 カーネル/VM勉強会
SPINって何?	
¤ sleep1.p ??	




                     本筋じゃなくてすいません。。。
SPINって何?	
¤ 並行システムのモデル検査ツール
   l ソフトウェアが「正しく」動くことを証明したり、
      反証を示すことが可能
   l テスト手法とは異なり、設計段階で使用
   l 例:通信プロトコルの状態遷移チェック、
      排他制御アルゴリズムの検証
¤ PromelaというC言語ライクなモデリング言語
¤ 1980年ごろからベル研で開発
¤ 現在、http://spinroot.com/から入手可能
SPINって何?	
                            SPIN:	
  Simple	
  Promela	
  Interpreter	
  
   モデル                      Promela:	
  Process	
  Meta	
  Language	
 (Promela)	
      SPIN	




                  pan.c	
                  C compiler	




spinpスクリプトは検証モードで動作:	
  
あらゆる状態遷移を生成し、所定の	
                       pan (protocol
                                           analyzer)	
性質を満たしているか検証
sleep1.p	
¤ 生産者・消費者問題を使った、排他制御の
  教材だと思われる
   l ロックを取得して、共有資源にアクセスする
   l テキスト “Sleep and wakeup” (P.55-57)
¤ 同じパターンはソースコード内に頻出
   l 例:bio.c, console.c, fs.c, log.c, pipe.c, proc.c
“Hello, world!”	

/* My first promela program. */
active proctype main() {
   printf(“Hello, world!n”);
}

$ spin hello.p !
      Hello, world!!
1 process created!
Promelaモデル	
¤ 変数
¤ プロセス
¤ メッセージチャネル
データ型、配列	
¤ 基本的にC言語と同じ
   l 例外:初期値は0かfalse
¤ スコープ
   l グローバル変数
   l プロセス内ローカル変数	

  # define N 2
                      #defineや#include文は内部でcppにより
  bit lk;             処理されるので、C言語同様に利用可能	
  

  byte value;
  bit sleeping[N]
プロセス	
¤ SPINは実行可能なプロセスをランダムに1つ
 選び、そこから1文を実行
 l 例外:atomicで囲まれた文は不可分に実行
¤ proctypeで定義し、activeでインスタンス化
¤ プロセスIDはローカル変数_pidで取得可能	


  active[N] proctype consumer() { ... }
  active[N] proctype producer() { ... }
inline文	
¤ C言語の関数に似ているが、あくまでマクロ
¤ Promela言語に関数は存在しない	
  inline acquire(x) {
        atomic { x == 0; x = 1 }
  }                                式は真になるまでブロック。	
  
                                   「x==0」は次のコードと等価	
  
                                   	
  
  inline release(x) {                   	
  while	
  (x	
  !=	
  0)	
  
                                        	
      	
  skip	
        assert x==1;
        x=0                  「;(セミコロン)」は、文の終端を示す
  }                          ものではなく、文の分割を意味する。
                             「-­‐>」も同じ意味	
  
assert文	
¤ assert(3)と同じで、不変条件の表明に使用
    l 偽だとエラー発生	

  inline acquire(x) {
        atomic { x == 0; x = 1 }
  }

  inline release(x) {
        assert x==1;
        x=0
  }
if式	
¤ 真のガード条件をランダムに1つ選んで実行
¤ 条件を満たすものがなければ待機	
inline sleep(cond, lk) {
      assert !sleeping[_pid];
      if
      :: cond ->
            skip     /* 何もしない文(Pythonのpassみたい) */
      :: else ->
            atomic { release(lk); sleeping[_pid] = 1 };
            sleeping[_pid] == 0;
            acquire(lk)
      fi
}
do式	
¤ 基本的にif式と同じだが、永久に評価を繰り返す
¤ break文で脱出	
inline wakeup()
{
      w = 0;
      do
      :: w < N ->
            sleeping[w] = 0;
            w=w+1
      :: else ->
            break
      od
}                         この例は、forループを書きたいときのイディオムかな
インストール for Mac OS X	
¤ Mountain Lion + Xcode command line tools
¤ spinroot.comからソースコードをダウンロード
 して、コンパイル
  l  makefileのCFLAGSに-DMACを追加
¤ 最新版はVersion 6.2.2

 $ ./spinp sleep1.p !
 ...snip...!
 State-vector 48 byte, depth reached 236,
 errors: 0!
 ...snip...!
デッドロック	
¤ ソースコード冒頭のコメントに従い、間違った
   ロックの使い方をするように改変すると、、、
¤ エラーが発生すると、各プロセスの実行トレー
   スを出力	

$ ./spinp sleep1.p !
...snip...!
State-vector 48 byte, depth reached 236,
errors: 5!
...snip...!
まとめ	
¤ モデル検査ツールSPINのPromela言語の
 ソースコードを読んでみた
 l 線形時間論理とかCSPとかわからなくても、
  とりあえず使うことはできる
¤ SPINはOS屋の嗜みの一つ
   l 通信プロトコルの設計などをする人は知って
      損はないようです
   l OSを形式手法を用いて検証するというのは、
      ここ数年のホットな話題らしいですよ

xv6から始めるSPIN入門