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

全ロックの解放の確認

assert(NO_LOCKS_HELD);

このアサーションによって、コードのこのポイントに到達したなら、このテストを実行するスレッドによってロックは保持されるべきでないと、ロック lint は認識します。このアサーションに対する違反は、解析中に報告されます。ブロックを行うルーチンは、スレッドがブロックまたは終了するときには、保持されるロックがないように、このようなアサーションを使用できます。

また、このアサーションには、獲得されたいかなるロックもその位置では必ず解放させることを、コードを修正しようとする第三者に思い出させる働きもあります。

唯一必要なことは、このアサーションを、ブロックするリーフレベルの関数で使用することです。ブロックするほかの関数を呼び出すためだけに、呼び出す側の関数がブロックするのであれば、呼び出される側の関数のみにアサーションを含めておくだけで呼び出す側に含める必要はありません。そのため、このアサーションは、特にロック lint 用に記述されたライブラリのバージョン (lint ライブラリのように) において (libc など) もっとも頻繁に出現することになるでしょう。

ファイル synch.h は、まだ別途定義されていない場合は、NO_LOCKS_HELD を 1 と定義し、このアサーションが適合するようにします。つまり、実行時にはアサーションは効果的に無視されます。note.h または synch.h のいずれかをインクルードする前に (順番はどちらが先でもかまいません)、NO_LOCKS_HELD を定義することによって、デフォルトの実行時の状態を上書きできます。たとえば、コードの本体に a と b と呼ばれる 2 つのロックだけが使用されている場合は、以下の定義で十分でしょう。


#define NO_LOCKS_HELD (!MUTEX_HELD(&a) && !MUTEX_HELD(&b))
#include <note.h>
#include <synch.h>

このようにしても、ロック lint によるアサーションのテストに影響はありません。ほかのロックが保持されていれば (a と b だけでなく)、ロック lint はその件について報告を行います。