diff options
author | William Cohen <wcohen@redhat.com> | 2008-11-19 20:27:28 -0500 |
---|---|---|
committer | William Cohen <wcohen@redhat.com> | 2008-11-19 20:27:28 -0500 |
commit | a006b96108a8b92b73af5ddb396cb1b1119f5529 (patch) | |
tree | a4d14055400a0ff012c45cac54bb1192ed0e716d /doc/SystemTap_Beginners_Guide/en-US/Array-Operations.xml | |
parent | 64db9629ddd2604cad4dc00086e028205fde46a5 (diff) | |
parent | c59943f6936e93819978d5149500ca217d09667a (diff) | |
download | systemtap-steved-a006b96108a8b92b73af5ddb396cb1b1119f5529.tar.gz systemtap-steved-a006b96108a8b92b73af5ddb396cb1b1119f5529.tar.xz systemtap-steved-a006b96108a8b92b73af5ddb396cb1b1119f5529.zip |
Merge branch 'master' of ssh://sources.redhat.com/git/systemtap
Diffstat (limited to 'doc/SystemTap_Beginners_Guide/en-US/Array-Operations.xml')
-rw-r--r-- | doc/SystemTap_Beginners_Guide/en-US/Array-Operations.xml | 81 |
1 files changed, 60 insertions, 21 deletions
diff --git a/doc/SystemTap_Beginners_Guide/en-US/Array-Operations.xml b/doc/SystemTap_Beginners_Guide/en-US/Array-Operations.xml index f63d1d70..4aef21f4 100644 --- a/doc/SystemTap_Beginners_Guide/en-US/Array-Operations.xml +++ b/doc/SystemTap_Beginners_Guide/en-US/Array-Operations.xml @@ -20,13 +20,13 @@ <example id="arrays-timestampprocessname"> <title>Associating Timestamps to Process Names</title> <programlisting> -foo[execname()] = gettimeofday_s() +foo[tid()] = gettimeofday_s() </programlisting> </example> -<para>Whenever an event invokes the statement in <xref linkend="arrays-timestampprocessname"/>, SystemTap returns the appropriate <command>execname()</command> value (i.e. the name of a process, which is then used as the unique key). At the same time, SystemTap also uses the function <command>gettimeofday_s()</command> to set the corresponding timestamp as the associated value to the unique key defined by the function <command>execname()</command>. This creates an array composed of key pairs containing process names and timestamps.</para> +<para>Whenever an event invokes the statement in <xref linkend="arrays-timestampprocessname"/>, SystemTap returns the appropriate <command>tid()</command> value (i.e. the ID of a thread, which is then used as the unique key). At the same time, SystemTap also uses the function <command>gettimeofday_s()</command> to set the corresponding timestamp as the associated value to the unique key defined by the function <command>tid()</command>. This creates an array composed of key pairs containing thread IDs and timestamps.</para> -<para>In this same example, if <command>execname()</command> returns a value that is already defined in the array <command>foo</command>, the operator will discard the original associated value to it, and replace it with the current timestamp from <command>gettimeofday_s()</command>.</para> +<para>In this same example, if <command>tid()</command> returns a value that is already defined in the array <command>foo</command>, the operator will discard the original associated value to it, and replace it with the current timestamp from <command>gettimeofday_s()</command>.</para> </section> <section id="arrayops-readvalues"> <title>Reading Values From Arrays</title> @@ -40,12 +40,12 @@ foo[execname()] = gettimeofday_s() <example id="arrayreadingvaluesfrom"> <title>Using Array Values in Simple Computations</title> <screen> -foo[execname()] = gettimeofday_s() -delta = gettimeofday_s() - foo[execname()] +foo[tid()] = gettimeofday_s() +delta = gettimeofday_s() - foo[tid()] </screen> </example> -<para>In <xref linkend="arrayreadingvaluesfrom"/>, the first statement sets a timestamp associated with the returned value of the handler function <command>execname()</command> as a <emphasis>reference point</emphasis>. The second statement computes a value for the variable <command>delta</command> by subtracting the associated value the reference point from the current <command>gettimeofday_s()</command>. Note that the first statement writes the value of <command>gettimeofday_s()</command> into the appropriate key of array <literal>foo</literal>, while in the second statement the value of <command>foo[execname()]</command> is <emphasis>read</emphasis> from the array in order to compute for <literal>delta</literal>.</para> +<para>In <xref linkend="arrayreadingvaluesfrom"/>, the first statement sets a timestamp associated with the returned value of the handler function <command>tid()</command> as a <emphasis>reference point</emphasis>. The second statement computes a value for the variable <command>delta</command> by subtracting the associated value the reference point from the current <command>gettimeofday_s()</command>. Note that the first statement writes the value of <command>gettimeofday_s()</command> into the appropriate key of array <literal>foo</literal>, while in the second statement the value of <command>foo[tid()]</command> is <emphasis>read</emphasis> from the array in order to compute for <literal>delta</literal>.</para> <para>In this situation, if the <command><replaceable>index_expression</replaceable></command> cannot find the unique key, it returns a value of 0 (for numerical operations, such as <xref linkend="arrayreadingvaluesfrom"/>) or a null/empty string value (for string operations) by default. </para> </section> @@ -73,16 +73,18 @@ probe kernel.function("vfs_read") </section> <section id="arrayops-foreach"> - <title>Processing Elements in a Tuple as Iterations</title> + <title>Processing Multiple Elements in an Array</title> +<!-- <title>Processing Elements in a Tuple as Iterations</title> --> <para>Once you've collected enough information in an array, you will need to retrieve and process all elements in that array to make it useful. Consider <xref linkend="simplesimplevfsread"/>: the script collects information about how many VFS reads each process performs, but does not specify what to do with it. The obvious means for making <xref linkend="simplesimplevfsread"/> useful is to print the key pairs in the array <command>reads</command>, but how?</para> - <para>The best way to process all elements in a tuple (treating each element as an iteration) is to use the <command>foreach</command> statement. Consider the following example:</para> + <para>The best way to process all key pairs in an array (as an iteration) is to use the <command>foreach</command> statement. Consider the following example:</para> +<!-- <para>The best way to process all elements in a tuple (treating each element as an iteration) is to use the <command>foreach</command> statement. Consider the following example:</para>--> <example id="simplevfsreadprint"> <title>cumulative-vfsreads.stp</title> <programlisting> global reads -probe kernel.function("vfs_read") +probe vfs.read { reads[execname()] ++ } @@ -104,12 +106,12 @@ probe timer.s(3) <screen> probe timer.s(3) { - foreach (count in reads+ limit 4) + foreach (count in reads- limit 10) printf("%s : %d \n", count, reads[count]) } </screen> -<para>This <command>foreach</command> statement instructs the script to process the elements in the array <command>reads</command> in ascending order (of associated value). The <command>limit 4</command> option instructs the script to only process the first four elements in the array (i.e. the first 4, starting with the lowest value).</para> +<para>This <command>foreach</command> statement instructs the script to process the elements in the array <command>reads</command> in descending order (of associated value). The <command>limit 10</command> option instructs the script to only process the first ten elements in the array (i.e. the first 10, starting with the highest value).</para> </section> <section id="arrayops-deleting"> @@ -118,12 +120,28 @@ probe timer.s(3) <para>Sometimes, you may need to clear the associated values in array elements, or reset an entire array for re-use in another probe. <xref linkend="simplevfsreadprint"/> in <xref linkend="arrayops-foreach"/> allows you to track how the number of VFS reads per process grows over time, but it does not show you the number of VFS reads each process makes per 3-second period.</para> <para>To do that, you will need to clear the values accumulated by the array. You can accomplish this using the <command>delete</command> operator to delete elements in an array, or an entire array. Consider the following example:</para> - +<example id="simplevfsreadprintnotcumulative"> + <title>noncumulative-vfsreads.stp</title> +<programlisting> +global reads +probe vfs.read +{ + reads[execname()] ++ +} +probe timer.s(3) +{ + foreach (count in reads) + printf("%s : %d \n", count, reads[count]) + delete reads +} +</programlisting> +</example> +<!-- <example id="simplevfsreadprintnotcumulative"> <title>vfsreads-per-2secs.stp</title> <programlisting> global reads -probe kernel.function("vfs_read") +probe vfs.read { reads[execname()] ++ @@ -136,7 +154,7 @@ probe timer.s(2) delete reads } </programlisting> -</example> +</example>--> <para>In <xref linkend="simplevfsreadprintnotcumulative"/>, the second probe prints the number of VFS reads each process made <emphasis>within the probed 2-second period only</emphasis>. The <command>delete reads</command> statement clears the <command>reads</command> array within the probe.</para> @@ -178,7 +196,28 @@ probe end <para>You can also use associative arrays in <command>if</command> statements. This is useful if you want to execute a subroutine once a value in the array matches a certain condition. Consider the following example:</para> <example id="simplevfsreadprintif"> - <title>vfsreads-stop-on-stapio.stp</title> + <title>vfsreads-print-if-1kb.stp</title> +<programlisting> +global reads +probe vfs.read +{ + reads[execname()] ++ +} + +probe timer.s(2) +{ + printf("=======\n") + foreach (count in reads-) + if (reads[count] >= 1024) + printf("%s : %dkB \n", count, reads[count]/1024) + else + printf("%s : %dB \n", count, reads[count]) +} +</programlisting> +</example> + +<para>Every two seconds, <xref linkend="simplevfsreadprintif"/> prints out a list of all processes, along with how many times each process performed a VFS read. If the associated value of a process name is equal or greater than 1024, the <command>if</command> statement in the script converts and prints it out in <command>kB</command>.</para> +<!-- <title>vfsreads-stop-on-stapio.stp</title> <programlisting> global reads probe kernel.function("vfs_read") @@ -200,7 +239,7 @@ probe timer.s(2) </example> <para>The <command>if(reads["stapio"] >= 20)</command> instructs the script to execute the subroutine <command>exit()</command> once the value associated with the unique key <command>stapio</command> (in the array <command>reads</command>) is greater than or equal to 20.</para> - +--> <formalpara> <title>Testing for Membership</title> <para>You can also test whether a specific unique key is a member of an array. Further, membership in an array can be used in <command>if</command> statements, as in:</para> @@ -217,7 +256,7 @@ if([<replaceable>index_expression</replaceable>] in <replaceable>array_name</rep <programlisting> global reads -probe kernel.function("vfs_read") +probe vfs.read { reads[execname()] ++ } @@ -251,15 +290,15 @@ probe timer.s(2) <example id="simpleaggregates"> <title>stat-aggregates.stp</title> <programlisting> -global writes -probe vfs_write +global reads +probe vfs.read { -writes[execname()] <<< count +reads[execname()] <<< count } </programlisting> </example> -<para>In <xref linkend="simpleaggregates"/>, the operator <command><<< count</command> <emphasis>stores</emphasis> the amount returned by <literal>count</literal> to to the associated value of the corresponding <command>execname()</command> in the <literal>writes</literal> array. Remember, these values are <emphasis>stored</emphasis>; they are not added to the associated values of each unique key, nor are they used to replace the current associated values. In a manner of speaking, think of it as having each unique key (<command>execname()</command>) having multiple associated values, accumulating with each probe handler run.</para> +<para>In <xref linkend="simpleaggregates"/>, the operator <command><<< count</command> <emphasis>stores</emphasis> the amount returned by <literal>count</literal> to to the associated value of the corresponding <command>execname()</command> in the <literal>reads</literal> array. Remember, these values are <emphasis>stored</emphasis>; they are not added to the associated values of each unique key, nor are they used to replace the current associated values. In a manner of speaking, think of it as having each unique key (<command>execname()</command>) having multiple associated values, accumulating with each probe handler run.</para> <note> <title>Note</title> |