speculate
これ以降の節の部分については、指定したIDで識別される投機バッファをDTraceが使用するように切り替える特殊な関数。
void speculate(int)
speculate
関数は、DTraceが節の残りの部分に対して、指定されたidで指定された投機バッファを使用するようにする特殊な関数です。
投機を使用するには、speculation
から返された識別子を、データ記録関数の前に節でspeculate
関数に渡す必要があります。speculate
を含む節の後続のデータ記録関数は、すべて投機的にトレースされます。1つのDプローブ節でデータ記録関数の後にspeculate
がコールされた場合は、Dコンパイラでコンパイル時エラーが生成されます。したがって、節には投機トレース・リクエストのみ、またはそれ非投機トレース・リクエストのみを含めることができ、両方を含めることはできません。
集積関数、破壊的関数およびexit
関数は、投機的になりません。speculate
を含む節でこれらの関数のいずれかを実行しようとすると、コンパイル時エラーが発生します。また、speculate
はspeculate
の後には続きません。1つの節に許可される投機は1つのみです。speculate
しか含まない節は、有効なプローブIDのみをトレースするように定義されているデフォルトの関数を投機的にトレースします。
例7-44 投機の使用方法
次の例は、投機の使用方法を示しています。投機の正しい動作には、すべての投機関数が一緒に使用されている必要があります。
投機はsyscall::open:entry
プローブに対して作成して、投機のIDはスレッド・ローカル変数にアタッチします。open()
システム・コールの最初の引数は、printf
関数を使用して投機バッファにトレースされます。
syscall::open:return
プローブには、さらに3つの節が含まれています。それらの節の最初で、投機バッファにerrno
をトレースします。2番目の節の述語では、ゼロ以外のerrno
値をフィルタ処理して、投機バッファをコミットします。3番目の節の述語では、ゼロのerrno
値をフィルタ処理して、投機バッファを破棄します。
プログラムの出力は主データ・バッファに返されるため、open()
システム・コールが失敗すると、プログラムは実質的にファイル名とエラー番号を返します。このコールが失敗しない場合は、投機バッファにトレースされた情報が破棄されます。
syscall::open:entry
{
/*
* The call to speculation() creates a new speculation. If this fails,
* dtrace will generate an error message indicating the reason for
* the failed speculation(), but subsequent speculative tracing will be
* silently discarded.
*/
self->spec = speculation();
speculate(self->spec);
/*
* Because this printf() follows the speculate(), it is being
* speculatively traced; it will only appear in the primary data buffer if the
* speculation is subsequently committed.
*/
printf("%s", copyinstr(arg0));
}
syscall::open:return
/self->spec/
{
/*
* Trace the errno value into the speculation buffer.
*/
speculate(self->spec);
trace(errno);
}
syscall::open:return
/self->spec && errno != 0/
{
/*
* If errno is non-zero, commit the speculation.
*/
commit(self->spec);
self->spec = 0;
}
syscall::open:return
/self->spec && errno == 0/
{
/*
* If errno is not set, discard the speculation.
*/
discard(self->spec);
self->spec = 0;
}