[複数のタスクでセットされる変数] レポート
[複数のタスクでセットされる変数] は、マルチタスク・ソフトウェアにおけるグローバル変数および静的変数の使用方法をレポートします。本レポートは高度な設定が可能のため、さまざまな状況に合わせてレポートをフィルタリングすることが可能です。
例えば、タスクを超えて設定される変数を、レポートでチェックすることができます。そのような変数への代入によって、それらの変数を使用するタスクがクリティカルな領域で保護されていない場合に予期せぬ動作が発生し、それが不具合を引き起こす可能性があるのです。本レポートでは、この他に5つの特定の状況をサポートしています。また、非ローカル変数のあらゆる使用方法をレポートしたり、各変数の使用をレビューしたりすることもできます。例として次のコードを示します。
int globalA, globalB, globalC;
int subX(int paramX) {
globalB = paramX;
/* some calculations */
paramX = globalB;
return paramX;
}
void taskX() {
int localX = 1;
globalA = localX;
/* some calculations */
localX = globalA;
DisableInt();
localX = subX(localX);
EnableInt();
globalC = localX;
}
void taskY() {
int localY = 1;
globalA = localY;
DisableInt();
globalB = localY;
EnableInt();
localY = globalC;
}
|
セマフォ、あるいは割り込み制御関数(この例では DisableInt や EnableInt)を使用しクリティカルな領域を保護することで、グローバル変数値の書き換えという、他のタスクからの予期しない干渉を防止します。例えば、subX で読み取られる globalB の値は、subX が taskX の DisableInt によって保護されるため、先に subX で globalB に代入された値と同じになります。その結果、taskY による割り込みにより、subX の globalB の設定と読み取りの間で発生する計算の実行中に globalB の値が変更されることはありません。
これに対して、taskX における globalA への設定および、その後の読み取りは保護されません。設定と読み取りの間で taskY による割り込みが発生した場合には、globalA の値が修正され、taskX の所定の動作に干渉します。
[複数のタスクでセットされる変数] レポートでは、クリティカルな領域における変数の代入の有無に関する解析を行い、その情報をディスプレイに表示します。保護されている変数の使用を、フィルタリングで除外することも可能です。この場合は、保護されている変数の集合と、保護されていない変数の集合の両方が表示されます。指定された用法でのアクセス状況は、U(非保護)もしくは P(保護)によって示されます。保護されたアクセスについては、クリティカルな領域の名前が明示されます。以下の例では、1つのクリティカルな領域が [クリティカルセクションの定義] ダイアログで定義され、int という名前が付けられています。
Variables Set in Multiple Tasks
Settings:
Critical Region: int ( DisableInt / EnableInt )
Usage Type: set in multiple tasks
Protected Variables: displayed
Unprotected Variables: displayed
Global Variables: displayed
Static Variables: displayed
Struct Container Summary: omitted
Union/Bitfield Members: separate
Combined Usage Listing: on
Task Definitions
Tasks are from User Defined Tasks
Name Members Graph Root
TaskX 4 [+] taskX
TaskY 3 [+] taskY
Variable File (Line)
Task
Line Number of Usage
Critical Region
User of Variable
globalA multi_set_vars.c (2)
TaskX
13 U (int) taskX multi_set_vars.c (11)
TaskY
24 U (int) taskY multi_set_vars.c (22)
globalB multi_set_vars.c (2)
TaskX
5 P (int) subX multi_set_vars.c (4)
TaskY
26 P (int) taskY multi_set_vars.c (22)
|
本レポートにおける変数の使用方法の設定はこの他に、少なくとも1つのタスクで使用される(設定あるいは読み取られる)変数の特定があります。保護された使用のリスト化を省略すると、レポート結果はクリティカルな領域の保護の外部における、変数の使用に焦点が置かれます。これらの使用方法は、個別のレビューに相当することがあります。
Variables Used in Tasks
Settings:
Critical Region: int ( DisableInt / EnableInt )
Usage Type: set or read in at least one task
Protected Variables: omitted
Unprotected Variables: displayed
Global Variables: displayed
Static Variables: displayed
Struct Container Summary: omitted
Union/Bitfield Members: separate
Combined Usage Listing: on
Task Definitions
Tasks are from User Defined Tasks
Name Members Graph Root
TaskX 4 [+] taskX
TaskY 3 [+] taskY
Variable File (Line)
Task
Usage Type
Line Number of Usage
Critical Region
User of Variable
globalA multi_set_vars.c (2)
TaskX
S 13 U (int) taskX multi_set_vars.c (11)
R 15 U (int) taskX multi_set_vars.c (11)
TaskY
S 24 U (int) taskY multi_set_vars.c (22)
globalC multi_set_vars.c (2)
TaskX
S 19 U (int) taskX multi_set_vars.c (11)
TaskY
R 28 U (int) taskY multi_set_vars.c (22)
|
セットと読み取りの両方が解析されると、アクセスに関する使用タイプの情報が、レポートに追加されます。アクセスのタイプはS(セット)あるいはR(読み取り)によって示されます。globalC などその他の変数は、あるタスクでのみ設定され、別のタスクで読み取られる場合にリスト表示されます。
集約変数は、C / C++ の構造体と共用体、および C++ のクラスで構成されます。このレポート、ならびにこれ以外の一部のレポートには、集約変数のレポート方法を調整するオプションが用意されています。レポートで Container Summary を有効にすると、これらの集約変数のメンバはコンテナ変数の要約に使用されます。例えば、構造体の1つのメンバが1つのタスクに割り当てられ、同じ構造体の別のメンバが、別のタスクに割り当てられた場合、各メンバは [複数のタスクでセットされる変数] レポートには表示されませんが、構造体変数には表示されるのです。
一方で配列は、インデックスが動的に表現されることから、通常は割り当てられている配列要素を識別することができないため、これらのレポートでは配列全体を単一の変数と見なします。
静的な解析が可能な範囲で、Imagix 4D はポインタに参照されるオブジェクトを追跡します。ポインタもしくは参照パラメータは、実際のパラメータ変数を追跡し、潜在的な変更を特定します。配列を介して配列に設定されたり、インデックスに使用されたりするポインタによって、配列は変更されます。Imagix 4D では、ポインタを「クリーン」に使用することが想定されています。この場合、ポインタは特定の変数に設定され、その変数でのみ機能し、隣接するメモリ領域に割り当てられている個々の変数に副次的にアクセスすることはありません。
|