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

ロック lint の制限事項

ロック lint の解析力にも限界はあります。こうした限界の最大の要因は、ロック lint がユーザーの変数の値を知らないという現実にあります。

ロック lint は、ありがちな原因を無視したり、想定を単純化することで、さまざまな種類の問題を解決します。その他の問題も、アプリケーションの中で条件付きでコンパイルされたコードを使用することで回避できます。-Zll オプションを使ってコンパイルを行うと、コンパイラはつねにプリプロセッサマクロ __lock_lint を定義します。このマクロを利用することで、コードがあいまいになることをかなり回避できます。

ロック lint は以下の問題についての推論ができません。

その他のロック lint の問題点には以下のものがあります。

解析中、ロック lint は rw_upgrade と呼ばれるロック操作についてのメッセージを生成する場合もあります。そうした呼び出しは現実には存在しませんが、ロック lint は以下のようなコードをその次のコードのように書き直します。


if (rw_tryupgrade(&lock1)) {  ...  }


if () { rw_tryupgrade(&lock1);	... }

rw_tryupgrade() が起こる場所では、ロック lint は常にそれが成功しているものとみなします。

すでに保持されているロックを獲得しようとした場合、ロック lint はエラーとしてフラグを立てます。しかし、ロックに名前未定の場合 (たとえば、foo::lock)、この名前は単独のロックではなく、一連のロックを参照するため、こうしたエラーは抑制されます。しかし、名前未定のロックが常に同じロックを参照する場合は、ロック lint がこの種の潜在的デッドロックを報告できるように、declare one サブコマンドを使ってください。

これらのロックから独自のロックを構築した場合 (たとえば、再帰的な相互排他はときに通常の相互排他から構築されます)、ロック lint はそれらについて知ることはありません。一般的には、#ifdef を使って、通常の相互排他が操作されているかのようにロック lint に提示します。名前未定のロックが再帰的にロックされても、エラーが生成されることはないので、再帰的なロックに対しては、名前未定のロックを使用してください。以下に例を示します。


void get_lock() {
    #ifdef __lock_lint.  
        struct bogus *p;
        pthread_mutex_lock(p->lock);
    #else
        <the real recursive locking code>
    #endif
}