Der Provider profile stellt Prüfpunkte für zeitbasierte Interrupts zur Verfügung, die mit einem festgelegten, angegebenen Intervall ausgelöst werden. Diese nicht verankerten Prüfpunkte sind nicht mit einem bestimmten Punkt in der Ausführung, sondern mit dem asynchronen Interrupt-Ereignis verknüpft. Sie dienen zum Prüfen einiger Aspekte des Systemstatus im Abstand von bestimmten Zeiteinheiten. Auf Grundlage der Messdaten lassen sich Rückschlüsse auf das Systemverhalten ziehen. Bei einer hohen Prüfrate oder einer langen Prüfzeit sind genaue Rückschlüsse möglich. In Verbindung mit DTrace-Aktionen können mit dem Provider profile praktisch alle Aspekte des Systems geprüft werden. So könnten Sie beispielsweise den Zustand des aktuellen Threads, der CPU oder der aktuellen Maschinenanweisung prüfen.
Thread-lokale Variablen sind für Prüfpunkte aus dem Provider profile nicht erreichbar. Die Verwendung des speziellen Bezeichners self mit einem solchen Prüfpunkt zur Referenzierung einer thread-lokalen Variable generiert keine Ausgabe.
Ein profile-n-Prüfpunkt wird in einem festgelegten, regelmäßigen Abstand auf jeder CPU mit einer hohen Interrupt-Ebene ausgelöst. Das Auslösungsintervall des Prüfpunkts wird durch den Wert von n bestimmt: Die Interrupt-Quelle wird n-mal pro Sekunde ausgelöst. Sie können n auch ein optionales Zeitsuffix anfügen. In diesem Fall wird n in der mit dem Suffix angegebenen Zeiteinheit interpretiert. Tabelle 19–1 zeigt die gültigen Suffixe und die von ihnen bezeichneten Einheiten.
Tabelle 19–1 Gültige Zeitsuffixe
Suffix |
Zeiteinheit |
---|---|
nsec oder ns |
Nanosekunden |
usec oder us |
Mikrosekunden |
msec oder ms |
Millisekunden |
sec oder s |
Sekunden |
min oder m |
Minuten |
hour oder h |
Stunden |
day oder d |
Tage |
hz |
Hertz (Frequenz pro Sekunde) |
Das nächste Beispiel erzeugt einen Prüfpunkt, der den aktuell laufenden Prozess prüft und mit einer Frequenz von 97 Hertz ausgelöst wird:
#pragma D option quiet profile-97 /pid != 0/ { @proc[pid, execname] = count(); } END { printf("%-8s %-40s %s\n", "PID", "CMD", "COUNT"); printa("%-8d %-40s %@d\n", @proc); }
Wenn der obige Code kurz ausgeführt wird, erhalten wir eine ähnliche Ausgabe wie in folgendem Beispiel:
# dtrace -s ./prof.d ^C PID CMD COUNT 223887 sh 1 100360 httpd 1 100409 mibiisa 1 223887 uname 1 218848 sh 2 218984 adeptedit 2 100224 nscd 3 3 fsflush 4 2 pageout 6 100372 java 7 115279 xterm 7 100460 Xsun 7 100475 perfbar 9 223888 prstat 15 |
Mit dem profile-n-Provider lassen sich auch Informationen über den laufenden Prozess abrufen. Das folgende D-Beispielskript enthält einen profile-Prüfpunkt mit 1.001 Hertz, der zum Abrufen der aktuellen Priorität des angegebenen Prozesses dient:
profile-1001 /pid == $1/ { @proc[execname] = lquantize(curlwpsinfo->pr_pri, 0, 100, 10); }
Um das Beispielskript in Aktion zu sehen, geben Sie die folgenden Befehle in ein Fenster ein:
$ echo $$ 12345 $ while true ; do let i=0 ; done |
Führen Sie das D-Skript einen kurze Zeit lang in einem anderen Fenster aus. Dabei müssen Sie 12345 mit der PID ersetzen, die Ihr echo-Befehl zurückgegeben hat.
# dtrace -s ./profpri.d 12345 dtrace: script './profpri.d' matched 1 probe ^C ksh value ------------- Distribution ------------- count < 0 | 0 0 |@@@@@@@@@@@@@@@@@@@@@ 7443 10 |@@@@@@ 2235 20 |@@@@ 1679 30 |@@@ 1119 40 |@ 560 50 |@ 554 60 | 0 |
Diese Ausgabe zeigt die Verzerrung der Timesharing-Scheduling-Klasse. Da der Shell-Prozess auf der CPU in einer Warteschleife läuft, wird dessen Priorität vom System stetig herabgesetzt. Wenn der Shell-Prozess seltener laufen würde, käme ihm eine höhere Priorität zuteil. Das Ergebnis sehen Sie, wenn Sie in die wartende Shell Strg-C eingeben und das Skript erneut ausführen:
# dtrace -s ./profpri.d 494621 dtrace: script './profpri.d' matched 1 probe |
Geben Sie nun einige Zeichen in die Shell ein. Nach Beendigung des DTrace-Skripts erhalten Sie eine ähnliche Ausgabe wie in diesem Beispiel:
ksh value ------------- Distribution ------------- count 40 | 0 50 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 14 60 | 0 |
Da der Shell-Prozess nicht in einer Warteschleife auf der CPU gelaufen ist, sondern sich in Erwartung einer Benutzereingabe schlafen gelegt hatte, hat er, als er schließlich ausgeführt wurde, eine wesentlich höhere Priorität erhalten.
Wie profile-n-Prüfpunkte werden auch tick-n-Prüfpunkte in einem festgelegten Abstand und mit hoher Interrupt-Ebene ausgelöst. Im Gegensatz zu profile-n-Prüfpunkten, die auf jeder CPU ausgelöst werden, werden tick-n-Prüfpunkte jedoch pro Intervall nur auf einer CPU ausgelöst. Die CPU, um die es sich dabei handelt, kann sich im Lauf der Zeit ändern. Wie bei profile-n-Prüfpunkten wird n standardmäßig als Rate pro Sekunde interpretiert, kann aber auch durch ein optionales Suffix ergänzt werden. tick-n-Prüfpunkte dienen zu verschiedenen Zwecken, wie etwa regelmäßige Ausgaben zu liefern oder regelmäßige Aktionen durchzuführen.
Die Argumente für profile-Prüfpunkte lauten:
arg0 |
Der Programmzähler im Kernel zum Zeitpunkt der Prüfpunktauslösung, oder 0, wenn der aktuelle Prozess zum Zeitpunkt der Prüfpunktauslösung nicht im Kernel ausgeführt wurde |
arg1 |
Der Programmzähler im Prozess auf Benutzerebene zum Zeitpunkt der Prüfpunktauslösung, oder 0, wenn der aktuelle Prozess zum Zeitpunkt der Prüfpunktauslösung im Kernel ausgeführt wurde |
Wie aus den Beschreibungen hervorgeht, ist arg1 Null, wenn arg0 nicht Null ist, und umgekehrt ist arg1 nicht Null, wenn arg0 Null ist. Folglich können Sie mithilfe von arg0 und arg1 wie in diesem einfachen Beispiel zwischen Benutzer- und Kernelebene unterscheiden:
profile-1ms { @ticks[arg0 ? "kernel" : "user"] = count(); }
Der Provider profile stützt sich auf Intervall-Timer mit frei wählbarer Auflösung im Betriebssystem. Auf Architekturen, die keine wirklich auf arbiträren Intervallen beruhenden Interrupts unterstützen, ist die Frequenz durch den Systemuhrtakt begrenzt, die von der Kernelvariable hz vorgegeben ist. Prüfpunkte mit einer höheren Frequenz als hz werden auf diesen Architekturen mehrmals alle 1/hz Sekunden ausgelöst. Beispielsweise wird ein profile-Prüfpunkt mit 1000 Hertz auf einer solchen Architektur, auf der hz auf 100 gesetzt ist, alle zehn Millisekunden zehnmal schnell hintereinander ausgelöst. Auf einer Plattform, die arbiträre Auflösungen unterstützt, würde der profile-Prüfpunkt mit 1000 Hertz genau jede Millisekunde einmal ausgelöst werden.
Die Auflösung einer Architektur lässt sich wie folgt testen:
profile-5000 { /* * We divide by 1,000,000 to convert nanoseconds to milliseconds, and * then we take the value mod 10 to get the current millisecond within * a 10 millisecond window. On platforms that do not support truly * arbitrary resolution profile probes, all of the profile-5000 probes * will fire on roughly the same millisecond. On platforms that * support a truly arbitrary resolution, the probe firings will be * evenly distributed across the milliseconds. */ @ms = lquantize((timestamp / 1000000) % 10, 0, 10, 1); } tick-1sec /i++ >= 10/ { exit(0); }
Auf einer Architektur, die profile-Prüfpunkte mit arbiträrer Auflösung unterstützt, ergibt die Ausführung des Beispielskripts eine gleichmäßige Verteilung:
# dtrace -s ./restest.d dtrace: script './restest.d' matched 2 probes CPU ID FUNCTION:NAME 0 33631 :tick-1sec value ------------- Distribution ------------- count < 0 | 0 0 |@@@ 10760 1 |@@@@ 10842 2 |@@@@ 10861 3 |@@@ 10820 4 |@@@ 10819 5 |@@@ 10817 6 |@@@@ 10826 7 |@@@@ 10847 8 |@@@@ 10830 9 |@@@@ 10830 |
Auf einer Architektur, die profile-Prüfpunkte mit arbiträrer Auflösung nicht unterstützt, ergibt die Ausführung des Beispielskripts eine ungleichmäßige Verteilung:
# dtrace -s ./restest.d dtrace: script './restest.d' matched 2 probes CPU ID FUNCTION:NAME 0 28321 :tick-1sec value ------------- Distribution ------------- count 4 | 0 5 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 107864 6 | 424 7 | 255 8 | 496 9 | 0 |
Auf diesen Architekturen kann hz zur Verbesserung der effektiven Profilauflösung unter /etc/system manuell angepasst werden.
Derzeit unterstützen alle Varianten von UltraSPARC (sun4u) profile-Prüfpunkte mit arbiträrer Auflösung. Auch zahlreiche Varianten der x86-Architektur (i86pc) bieten Unterstützung für profile-Prüfpunkte mit frei wählbarer Auflösung, einige ältere Varianten jedoch nicht.
Im Gegensatz zu anderen Providern erzeugt der Provider profile die Prüfpunkte dynamisch auf Bedarfsbasis. Der gewünschte profile-Prüfpunkt scheint in einer Auflistung aller Prüfpunkte (z. B. mit dtrace -l -P profile) möglicherweise nicht auf, wird aber erzeugt, wenn er ausdrücklich aktiviert wird.
Auf Architekturen, die profile-Prüfpunkte mit frei wählbarer Auflösung unterstützen, würde die Maschine durch ein zu kurzes Intervall kontinuierlich zeitbasierte Interrupts abfangen und einen Denial-of-Service-Fehler auslösen. Um dies zu verhindern, lehnt der Provider profile kommentarlos die Erzeugung von Prüfpunkten ab, die ein Intervall von weniger als 200 Mikrosekunden bewirken würden.
Der Provider profile beschreibt die verschiedenen Stabilitäten anhand des DTrace-Stabilitätsmechanismus gemäß der folgenden Tabelle. Weitere Informationen zum Stabilitätsmechanismus finden Sie in Kapitel 39Stabilität.
Element |
Namensstabilität |
Datenstabilität |
Abhängigkeitsklasse |
---|---|---|---|
Provider |
Evolving |
Evolving |
Common |
Modul |
Unstable |
Unstable |
Unknown |
Funktion |
Private |
Private |
Unknown |
Name |
Evolving |
Evolving |
Common |
Argumente |
Evolving |
Evolving |
Common |