メインコンテンツ

このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。

クリティカル セクション詳細 (-critical-section-begin -critical-section-end)

クリティカル セクションを開始、終了する関数の指定

説明

このオプションは、MATLAB® コードまたは Simulink® モデルから生成されたコードでは使用できません。

マルチタスキング コードを検証するとき、Polyspace® はクリティカル セクションがロック関数とロック解除関数の呼び出しの間に存在すると見なします。

lock();
/* Critical section code */
unlock();
クリティカル セクションのロック関数とロック解除関数の名前を指定します (たとえば、lock()unlock())。

オプションの設定

以下のいずれかの方法を使用してオプションを設定します。

  • Polyspace ユーザー インターフェイス (デスクトップ製品のみ): プロジェクト構成で [マルチタスキング] ノードを選択してから、このオプションの関数名を入力します。最初に有効にしなければならない他のオプションについては、依存関係を参照してください。

  • Polyspace Platform ユーザー インターフェイス (デスクトップ製品のみ): プロジェクト構成の [静的解析] タブで [マルチタスキング] ノードを選択してから、このオプションの関数名を入力します。最初に有効にしなければならない他のオプションについては、依存関係を参照してください。

  • コマンド ラインとオプション ファイル: -critical-section-begin オプションおよび -critical-section-end オプションを使用します。コマンド ライン情報を参照してください。

このオプションを使用する理由

タスク my_task がロック関数 my_lock を呼び出すと、my_lock を呼び出し中の他のタスクは my_task が対応するロック解除関数を呼び出すまで待たなくてはなりません。そのため、他のタスクのクリティカル セクション演算が、my_task のクリティカル セクション演算に割り込むことはできません。

たとえば、my_task1 および my_task2 の演算 var++ は互いに割り込むことはできません。

int var;

void my_task1() {
   my_lock();
   var++;
   my_unlock();
}

void my_task2() {
   my_lock();
   var++; 
   my_unlock();
}

自分の指定を使用して、ロック関数とロック解除関数の配置によってすべての共有変数が同時アクセスから保護されるかどうかが、Code Prover 検証によってチェックされます。これらの変数の値を決定する際、検証では、異なるタスクのクリティカル セクションは互いに割り込まないと見なされます。

Bug Finder 解析では、クリティカル セクションの情報を使用して、データ レースやデッドロックなどの同時実行の欠陥が調査されます。

設定

既定値なし

をクリックしてフィールドを追加します。

  • [開始ルーチン] にロック関数名を入力します。

  • [終了ルーチン] にロック解除関数名を入力します。

関数名を入力するか、一覧から選択します。

  • をクリックしてフィールドを追加し、関数名を入力します。

  • をクリックして、コード内の関数の一覧を表示します。その一覧から関数を選択します。

依存関係

デスクトップ製品のユーザー インターフェイスでこのオプションを有効にするには、最初にオプション [マルチタスクを手動で構成] を選択します。

ヒント

  • POSIX® 関数 pthread_mutex_lockpthread_mutex_unlock などのプリミティブ型を使用して、クリティカル セクションを開始および終了することもできます。Polyspace で自動的に検出できるプリミティブ型のリストについては、Polyspace でのスレッド作成とクリティカル セクションの自動検出を参照してください。

  • Polyspace はクリティカル セクションを開始および終了させる関数呼び出しの関数の引数を無視します。

    たとえば、Polyspace は以下の 2 つのコード セクションを同じクリティカル セクションとして扱います。

    開始ルーチン: my_lock
    終了ルーチン: my_unlock
    void my_task1() {
       my_lock(1);
       /* Critical section code */
       my_unlock(1);
    }
    void my_task2() {
       my_lock(2);
       /* Critical section code */
       my_unlock(2);
    }

    この制限の回避については、引数を取る関数によるクリティカル セクションの定義を参照してください。

  • クリティカル セクションを開始および終了する関数は、関数でなければなりません。たとえば、関数のようなマクロを次のように定義するとします。

    #define init() num_locks++
    このマクロ init() を使用して、クリティカル セクションを開始または終了することはできません。

  • クリティカル セクションを複数使用すると、以下のような問題に陥る可能性があります。

    • デッドロック:ロック関数を呼び出す順序によって 2 つのタスクが相互にブロックすることになる。

    • ダブル ロック:ロック関数がタスク内で 2 回呼び出され、その間にロック解除関数が呼び出されていない。

    このような問題を検出するには、Polyspace Bug Finder™ を使用します。同時実行の欠陥を参照してください。

    その後、Polyspace Code Prover™ を使用して、ロック関数とロック解除関数の配置によってすべての共有変数が実際に同時アクセスから保護されるかどうかをチェックします。グローバル変数 (Polyspace Code Prover)を参照してください。

  • 共有変数の取り得る値を判断する際、Code Prover 検証ではクリティカル セクションの指定が考慮されます。

    ただし、共有変数がポインターまたは配列の場合、本ソフトウェアでは、その変数が保護された共有グローバル変数かどうかを判断するためにのみ、この指定が使用されます。ランタイム エラーをチェックしている場合、本ソフトウェアではこの指定が考慮されず、その変数は同時にアクセスされる可能性があると見なされます。

コマンド ライン情報

パラメーター: -critical-section-begin | -critical-section-end
既定値なし
値: function1:cs1[,function2:cs2[,...]]
例 (Bug Finder): polyspace-bug_finder -sources file_name -critical-section-begin func_begin:cs1 -critical-section-end func_end:cs1
例 (Code Prover): polyspace-code-prover -sources file_name -critical-section-begin func_begin:cs1 -critical-section-end func_end:cs1
例 (Bug Finder Server): polyspace-bug_finder-server -sources file_name -critical-section-begin func_begin:cs1 -critical-section-end func_end:cs1
例 (Code Prover Server): polyspace-code-prover-server -sources file_name -critical-section-begin func_begin:cs1 -critical-section-end func_end:cs1