プログラムのパフォーマンス解析

assert

assert は以下の構文を持っています。

assert side effect

mutex

acquired in 

func ...

assert side effect

rwlock [read]

acquired in 

func ...

assert side effect

lock

released in 

func ...

assert side effect

rwlock

upgraded in 

func ...

assert side effect

rwlock

downgraded in 

func ...

assert mutex|rwlock

protects 

 

var ...

assert mutex

protects 

 

func ...

assert rwlock

protects 

[reads in] 

func ...

assert order 

 

 

lock lock ...

assert read only 

 

 

var ...

assert rwlock

covers 

 

lock ...

これらのサブコマンドは、ロック lint に対して、チェックの対象となるアプリケーションにおいてロックおよび変数がどのようにアクセスおよび変更されることをプログラマが期待しているかを指示します。解析中には、そうしたアサーションの違反が報告されます。


注 -

1 つの変数について 2 回以上のアサートが行われている場合、最後の assert のみが有効となります。


assert side effect

副作用 (side effect) とは、ロックの状態が関数によって変化し、関数が制御を返す前に、その変化が復帰しないことを指します。関数にロックの副作用が含まれ、その副作用についてのアサーションが作成されていない場合、あるいは、実際の副作用がアサーションの内容と異なる場合、解析中に警告が発行されます。その後は、予期せぬ副作用はまったく起こらないものとして、解析は続行されます。


注 -

副作用には逆転と呼ばれる種類もあります。詳細については、 「ロックの逆転」、および「locks」または「funcs」サブコマンドを参照してください。


関数によってもたらされる副作用が呼び出しごとに異なる場合も (たとえば、条件付きの副作用など)、警告が発せられます。キーワード acquired inreleased inupgraded indowngraded in は、関数についてアサートされているロック副作用の種類を明らかにします。これらのキーワードは、スレッドライブラリインタフェース、DDI および DKI カーネルファンクションを介して利用が可能な副作用に対応しています (「mutex(3T)」、「rwlock(3T)」、「mutex(9F)」、「rwlock(9F)」を 参照)。

rwlocks に対する副作用のアサーションは、オプション引数 read を取ります。read が付いている場合、その副作用は、その関数がそのロックに対して読み取りレベルのアクセスを獲得することになります。read がない場合は、書き込みレベルのアクセスを獲得することになります。

assert mutex|rwlock protects

相互排他ロックが変数を保護しているとアサートした場合、相互排他ロックを保持せずにその変数がアクセスされた時点で必ずエラーとなります。読み取り書き込みロックが変数を保護しているとアサートした場合、読み取りアクセスに対するロックを保持せずにその変数を読み取ろうした時点、あるいは書き込みアクセスに対するロックを保持せずにその変数に書き込もうとした時点で必ずエラーとなります。どちらのロックが変数を保護しているかに関するその後のアサーションは、それ以前のアサーションを上書きします。つまり、解析中は、変数保護について、最後にアサートされたロックのみが常に使用されるということです。

assert mutex protects

相互排他ロックが関数を保護しているとアサートした場合、ロックを保持せずにその関数が呼び出された時点で必ずエラーとなります。ルート関数の場合、このアサーションが真である状態でルート関数が呼び出されたものとして、解析は実行されます。

assert rwlock protects

読み取り書き込みロックが関数を保護しているとアサートした場合、書き込みアクセスに対するロックを保持せずにその関数が呼び出された時点で必ずエラーとなります。読み取り書き込みロックが関数の読み取りを保護しているとアサートした場合、読み取りアクセスに対するロックを保持せずにその関数が呼び出された時点で必ずエラーとなります。ルート関数の場合、このアサーションが真である状態でルート関数が呼び出されたものとして、解析は実行されます。


注 -

単独の assert ... protects サブコマンドに対する違反が多すぎて、出力が大量になることを防ぐため、指定されたアサーションの違反は最大 20 まで提示されます。この制限は、assert order サブコマンドには適用されません。


assert order

ロックがどのような順番で獲得されるべきかを、ロック lint に知らせます。見慣れたロックの順序を守っていれば、プログラムにデッドロックは起こらないと、ロック lint は想定します。このサブコマンドを使って、ロック lint にあらかじめ定めた順序を理解させ、その結果、解析中にその順序の違反が見つかると出力されます。

assert read only

特定の変数に対して、アプリケーションは絶対に書き込みを行ってはいけないというアサーションを作成します。ロック lint は、そうした変数に対する書き込みを報告します。変数が書き込み禁止ではない限り、ロックが保持されていない状態で、変数の読み取りが行われると、エラーが発行されます。これは、ロック lint が、ほかのスレッドが同時にその変数へ書き込みを行う心配があると想定しているためです。

assert rwlock covers

ロック lint に、階層的なロック関係が存在することを知らせます。特定の状況におけるパフォーマンスを改善するため、読み取り書き込みロックは、ほかのロック (相互排他あるいは読み取り書き込み) と組み合わせて使用されることがあります。