[タスク内のイベント呼出し] レポート
[タスク内のイベント呼出し] レポートは [タスク間のイベントの遷移] レポートと同様に、マルチタスク・システムにおいて、同期イベントの使用を確認するために利用します。
イベントメカニズムは C / C++ プログラムで明示されないため、両レポートでは最初にイベントメカニズムを特定する必要があります。イベント関数およびイベントそのものは、[イベント定義] ダイアログで指定します。このイベントとは、イベント間の情報伝達に使用されるオペレーティング・システムの共有リソースに対する、ソースコード・レベルの識別子(マクロ、列挙リテラル、定数変数)です。一方イベント関数は、オペレーティング・システム固有の関数であり、イベントの待機(pend)、イベントの通知(現在のタスクに共有リソースへのアクセスを提供)、イベントのクリア(すべてのタスクを再び待機状態とするため、利用可能なあらゆる通知を削除)するために使用されます。クリアのイベント関数は、通知のイベント関数の変種とみなされ、特殊なパラメータ値によって通知ではなくクリアの実行が命令されます。
以下に、taskX が taskY に動作を開始する準備が整ったことを合図する、簡単な例をあげます。
#define EVENTA 1
extern void PostEvent(int event);
extern void WaitEvent(int event);
void taskX() {
// 割り込みで開始、関連項目をセットアップ
PostEvent(EVENTA);
}
void taskY() {
while (1) {
WaitEvent(EVENTA);
// 続いて動作を開始
}
}
|
[タスク内のイベント呼出し] レポートでは、イベント関数への呼び出しを実行したタスクを表示します。これらのイベント関数は、イベント識別子によってまとめられます。この情報を使用することで、各イベントが一連の適切なタスクを同期するために使用されていること、またイベントの通知に過不足がないことを確認することが可能です。
Event Calls in Tasks
Key:
P: task posts this event
W: task waits for this event
C: task clears this event
Settings:
Wait event function: WaitEvent
Post event function: PostEvent
Number of events defined: 1
Task Definitions
Tasks are from User Defined Tasks
Name Members Graph Root
taskX 2 [+] taskX
taskY 2 [+] taskY
Event File
Task
Line Number of Usage
Action
User of Event
EVENTA events_simple.c
taskX
8 P taskX
taskY
13 W taskY
|
以下に、より複雑な例を示します。ここでは合図を行うためタスクをいくつか呼び出し、複数のイベントを使用しています。また、この例では、データフロー解析による値の伝播および式の解釈に関するサポート方法も示しており、同時にある特殊なケースのイベントが通知されます。
// イベント
#define EVENT1 1
#define EVENT2 2
#define EVENT3 4
#define EVENT4 8
void PostEvent(int event, int mode);
void WaitEvent(int event);
#define POSTMODE 1 // 通常の通知
#define OS_FLAG_CLR 2 // 通知済みのイベントのクリア
void task1() {
PostEvent(EVENT1, POSTMODE);
// OS_FLAG_CLR のため無視
PostEvent(~(EVENT4|EVENT2), OS_FLAG_CLR);
}
void task2() {
WaitEvent(EVENT1);
}
void task3_f1(int p) {
int event;
if (p == 13) event = EVENT2;
else event = EVENT4;
if (p) {
PostEvent(event, POSTMODE); // 直接代入のローカル var
} else {
WaitEvent(EVENT3);
}
}
void task3() {
int b = 2;
if (b)
while (b--)
task3_f1(b);
WaitEvent(EVENT2);
}
// より複雑なイベントの式
int pevents = ~0;
void task4() {
if (pevents & EVENT4)
pevents &= ~EVENT1;
else
pevents &= ~(EVENT1 | EVENT3);
PostEvent(pevents, POSTMODE);
int wevents = EVENT1 | EVENT3 | EVENT4;
if (pevents)
wevents &= ~EVENT1;
WaitEvent(wevents);
}
#define MULTI_EVENT1 (EVENT1 | EVENT3)
#define MULTI_EVENT2 (MULTI_EVENT1 | EVENT2)
void task5() {
int c = 3;
int event = EVENT4;
if (c == 13) event |= MULTI_EVENT1;
if (c) {
PostEvent(event, POSTMODE); // 式をともなうローカル変数
}else {
WaitEvent(MULTI_EVENT2);
}
}
// イベントの式で使用する配列
static const int execDefaultCallbackEvents[] =
{ // タスク id によるインデックスは、"tasks.h" で定義されたタスク id に必ず対応しする必要があります
EVENT1, // SUPERVISOR タスク - デフォルトのコールバック・イベント
NULL, // DISK タスク - 無し
NULL, // XFER タスク - 無し
NULL, // HOST タスク - 無し
NULL, // EXEC タスク - 無し
EVENT4 // BACKGROUND タスク - デフォルトのコールバック・イベント
};
void task6() {
int taskid = 0;
WaitEvent(execDefaultCallbackEvents[taskid]);
};
|
次の例で生成されるレポートは、複雑な式でイベントの使用を解決する、タスク間の情報伝達におけるイベントの使用を、すべて追跡します。
Event Calls in Tasks
Key:
P: task posts this event
W: task waits for this event
C: task clears this event
Settings:
Post event function: PostEvent
Wait event function: WaitEvent
Number of events defined: 4
Task Definitions
Tasks are from User Defined Tasks
Name Members Graph Root
Task1 2 [+] task1
Task2 2 [+] task2
Task3 4 [+] task3
Task4 3 [+] task4
Task5 3 [+] task5
Task6 2 [+] task6
Event File
Task
Line Number of Usage
Action
User of Event
EVENT1 events_comm.c
Task1
17 P task1
Task2
23 W task2
Task5
67 P task5
69 W task5
Task6
85 W task6
EVENT2 events_comm.c
Task1
19 P task1
Task3
42 W task3
31 P task3_f1
Task4
52 P task4
Task5
69 W task5
EVENT3 events_comm.c
Task3
33 W task3_f1
Task4
56 W task4
Task5
67 P task5
69 W task5
EVENT4 events_comm.c
Task1
19 P task1
Task3
31 P task3_f1
Task4
52 P task4
56 W task4
Task5
67 P task5
Task6
85 W task6
|
|