#!/usr/sbin/dtrace -s
#pragma D option quiet
syscall::read:entry
{
self->time = timestamp;
}
syscall::read:return
{
@time[execname] = sum(timestamp - self->time);
}
dtrace:::END
{
printa(@bytes);
}
リスト2では、readシステムコールのentryプローブとreturnプローブを処理している。
entryプローブでは、timestamp変数を使って現在のタイムスタンプを取得するビルドイン変数であり、ナノ秒単位での値を保持している。entryプローブの処理では、次のように「self->time」という書式を指定している点に注目しよう。
self->time = timestamp;
「self->」という書式は、「スレッドローカルな変数」を示すものだ。プローブは異なるスレッドで同時に呼び出される可能性があるが、「self->変数名」という書式を使うと(ここでは変数名としてtimeという名前を用いたが、これは任意名でよい)、スレッドごとに別々の変数が用意されるため、値が混じらなくなる。
なお、Dスクリプトでは、「self->変数名」と似た書式として「this->変数名」という書式も用意されている。「this->変数名」はブロック内でのみ有効な一時的な変数(C言語で言うところの自動変数。Perlで言えば、My)だ。
さて、returnプローブでは、次のように現在のタイムスタンプ値から、先にentryプローブで保存しておいたタイムスタンプ値を引いたものの総和を採っている。
@time[execname] = sum(timestamp - self->time);
これにより、entryからreturnまでの所要時間――readシステムコールが呼び出し終わるまで――の合計を求められるという仕組みだ。
実際に実行すると、次のように、コマンドごとにファイルの読み込みに要した時間総計がナノ秒単位で表示される(表示される内容は環境によって異なる)。
# dtrace -s filereadtime.d
^C
cat 36265
ttymon 40936
dtscreen 173114
dtwm 217419
utmpd 354749
sac 847370
sdtperfmeter 1419325
java 4769073
Xorg 6133046
more 973867805
tcsh 16200305646
dtfile 30029429139
sh 659094214480122
Copyright © ITmedia, Inc. All Rights Reserved.