From 5191b61cb908d096d872ad26f8f632641ff15cc8 Mon Sep 17 00:00:00 2001 From: ddomingo Date: Thu, 20 Nov 2008 10:56:02 +1000 Subject: revise as per wcohen, run 2 --- .../en-US/Array-Operations.xml | 46 +++++++++++++++------- 1 file changed, 32 insertions(+), 14 deletions(-) (limited to 'doc/SystemTap_Beginners_Guide/en-US/Array-Operations.xml') diff --git a/doc/SystemTap_Beginners_Guide/en-US/Array-Operations.xml b/doc/SystemTap_Beginners_Guide/en-US/Array-Operations.xml index f63d1d70..270c6fc9 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 @@ Associating Timestamps to Process Names -foo[execname()] = gettimeofday_s() +foo[tid()] = gettimeofday_s() -Whenever an event invokes the statement in , SystemTap returns the appropriate execname() 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 gettimeofday_s() to set the corresponding timestamp as the associated value to the unique key defined by the function execname(). This creates an array composed of key pairs containing process names and timestamps. +Whenever an event invokes the statement in , SystemTap returns the appropriate tid() 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 gettimeofday_s() to set the corresponding timestamp as the associated value to the unique key defined by the function tid(). This creates an array composed of key pairs containing thread IDs and timestamps. -In this same example, if execname() returns a value that is already defined in the array foo, the operator will discard the original associated value to it, and replace it with the current timestamp from gettimeofday_s(). +In this same example, if tid() returns a value that is already defined in the array foo, the operator will discard the original associated value to it, and replace it with the current timestamp from gettimeofday_s().
Reading Values From Arrays @@ -40,12 +40,12 @@ foo[execname()] = gettimeofday_s() Using Array Values in Simple Computations -foo[execname()] = gettimeofday_s() -delta = gettimeofday_s() - foo[execname()] +foo[tid()] = gettimeofday_s() +delta = gettimeofday_s() - foo[tid()] -In , the first statement sets a timestamp associated with the returned value of the handler function execname() as a reference point. The second statement computes a value for the variable delta by subtracting the associated value the reference point from the current gettimeofday_s(). Note that the first statement writes the value of gettimeofday_s() into the appropriate key of array foo, while in the second statement the value of foo[execname()] is read from the array in order to compute for delta. +In , the first statement sets a timestamp associated with the returned value of the handler function tid() as a reference point. The second statement computes a value for the variable delta by subtracting the associated value the reference point from the current gettimeofday_s(). Note that the first statement writes the value of gettimeofday_s() into the appropriate key of array foo, while in the second statement the value of foo[tid()] is read from the array in order to compute for delta. In this situation, if the index_expression cannot find the unique key, it returns a value of 0 (for numerical operations, such as ) or a null/empty string value (for string operations) by default.
@@ -73,16 +73,18 @@ probe kernel.function("vfs_read")
- Processing Elements in a Tuple as Iterations + Processing Multiple Elements in an Array + 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 : 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 useful is to print the key pairs in the array reads, but how? - The best way to process all elements in a tuple (treating each element as an iteration) is to use the foreach statement. Consider the following example: + The best way to process all key pairs in an array (as an iteration) is to use the foreach statement. Consider the following example: + cumulative-vfsreads.stp global reads -probe kernel.function("vfs_read") +probe vfs.read { reads[execname()] ++ } @@ -104,12 +106,12 @@ probe timer.s(3) probe timer.s(3) { - foreach (count in reads+ limit 4) + foreach (count in reads- limit 10) printf("%s : %d \n", count, reads[count]) } -This foreach statement instructs the script to process the elements in the array reads in ascending order (of associated value). The limit 4 option instructs the script to only process the first four elements in the array (i.e. the first 4, starting with the lowest value). +This foreach statement instructs the script to process the elements in the array reads in descending order (of associated value). The limit 10 option instructs the script to only process the first ten elements in the array (i.e. the first 10, starting with the highest value).
@@ -118,12 +120,28 @@ probe timer.s(3) Sometimes, you may need to clear the associated values in array elements, or reset an entire array for re-use in another probe. in 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. To do that, you will need to clear the values accumulated by the array. You can accomplish this using the delete operator to delete elements in an array, or an entire array. Consider the following example: - + + noncumulative-vfsreads.stp + +global reads +probe vfs.read +{ + reads[execname()] ++ +} +probe timer.s(3) +{ + foreach (count in reads) + printf("%s : %d \n", count, reads[count]) + delete reads +} + + + In , the second probe prints the number of VFS reads each process made within the probed 2-second period only. The delete reads statement clears the reads array within the probe. -- cgit From c59943f6936e93819978d5149500ca217d09667a Mon Sep 17 00:00:00 2001 From: ddomingo Date: Thu, 20 Nov 2008 11:19:00 +1000 Subject: revise as per wcohen, run 3 --- .../en-US/Array-Operations.xml | 35 +++++++++++++++++----- 1 file changed, 28 insertions(+), 7 deletions(-) (limited to 'doc/SystemTap_Beginners_Guide/en-US/Array-Operations.xml') diff --git a/doc/SystemTap_Beginners_Guide/en-US/Array-Operations.xml b/doc/SystemTap_Beginners_Guide/en-US/Array-Operations.xml index 270c6fc9..4aef21f4 100644 --- a/doc/SystemTap_Beginners_Guide/en-US/Array-Operations.xml +++ b/doc/SystemTap_Beginners_Guide/en-US/Array-Operations.xml @@ -196,7 +196,28 @@ probe end You can also use associative arrays in if 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: - vfsreads-stop-on-stapio.stp + vfsreads-print-if-1kb.stp + +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]) +} + + + +Every two seconds, 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 if statement in the script converts and prints it out in kB. + Testing for Membership You can also test whether a specific unique key is a member of an array. Further, membership in an array can be used in if statements, as in: @@ -235,7 +256,7 @@ if([index_expression] in array_name global reads -probe kernel.function("vfs_read") +probe vfs.read { reads[execname()] ++ } @@ -269,15 +290,15 @@ probe timer.s(2) stat-aggregates.stp -global writes -probe vfs_write +global reads +probe vfs.read { -writes[execname()] <<< count +reads[execname()] <<< count } -In , the operator <<< count stores the amount returned by count to to the associated value of the corresponding execname() in the writes array. Remember, these values are stored; 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 (execname()) having multiple associated values, accumulating with each probe handler run. +In , the operator <<< count stores the amount returned by count to to the associated value of the corresponding execname() in the reads array. Remember, these values are stored; 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 (execname()) having multiple associated values, accumulating with each probe handler run. Note -- cgit