Periodic Processing of Aggregation

In addition to different ways to process aggregations after the data collection is complete, you can also process aggregation data periodically as the data is being collected. You can use the dtrace_aggregate_snap() and dtrace_aggregate_clear() functions to process aggregation data periodically.

The dtrace_work() function transfers the existing aggregation data from the kernel, clears the in-kernel buffers, and adds the data to the copies of the aggregation data, which is maintained in user space. However, if a consumer wants to generate only aggregation data, it is more efficient to call the dtrace_aggregate_snap() function and skip the call to the dtrace_consume() function. You must also use the dtrace_status() function because the deadman timer fires if the aggregation is not performed periodically.

The dtrace_aggregate_clear() function clears the aggregate data associated with a DTrace handle. Although the function does not free the data structures holding this data, it zeros those parts of the data structures that hold aggregation data. This distinction is important because the entries in an aggregation remains with zeroed values. For example, suppose you modify the Embedding DTrace in a Consumer by replacing the work() loop with the following code. You can also use dtrace_getopt() to determine the rate at which the dtrace_status() and dtrace_aggregate_snap() functions are called. You can also use aggrate.

if (dtrace_getopt(g_dtp, "statusrate", &statustime) == -1)
        fatal("failed to get 'statusrate'");

for (int i = 0; i < 10; i++) {
        usleep(statustime / 1000);

        if (dtrace_status(g_dtp) == -1)    
                fatal("dtrace_status()");

        if (dtrace_aggregate_snap(g_dtp) != 0)
                fatal("failed to add to aggregate");

        if (dtrace_aggregate_print(g_dtp, stdout, NULL) == -1)
                fatal("failed to print aggregation");

        dtrace_aggregate_clear(g_dtp);
}

If you run this consumer by using a D program that counts system calls, you can see the output for each iteration of the loop. The output for the final iteration of the loop would be similar to the following example.

brk                           0
close                         0
fchmod                        0
fcntl                         0
getdents64                    0
getpid                        0
lstat                         0
mkdir                         0
p_online                      0
pread                         0
pset                          0
rename                        0
stat64                        0
statvfs64                     0
sysconfig                     0
yield                         0
gtime                         1
lwp_cond_wait                 1
open                          1
writev                        1
clock_gettime                 2
nanosleep                     2
setitimer                     2
lwp_sigmask                  18
portfs                       22
read                         28
lwp_park                     30
write                        55
ioctl                        63
pollsys                     102

The zeroed entries in this output correspond to system calls that have been made since the D program is executing but are not called during the final loop. The dtrace_aggregate_clear() function zeros the data for the entries but does not remove the entries themselves. The dtrace_aggregate_print() function prints the value for every entry, including the entries with a zero value.