Go to main content

man pages section 3: Extended Library Functions, Volume 2

Exit Print View

Updated: Wednesday, July 27, 2022
 
 

dtrace_aggregate_walk_valrevsorted (3DTRACE)

Name

dtrace_aggregate_walk, dtrace_aggregate_print, dtrace_aggregate_walk_sorted, dtrace_aggregate_walk_keysorted, dtrace_aggregate_walk_valsorted, dtrace_aggregate_walk_keyvarsorted, dtrace_aggregate_walk_valvarsorted, dtrace_aggregate_walk_keyrevsorted, dtrace_aggregate_walk_valrevsorted, dtrace_aggregate_walk_keyvarrevsorted, dtrace_aggregate_walk_valvarrevsorted, dtrace_aggregate_walk_joined - Process aggregation data

Synopsis

     cc [ flag... ] file... -ldtrace [ library... ]
     #include <dtrace.h>

     typedef int dtrace_aggregate_f(const dtrace_aggdata_t *, void *);
     typedef int dtrace_aggregate_walk_f(dtrace_hdl_t *,
         dtrace_aggregate_f *, void *);
     typedef int dtrace_aggregate_walk_joined_f(const dtrace_aggdata_t **,
         const int, void *);

     int dtrace_aggregate_print(dtrace_hdl_t *dtp, FILE *fp,
         dtrace_aggregate_walk_f *func);

     int dtrace_aggregate_walk(dtrace_hdl_t *dtp,
	 dtrace_aggregate_f *func, void *arg);

     int dtrace_aggregate_walk_sorted(dtrace_hdl_t *dtp,
         dtrace_aggregate_f *func, void *arg);

     int dtrace_aggregate_walk_keysorted(dtrace_hdl_t *dtp,
         dtrace_aggregate_f *func, void *arg);

     int dtrace_aggregate_walk_valsorted(dtrace_hdl_t *dtp,
         dtrace_aggregate_f *func, void *arg);

     int dtrace_aggregate_walk_keyvarsorted(dtrace_hdl_t *dtp,
         dtrace_aggregate_f *func, void *arg);

     int dtrace_aggregate_walk_valvarsorted(dtrace_hdl_t *dtp,
         dtrace_aggregate_f *func, void *arg);

     int dtrace_aggregate_walk_keyrevsorted(dtrace_hdl_t *dtp,
         dtrace_aggregate_f *func, void *arg);

     int dtrace_aggregate_walk_valrevsorted(dtrace_hdl_t *dtp,
         dtrace_aggregate_f *func, void *arg);

     int dtrace_aggregate_walk_keyvarrevsorted(dtrace_hdl_t *dtp,
         dtrace_aggregate_f *func, void *arg);

     int dtrace_aggregate_walk_valvarrevsorted(dtrace_hdl_t *dtp,
         dtrace_aggregate_f *func, void *arg);

     int dtrace_aggregate_walk_joined(dtrace_hdl_t *dtp,
         dtrace_aggvarid_t *aggvars, int naggvars,
	 dtrace_aggregate_walk_joined_f *func, void *arg);

Description

You can use the dtrace_aggregate_print() function to print DTrace aggregate data. The function can be passed a specific walk() function (as those described below). If passed NULL, it defaults to the dtrace_aggregate_walk_sorted() function, and the callback function passed to the walk() function is the default function that the libdtrace library uses to print aggregate data.

You can use the dtrace_aggregate_walk() and dtrace_aggregate_walk_sorted() functions to process aggregate data with sorting functions as described below. For each aggregate buffer, the callback function, func() is called. This callback function can extract and process the keys and value for this entry.

The following section illustrates how you can use the functions to process the aggregate data in a D script. This section consists of a sample D script containing aggregate data, followed by information on how each function would process this data.

Aggregate Data Processing by Functions

Sample D Script With Aggregate Data
       BEGIN
	{
	       @a["bravo"] = sum(3);
	       @b["alpha"] = sum(4);
	       @a["delta"] = sum(1);
	       @b["charlie"] = sum(2);
	       @a["echo"] = sum(6);
	       @b["echo"] = sum(5);
	       exit(0);
	}
Using dtrace_aggregate_walk()to Process Aggregate Data

The dtrace_aggregate_walk() function processes the aggregate data with no sorting. The data remains the same as it appears in the buffer. The order is random. For the sample D script given above, the output of the dtrace_aggregate_walk() function might appear as follows:

        echo                    5
        echo                    6
        charlie                 2
        delta                   1
        alpha                   4
        bravo                   3
Using dtrace_aggregate_walk_sorted() to Process Aggregate Data

The dtrace_aggregate_walk_sorted() function processes the aggregate data sorted first by variable name if multiple aggregations are processed. The function then sorts the data within each aggregation by ascending value.

For the D sample script, the dtrace_aggregate_walk_sorted() function sorts the aggregate data by variable first, so @a comes before @b. Note that this is by variable ID, not variable name. IDs are assigned in the order in which the aggregation appears in the script. In this case, @a has aggregation ID 1 and @b has aggregation ID 2.

Entries in aggregation @a, the bravo, delta, and echo values are printed first. Then, within each aggregation, the entries are sorted by value. Thus, in the aggregation, @a, delta comes before bravo, and charlie comes before alpha. The output of the D sample script is as follows:

        delta                   1
        bravo                   3
        echo                    6
        charlie                 2
        alpha                   4
        echo                    5
Using dtrace_aggregate_walk_keysorted() to Process Aggregate Data

The dtrace_aggregate_walk_keysorted() function processes the aggregate data sorted first by variable name if there are multiple aggregations. The function then sorts the data within each aggregation by key. For the D sample script, the function sorts @a first. The function then sorts by key, so bravo comes before delta, and alpha comes before charlie. The output of the sample D script is as follows:

        bravo                   3
        delta                   1
        echo                    6
        alpha                   4
        charlie                 2
        echo                    5
Using dtrace_aggregate_walk_valsorted() to Process Aggregate Data

The dtrace_aggregate_walk_valsorted() function processes the aggregate data sorted first by variable name if there are multiple aggregations. The function then sorts the data within each aggregation by value, which is the same as the default behavior.

Using dtrace_aggregate_walk_keyvarsorted() to Process Aggregate Data

The dtrace_aggregate_walk_keyvarsorted() function processes the aggregate data sorted first by key. If the same key occurs in two different aggregations, the function then sorts by variable (aggregation ID). Thus, the function prints echo from the aggregate, @a before echo from the aggregate, @b. The output of the sample D script is as follows:

        alpha                   4
        bravo                   3
        charlie                 2
        delta                   1
        echo                    6
        echo                    5
Using dtrace_aggregate_walk_valvarsorted() to Process Aggregate Data

The dtrace_aggregate_walk_valvarsorted() function processes the aggregate data sorted first by value and then by variable (i.e., aggregation ID). The output of the sample D script is as follows:

        delta                   1
        charlie                 2
        bravo                   3
        alpha                   4
        echo                    5
        echo                    6
Using dtrace_aggregate_walk_keyrevsorted() to Process Aggregate Data

The dtrace_aggregate_walk_keyrevsorted() function sorts the aggregate data in an order reverse to that of the dtrace_aggregate_walk_keysorted() function. Thus, the dtrace_aggregate_walk_keyrevsorted() function first sorts the data in reverse order by variable (aggregation ID) and then in reverse order by key. Thus . The output of the sample D script is as follows:

        echo                    5
        charlie                 2
        alpha                   4
        echo                    6
        delta                   1
        bravo                   3
Using dtrace_aggregate_walk_valrevsorted() to Process Aggregate Data

The dtrace_aggregate_walk_valrevsorted() function processes the aggregate data in the reverse order as the dtrace_aggregate_walk_valsorted() function. Thus, the dtrace_aggregate_walk_valrevsorted() function first sorts the data in reverse order by variable (aggregation ID) and then in reverse order by value. The output of the sample D script is as follows:

        echo                    5
        alpha                   4
        charlie                 2
        echo                    6
        bravo                   3
        delta                   1
Using dtrace_aggregate_walk_keyvarrevsorted() to Process Aggregate Data

The dtrace_aggregate_walk_keyvarrevsorted() function processes the aggregate data in the reverse order as the dtrace_aggregate_walk_keyvarsorted() function. Thus, the dtrace_aggregate_walk_keyvarrevsorted() function first sorts the data in reverse order by key and then, If the same key occurs in two different aggregations, in reverse order by variable (aggregation ID). The output of the sample D script is as follows:

        echo                    5
        echo                    6
        delta                   1
        charlie                 2
        bravo                   3
        alpha                   4
Using dtrace_aggregate_walk_valvarrevsorted() to Process Aggregate Data

The dtrace_aggregate_walk_valvarrevsorted() function processes the aggregate data in the reverse order as the dtrace_aggregate_walk_valvarsorted() function. Thus, the dtrace_aggregate_walk_valvarrevsorted() first sorts the data in reverse order by value and then in reverse order by variable (aggregation ID). The output of the sample D script is as follows:

        echo                    6
        echo                    5
        alpha                   4
        bravo                   3
        charlie                 2
        delta                   1
Using dtrace_aggregate_walk_joined() to Process Aggregate Data

The dtrace_aggregate_walk_joined() function allows you to process multiple aggregations at the same time, similar to a database join operation. The callback function, func() is passed an array, aggvars, of aggregation entries to be joined, and the number of elements in that array, naggvars. The aggvars array consists of aggregation entries from the multiple aggregations that have the same key or set of keys.

Return Values

On successful completion, the functions return 0. On failure, the functions return -1 and set the DTrace error number to indicate the reason for the failure. See the dtrace_errno(3DTRACE) man page for more information.

Errors

All the functions will fail if:

EDT_NOMEM

The system was unable to allocate memory while processing this function.

The dtrace_aggregate_print() function will fail if:

EINVAL

dtp is NULL.

EDT_NOBUFFERED

fp is NULL and there is no buffer handler installed. See the dtrace_handle_buffered(3DTRACE) man page for more information.

The dtrace_aggregate_walk(), dtrace_aggregate_walk_sorted(), dtrace_aggregate_walk_keysorted(), dtrace_aggregate_walk_valsorted(), dtrace_aggregate_walk_keyvarsorted(), dtrace_aggregate_walk_valvarsorted(), dtrace_aggregate_walk_keyrevsorted(), dtrace_aggregate_walk_valrevsorted(), dtrace_aggregate_walk_keyvarrevsorted(), and dtrace_aggregate_walk_valvarrevsorted() functions will fail if:

EINVAL

dtp or func is NULL.

EDT_DIRABORT

func returned the value, DTRACE_AGGWALK_ABORT while processing an entry in the aggregation buffer. See the Usage section for more information.

EDT_BADRVAL
  • func returned the value, DTRACE_AGGWALK_NORMALIZE when the normalization value was 0. See the Usage section for more information.

  • func returned an invalid value. An invalid value is a value that is not one of the DTRACE_AGGWALK_* constants mentioned in the Usage section.

The dtrace_aggregate_walk_joined() function will fail if:

EINVAL

dtp, aggvars or func is NULL, or naggvars < 0.

Usage

The callback function, passed to dtrace_aggregate_walk() and other functions, is used to process a single aggregation record. The data in the aggregation is described by the dtrace_aggdata_t argument to the callback. The dtrace_aggdata_t structure is defined as follows:

     struct dtrace_aggdata {
     	dtrace_hdl_t *dtada_handle;               /* handle to DTrace library */
     	dtrace_aggdesc_t *dtada_desc;		/* aggregation description */
     	dtrace_eprobedesc_t *dtada_edesc;         /* enabled probe description */
     	dtrace_probedesc_t *dtada_pdesc;          /* probe description */
     	caddr_t dtada_data;                       /* pointer to raw data */
     	uint64_t dtada_normal;                    /* the normal -- 1 for denorm */
     	size_t dtada_size;                        /* total size of the data */
     	caddr_t dtada_delta;                      /* delta data, if available */
     	caddr_t *dtada_percpu;                    /* per CPU data, if avail */
     	caddr_t *dtada_percpu_delta;		 /* per CPU delta, if avail */
     };

Note -  The callback function to the dtrace_aggregate_walk_joined() function is passed an array, aggvars, of aggregation entries to be joined, and the number of elements in that array, naggvars. The entries are pointers to the data structures of the dtrace_aggdata_t type.

The dtada_data member of this structure references the raw data for the aggregation record. The dtada_desc member contains the description for the aggregation record. The type of this member, dtrace_aggdesc_t, is defined as follows:

    typedef struct dtrace_aggdesc {
     	DTRACE_PTR(char, dtagd_name);		/* not filled in by kernel */
     	dtrace_aggvarid_t dtagd_varid;            /* not filled in by kernel */
     	int dtagd_flags;                          /* not filled in by kernel */
     	dtrace_aggid_t dtagd_id;		     /* aggregation ID */
     	dtrace_epid_t dtagd_epid;		    /* enabled probe ID */
     	uint32_t dtagd_size;                      /* size in bytes */
     	int dtagd_nrecs;                          /* number of records */
     	uint32_t dtagd_pad;                       /* explicit padding */
     	dtrace_recdesc_t dtagd_rec[1];            /* record descriptions */
     } dtrace_aggdesc_t;

The dtagd_nrecs member of this structure stores the number of individual records associated with this aggregation record. The dtagd_rec array stores the individual records, which represent, the keys and the value, in that order, for the aggregation record. The members of the dtagd_rec array are of the dtrace_recdesc_t type, defined as follows:

    typedef struct dtrace_recdesc {
     	dtrace_actkind_t dtrd_action;            /* kind of action */
     	uint32_t dtrd_size;                      /* size of record */
     	uint32_t dtrd_offset;                    /* offset in ECB's data */
     	uint16_t dtrd_alignment;                 /* required alignment */
     	uint16_t dtrd_format;                    /* format, if any */
     	uint64_t dtrd_arg;                       /* action argument */
     	uint64_t dtrd_uarg;                      /* user argument */
     } dtrace_recdesc_t;

For example, the following code shows how to extract a pointer to a particular record and the size of that record:

    void *record;
        size_t size;

        record = aggdata->dtada_data + aggdesc->dtagd_rec[index].dtrd_offset;
        size = aggdesc->dtagd_rec[index].dtrd_size;

The callback function passed to dtrace_aggregate_walk() and other functions is expected to return one of the following set of values:

     DTRACE_AGGWALK_ERROR
     DTRACE_AGGWALK_NEXT
     DTRACE_AGGWALK_ABORT
     DTRACE_AGGWALK_CLEAR
     DTRACE_AGGWALK_NORMALIZE
     DTRACE_AGGWALK_DENORMALIZE
     DTRACE_AGGWALK_REMOVE

These values are documented in the /usr/include/dtrace.h ?.

Examples

Example 1 Using the dtrace_aggregate_walk() Function to Process Data

The following example demonstrates the use of the dtrace_aggregate_walk() function to process the data from a simple DTrace script:

     #include <dtrace.h>
     #include <stdarg.h>
     #include <stdio.h>
     #include <stdlib.h>

     static dtrace_hdl_t *g_dtp;

     char *g_prog = ""
     "syscall:::entry"
     "{"
     "        @[probefunc] = count();"
     "}"
     "tick-1s"
     "{"
     "       exit(0);"
     "}"
     "";

     static void
     fatal(const char *fmt, ...)
     {
             va_list ap;

             va_start(ap, fmt);
             (void) vfprintf(stderr, fmt, ap);

             if (fmt[strlen(fmt) - 1] != '\n')
                     (void) fprintf(stderr, ": %s\n",
                         dtrace_errmsg(g_dtp, dtrace_errno(g_dtp)));

             exit(EXIT_FAILURE);
     }

     static int
     walk(const dtrace_aggdata_t *aggdata, void *arg)
     {
             dtrace_aggdesc_t *aggdesc;
             char *key;
             uint64_t value;

             if (aggdata == NULL)
                     fatal("No aggdata\n");
             if ((aggdesc = aggdata->dtada_desc) == NULL)
                     fatal("No aggdesc\n");

             key = dtrace_extract_aggregate_string(aggdata, aggdesc, 1);
             value = dtrace_extract_aggregate_value(aggdata, aggdesc, 2);

             printf("%s\t%llu\n", key, value);

             return (DTRACE_AGGWALK_NEXT);
     }

     static int
     chewrec(const dtrace_probedata_t *data, const dtrace_recdesc_t *rec,
         void *arg)
     {
             dtrace_actkind_t act;

             if (rec == NULL)
                     return (DTRACE_CONSUME_NEXT);
             act = rec->dtrd_action;

             if (act == DTRACEACT_EXIT)
                     return (DTRACE_CONSUME_NEXT);

             return (DTRACE_CONSUME_NEXT);
     }

     static int
     chew(const dtrace_probedata_t *data, void *arg)
     {
             return (DTRACE_CONSUME_THIS);
     }

     int
     main()
     {
             dtrace_prog_t *prog;
             dtrace_proginfo_t info;
             int err;

             if ((g_dtp = dtrace_open(DTRACE_VERSION, 0, &err)) == NULL)
                     fatal("cannot open dtrace library: %s\n",
                         dtrace_errmsg(NULL, err));

             if ((prog = dtrace_program_strcompile(g_dtp, g_prog,
                  DTRACE_PROBESPEC_NAME, 0, 0, NULL)) == NULL)
                     fatal("invalid program");

             if (dtrace_program_exec(g_dtp, prog, &info) == -1)
                     fatal("failed to enable probes");

             if (dtrace_setopt(g_dtp, "bufsize", "512k") == -1)
                     fatal("failed to set bufsize");

             if (dtrace_setopt(g_dtp, "aggsize", "512k") == -1)
                     fatal("failed to set aggsize");

             if (dtrace_go(g_dtp) != 0)
                     fatal("dtrace_go()");

             while (1) {
                     int done = 0;

                     dtrace_sleep(g_dtp);

                     switch (dtrace_work(g_dtp, stdout, chew, chewrec,
                         NULL)) {
                     case DTRACE_WORKSTATUS_DONE:
                             done = 1;
                             break;

                     case DTRACE_WORKSTATUS_OKAY:
                             break;

                     default:
                             fatal("processing aborted");
                     }

                     if (done)
                         break;
             }

             if (dtrace_aggregate_walk(g_dtp, walk, NULL) != 0)
                     fatal("dtrace_aggregate_walk failed");
             printf("\n");

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

             dtrace_close(g_dtp);

             return (0);
     }

Attributes

See attributes(7) for descriptions of the following attributes:

ATTRIBUTE TYPE
ATTRIBUTE VALUE
Architecture
all
Availability
system/dtrace
Interface Stability
Committed
MT-Level
Safe

See Also

libdtrace(3LIB), dtrace_errno(3DTRACE), dtrace_aggregate_clear(3DTRACE), dtrace_aggregate_snap(3DTRACE)