Author: pfg
Date: Sun Jul  1 04:15:14 2012
New Revision: 237870
URL: http://svn.freebsd.org/changeset/base/237870

Log:
  MFC   r237624, r237714, r237716, r237860:
  
  Bring llquantize support into Dtrace.
  
  Bryan Cantrill implemented the equivalent of semi-log graph
  paper for Dtrace so llquantize will use one logarithmic and
  one linear scale.

Added:
     - copied from r237868, 
head/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/
Directory Properties:
  stable/9/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/   
(props changed)
Modified:
  stable/9/cddl/contrib/opensolaris/lib/libdtrace/common/dt_aggregate.c
  stable/9/cddl/contrib/opensolaris/lib/libdtrace/common/dt_cc.c
  stable/9/cddl/contrib/opensolaris/lib/libdtrace/common/dt_consume.c
  stable/9/cddl/contrib/opensolaris/lib/libdtrace/common/dt_errtags.h
  stable/9/cddl/contrib/opensolaris/lib/libdtrace/common/dt_impl.h
  stable/9/cddl/contrib/opensolaris/lib/libdtrace/common/dt_open.c
  stable/9/cddl/contrib/opensolaris/lib/libdtrace/common/dt_printf.c
  stable/9/cddl/contrib/opensolaris/lib/libdtrace/common/dtrace.h
  stable/9/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c
  stable/9/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h
Directory Properties:
  stable/9/cddl/   (props changed)
  stable/9/cddl/contrib/opensolaris/   (props changed)
  stable/9/sys/   (props changed)
  stable/9/sys/cddl/contrib/opensolaris/   (props changed)

Modified: stable/9/cddl/contrib/opensolaris/lib/libdtrace/common/dt_aggregate.c
==============================================================================
--- stable/9/cddl/contrib/opensolaris/lib/libdtrace/common/dt_aggregate.c       
Sun Jul  1 04:09:42 2012        (r237869)
+++ stable/9/cddl/contrib/opensolaris/lib/libdtrace/common/dt_aggregate.c       
Sun Jul  1 04:15:14 2012        (r237870)
@@ -24,7 +24,9 @@
  * Use is subject to license terms.
  */
 
-#pragma ident  "%Z%%M% %I%     %E% SMI"
+/*
+ * Copyright (c) 2011, Joyent, Inc. All rights reserved.
+ */
 
 #include <stdlib.h>
 #include <strings.h>
@@ -209,6 +211,83 @@ dt_aggregate_lquantizedcmp(int64_t *lhs,
        return (0);
 }
 
+static void
+dt_aggregate_llquantize(int64_t *existing, int64_t *new, size_t size)
+{
+       int i;
+
+       for (i = 1; i < size / sizeof (int64_t); i++)
+               existing[i] = existing[i] + new[i];
+}
+
+static long double
+dt_aggregate_llquantizedsum(int64_t *llquanta)
+{
+       int64_t arg = *llquanta++;
+       uint16_t factor = DTRACE_LLQUANTIZE_FACTOR(arg);
+       uint16_t low = DTRACE_LLQUANTIZE_LOW(arg);
+       uint16_t high = DTRACE_LLQUANTIZE_HIGH(arg);
+       uint16_t nsteps = DTRACE_LLQUANTIZE_NSTEP(arg);
+       int bin = 0, order;
+       int64_t value = 1, next, step;
+       long double total;
+
+       assert(nsteps >= factor);
+       assert(nsteps % factor == 0);
+
+       for (order = 0; order < low; order++)
+               value *= factor;
+
+       total = (long double)llquanta[bin++] * (long double)(value - 1);
+
+       next = value * factor;
+       step = next > nsteps ? next / nsteps : 1;
+
+       while (order <= high) {
+               assert(value < next);
+               total += (long double)llquanta[bin++] * (long double)(value);
+
+               if ((value += step) != next)
+                       continue;
+
+               next = value * factor;
+               step = next > nsteps ? next / nsteps : 1;
+               order++;
+       }
+
+       return (total + (long double)llquanta[bin] * (long double)value);
+}
+
+static int
+dt_aggregate_llquantizedcmp(int64_t *lhs, int64_t *rhs)
+{
+       long double lsum = dt_aggregate_llquantizedsum(lhs);
+       long double rsum = dt_aggregate_llquantizedsum(rhs);
+       int64_t lzero, rzero;
+
+       if (lsum < rsum)
+               return (DT_LESSTHAN);
+
+       if (lsum > rsum)
+               return (DT_GREATERTHAN);
+
+       /*
+        * If they're both equal, then we will compare based on the weights at
+        * zero.  If the weights at zero are equal, then this will be judged a
+        * tie and will be resolved based on the key comparison.
+        */
+       lzero = lhs[1];
+       rzero = rhs[1];
+
+       if (lzero < rzero)
+               return (DT_LESSTHAN);
+
+       if (lzero > rzero)
+               return (DT_GREATERTHAN);
+
+       return (0);
+}
+
 static int
 dt_aggregate_quantizedcmp(int64_t *lhs, int64_t *rhs)
 {
@@ -592,6 +671,10 @@ hashnext:
                        h->dtahe_aggregate = dt_aggregate_lquantize;
                        break;
 
+               case DTRACEAGG_LLQUANTIZE:
+                       h->dtahe_aggregate = dt_aggregate_llquantize;
+                       break;
+
                case DTRACEAGG_COUNT:
                case DTRACEAGG_SUM:
                case DTRACEAGG_AVG:
@@ -859,6 +942,10 @@ dt_aggregate_valcmp(const void *lhs, con
                rval = dt_aggregate_lquantizedcmp(laddr, raddr);
                break;
 
+       case DTRACEAGG_LLQUANTIZE:
+               rval = dt_aggregate_llquantizedcmp(laddr, raddr);
+               break;
+
        case DTRACEAGG_COUNT:
        case DTRACEAGG_SUM:
        case DTRACEAGG_MIN:

Modified: stable/9/cddl/contrib/opensolaris/lib/libdtrace/common/dt_cc.c
==============================================================================
--- stable/9/cddl/contrib/opensolaris/lib/libdtrace/common/dt_cc.c      Sun Jul 
 1 04:09:42 2012        (r237869)
+++ stable/9/cddl/contrib/opensolaris/lib/libdtrace/common/dt_cc.c      Sun Jul 
 1 04:15:14 2012        (r237870)
@@ -82,6 +82,7 @@
 
 #include <sys/types.h>
 #include <sys/wait.h>
+#include <sys/sysmacros.h>
 
 #include <assert.h>
 #include <string.h>
@@ -1369,6 +1370,146 @@ dt_compile_agg(dtrace_hdl_t *dtp, dt_nod
                argmax = 5;
        }
 
+       if (fid->di_id == DTRACEAGG_LLQUANTIZE) {
+               /*
+                * For log/linear quantizations, we have between one and five
+                * arguments in addition to the expression:
+                *
+                *    arg1 => Factor
+                *    arg2 => Low magnitude
+                *    arg3 => High magnitude
+                *    arg4 => Number of steps per magnitude
+                *    arg5 => Quantization increment value (defaults to 1)
+                */
+               dt_node_t *llarg = dnp->dn_aggfun->dn_args->dn_list;
+               uint64_t oarg, order, v;
+               dt_idsig_t *isp;
+               int i;
+
+               struct {
+                       char *str;              /* string identifier */
+                       int badtype;            /* error on bad type */
+                       int badval;             /* error on bad value */
+                       int mismatch;           /* error on bad match */
+                       int shift;              /* shift value */
+                       uint16_t value;         /* value itself */
+               } args[] = {
+                       { "factor", D_LLQUANT_FACTORTYPE,
+                           D_LLQUANT_FACTORVAL, D_LLQUANT_FACTORMATCH,
+                           DTRACE_LLQUANTIZE_FACTORSHIFT },
+                       { "low magnitude", D_LLQUANT_LOWTYPE,
+                           D_LLQUANT_LOWVAL, D_LLQUANT_LOWMATCH,
+                           DTRACE_LLQUANTIZE_LOWSHIFT },
+                       { "high magnitude", D_LLQUANT_HIGHTYPE,
+                           D_LLQUANT_HIGHVAL, D_LLQUANT_HIGHMATCH,
+                           DTRACE_LLQUANTIZE_HIGHSHIFT },
+                       { "linear steps per magnitude", D_LLQUANT_NSTEPTYPE,
+                           D_LLQUANT_NSTEPVAL, D_LLQUANT_NSTEPMATCH,
+                           DTRACE_LLQUANTIZE_NSTEPSHIFT },
+                       { NULL }
+               };
+
+               assert(arg == 0);
+
+               for (i = 0; args[i].str != NULL; i++) {
+                       if (llarg->dn_kind != DT_NODE_INT) {
+                               dnerror(llarg, args[i].badtype, "llquantize( ) "
+                                   "argument #%d (%s) must be an "
+                                   "integer constant\n", i + 1, args[i].str);
+                       }
+
+                       if ((uint64_t)llarg->dn_value > UINT16_MAX) {
+                               dnerror(llarg, args[i].badval, "llquantize( ) "
+                                   "argument #%d (%s) must be an unsigned "
+                                   "16-bit quantity\n", i + 1, args[i].str);
+                       }
+
+                       args[i].value = (uint16_t)llarg->dn_value;
+
+                       assert(!(arg & ((uint64_t)UINT16_MAX <<
+                           args[i].shift)));
+                       arg |= ((uint64_t)args[i].value << args[i].shift);
+                       llarg = llarg->dn_list;
+               }
+
+               assert(arg != 0);
+
+               if (args[0].value < 2) {
+                       dnerror(dnp, D_LLQUANT_FACTORSMALL, "llquantize( ) "
+                           "factor (argument #1) must be two or more\n");
+               }
+
+               if (args[1].value >= args[2].value) {
+                       dnerror(dnp, D_LLQUANT_MAGRANGE, "llquantize( ) "
+                           "high magnitude (argument #3) must be greater "
+                           "than low magnitude (argument #2)\n");
+               }
+
+               if (args[3].value < args[0].value) {
+                       dnerror(dnp, D_LLQUANT_FACTORNSTEPS, "llquantize( ) "
+                           "factor (argument #1) must be less than or "
+                           "equal to the number of linear steps per "
+                           "magnitude (argument #4)\n");
+               }
+
+               for (v = args[0].value; v < args[3].value; v *= args[0].value)
+                       continue;
+
+               if ((args[3].value % args[0].value) || (v % args[3].value)) {
+                       dnerror(dnp, D_LLQUANT_FACTOREVEN, "llquantize( ) "
+                           "factor (argument #1) must evenly divide the "
+                           "number of steps per magnitude (argument #4), "
+                           "and the number of steps per magnitude must evenly "
+                           "divide a power of the factor\n");
+               }
+
+               for (i = 0, order = 1; i < args[2].value; i++) {
+                       if (order * args[0].value > order) {
+                               order *= args[0].value;
+                               continue;
+                       }
+
+                       dnerror(dnp, D_LLQUANT_MAGTOOBIG, "llquantize( ) "
+                           "factor (%d) raised to power of high magnitude "
+                           "(%d) overflows 64-bits\n", args[0].value,
+                           args[2].value);
+               }
+
+               isp = (dt_idsig_t *)aid->di_data;
+
+               if (isp->dis_auxinfo == 0) {
+                       /*
+                        * This is the first time we've seen an llquantize()
+                        * for this aggregation; we'll store our argument
+                        * as the auxiliary signature information.
+                        */
+                       isp->dis_auxinfo = arg;
+               } else if ((oarg = isp->dis_auxinfo) != arg) {
+                       /*
+                        * If we have seen this llquantize() before and the
+                        * argument doesn't match the original argument, pick
+                        * the original argument apart to concisely report the
+                        * mismatch.
+                        */
+                       int expected = 0, found = 0;
+
+                       for (i = 0; expected == found; i++) {
+                               assert(args[i].str != NULL);
+
+                               expected = (oarg >> args[i].shift) & UINT16_MAX;
+                               found = (arg >> args[i].shift) & UINT16_MAX;
+                       }
+
+                       dnerror(dnp, args[i - 1].mismatch, "llquantize( ) "
+                           "%s (argument #%d) doesn't match previous "
+                           "declaration: expected %d, found %d\n",
+                           args[i - 1].str, i, expected, found);
+               }
+
+               incr = llarg;
+               argmax = 6;
+       }
+
        if (fid->di_id == DTRACEAGG_QUANTIZE) {
                incr = dnp->dn_aggfun->dn_args->dn_list;
                argmax = 2;

Modified: stable/9/cddl/contrib/opensolaris/lib/libdtrace/common/dt_consume.c
==============================================================================
--- stable/9/cddl/contrib/opensolaris/lib/libdtrace/common/dt_consume.c Sun Jul 
 1 04:09:42 2012        (r237869)
+++ stable/9/cddl/contrib/opensolaris/lib/libdtrace/common/dt_consume.c Sun Jul 
 1 04:15:14 2012        (r237870)
@@ -23,6 +23,10 @@
  * Use is subject to license terms.
  */
 
+/*
+ * Copyright (c) 2011, Joyent, Inc. All rights reserved.
+ */
+
 #include <stdlib.h>
 #include <strings.h>
 #include <errno.h>
@@ -686,6 +690,121 @@ dt_print_lquantize(dtrace_hdl_t *dtp, FI
        return (0);
 }
 
+int
+dt_print_llquantize(dtrace_hdl_t *dtp, FILE *fp, const void *addr,
+    size_t size, uint64_t normal)
+{
+       int i, first_bin, last_bin, bin = 1, order, levels;
+       uint16_t factor, low, high, nsteps;
+       const int64_t *data = addr;
+       int64_t value = 1, next, step;
+       char positives = 0, negatives = 0;
+       long double total = 0;
+       uint64_t arg;
+       char c[32];
+
+       if (size < sizeof (uint64_t))
+               return (dt_set_errno(dtp, EDT_DMISMATCH));
+
+       arg = *data++;
+       size -= sizeof (uint64_t);
+
+       factor = DTRACE_LLQUANTIZE_FACTOR(arg);
+       low = DTRACE_LLQUANTIZE_LOW(arg);
+       high = DTRACE_LLQUANTIZE_HIGH(arg);
+       nsteps = DTRACE_LLQUANTIZE_NSTEP(arg);
+
+       /*
+        * We don't expect to be handed invalid llquantize() parameters here,
+        * but sanity check them (to a degree) nonetheless.
+        */
+       if (size > INT32_MAX || factor < 2 || low >= high ||
+           nsteps == 0 || factor > nsteps)
+               return (dt_set_errno(dtp, EDT_DMISMATCH));
+
+       levels = (int)size / sizeof (uint64_t);
+
+       first_bin = 0;
+       last_bin = levels - 1;
+
+       while (first_bin < levels && data[first_bin] == 0)
+               first_bin++;
+
+       if (first_bin == levels) {
+               first_bin = 0;
+               last_bin = 1;
+       } else {
+               if (first_bin > 0)
+                       first_bin--;
+
+               while (last_bin > 0 && data[last_bin] == 0)
+                       last_bin--;
+
+               if (last_bin < levels - 1)
+                       last_bin++;
+       }
+
+       for (i = first_bin; i <= last_bin; i++) {
+               positives |= (data[i] > 0);
+               negatives |= (data[i] < 0);
+               total += dt_fabsl((long double)data[i]);
+       }
+
+       if (dt_printf(dtp, fp, "\n%16s %41s %-9s\n", "value",
+           "------------- Distribution -------------", "count") < 0)
+               return (-1);
+
+       for (order = 0; order < low; order++)
+               value *= factor;
+
+       next = value * factor;
+       step = next > nsteps ? next / nsteps : 1;
+
+       if (first_bin == 0) {
+               (void) snprintf(c, sizeof (c), "< %lld", (long long)value);
+
+               if (dt_printf(dtp, fp, "%16s ", c) < 0)
+                       return (-1);
+
+               if (dt_print_quantline(dtp, fp, data[0], normal,
+                   total, positives, negatives) < 0)
+                       return (-1);
+       }
+
+       while (order <= high) {
+               if (bin >= first_bin && bin <= last_bin) {
+                       if (dt_printf(dtp, fp, "%16lld ", (long long)value) < 0)
+                               return (-1);
+
+                       if (dt_print_quantline(dtp, fp, data[bin],
+                           normal, total, positives, negatives) < 0)
+                               return (-1);
+               }
+
+               assert(value < next);
+               bin++;
+
+               if ((value += step) != next)
+                       continue;
+
+               next = value * factor;
+               step = next > nsteps ? next / nsteps : 1;
+               order++;
+       }
+
+       if (last_bin < bin)
+               return (0);
+
+       assert(last_bin == bin);
+       (void) snprintf(c, sizeof (c), ">= %lld", value);
+
+       if (dt_printf(dtp, fp, "%16s ", c) < 0)
+               return (-1);
+
+       return (dt_print_quantline(dtp, fp, data[bin], normal,
+           total, positives, negatives));
+}
+
 /*ARGSUSED*/
 static int
 dt_print_average(dtrace_hdl_t *dtp, FILE *fp, caddr_t addr,
@@ -1711,6 +1830,9 @@ dt_print_datum(dtrace_hdl_t *dtp, FILE *
        case DTRACEAGG_LQUANTIZE:
                return (dt_print_lquantize(dtp, fp, addr, size, normal));
 
+       case DTRACEAGG_LLQUANTIZE:
+               return (dt_print_llquantize(dtp, fp, addr, size, normal));
+
        case DTRACEAGG_AVG:
                return (dt_print_average(dtp, fp, addr, size, normal));
 

Modified: stable/9/cddl/contrib/opensolaris/lib/libdtrace/common/dt_errtags.h
==============================================================================
--- stable/9/cddl/contrib/opensolaris/lib/libdtrace/common/dt_errtags.h Sun Jul 
 1 04:09:42 2012        (r237869)
+++ stable/9/cddl/contrib/opensolaris/lib/libdtrace/common/dt_errtags.h Sun Jul 
 1 04:15:14 2012        (r237870)
@@ -236,6 +236,23 @@ typedef enum {
        D_LQUANT_MATCHBASE,             /* lquantize() mismatch on base */
        D_LQUANT_MATCHLIM,              /* lquantize() mismatch on limit */
        D_LQUANT_MATCHSTEP,             /* lquantize() mismatch on step */
+       D_LLQUANT_FACTORTYPE,           /* llquantize() bad magnitude type */
+       D_LLQUANT_FACTORVAL,            /* llquantize() bad magnitude value */
+       D_LLQUANT_FACTORMATCH,          /* llquantize() mismatch on magnitude */
+       D_LLQUANT_LOWTYPE,              /* llquantize() bad low mag type */
+       D_LLQUANT_LOWVAL,               /* llquantize() bad low mag value */
+       D_LLQUANT_LOWMATCH,             /* llquantize() mismatch on low mag */
+       D_LLQUANT_HIGHTYPE,             /* llquantize() bad high mag type */
+       D_LLQUANT_HIGHVAL,              /* llquantize() bad high mag value */
+       D_LLQUANT_HIGHMATCH,            /* llquantize() mismatch on high mag */
+       D_LLQUANT_NSTEPTYPE,            /* llquantize() bad # steps type */
+       D_LLQUANT_NSTEPVAL,             /* llquantize() bad # steps value */
+       D_LLQUANT_NSTEPMATCH,           /* llquantize() mismatch on # steps */
+       D_LLQUANT_MAGRANGE,             /* llquantize() bad magnitude range */
+       D_LLQUANT_FACTORNSTEPS,         /* llquantize() # steps < factor */
+       D_LLQUANT_FACTOREVEN,           /* llquantize() bad # steps/factor */
+       D_LLQUANT_FACTORSMALL,          /* llquantize() magnitude too small */
+       D_LLQUANT_MAGTOOBIG,            /* llquantize() high mag too large */
        D_PRINTM_ADDR,                  /* printm() memref bad type */
        D_PRINTM_SIZE,                  /* printm() size bad type */
        D_PRINTT_ADDR,                  /* printt() typeref bad type */

Modified: stable/9/cddl/contrib/opensolaris/lib/libdtrace/common/dt_impl.h
==============================================================================
--- stable/9/cddl/contrib/opensolaris/lib/libdtrace/common/dt_impl.h    Sun Jul 
 1 04:09:42 2012        (r237869)
+++ stable/9/cddl/contrib/opensolaris/lib/libdtrace/common/dt_impl.h    Sun Jul 
 1 04:15:14 2012        (r237870)
@@ -24,6 +24,10 @@
  * Use is subject to license terms.
  */
 
+/*
+ * Copyright (c) 2011, Joyent, Inc. All rights reserved.
+ */
+
 #ifndef        _DT_IMPL_H
 #define        _DT_IMPL_H
 
@@ -641,6 +645,8 @@ extern int dt_print_quantize(dtrace_hdl_
     const void *, size_t, uint64_t);
 extern int dt_print_lquantize(dtrace_hdl_t *, FILE *,
     const void *, size_t, uint64_t);
+extern int dt_print_llquantize(dtrace_hdl_t *, FILE *,
+    const void *, size_t, uint64_t);
 extern int dt_print_agg(const dtrace_aggdata_t *, void *);
 
 extern int dt_handle(dtrace_hdl_t *, dtrace_probedata_t *);

Modified: stable/9/cddl/contrib/opensolaris/lib/libdtrace/common/dt_open.c
==============================================================================
--- stable/9/cddl/contrib/opensolaris/lib/libdtrace/common/dt_open.c    Sun Jul 
 1 04:09:42 2012        (r237869)
+++ stable/9/cddl/contrib/opensolaris/lib/libdtrace/common/dt_open.c    Sun Jul 
 1 04:15:14 2012        (r237870)
@@ -21,6 +21,7 @@
 
 /*
  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, Joyent, Inc. All rights reserved.
  */
 
 #include <sys/types.h>
@@ -114,8 +115,9 @@
 #define        DT_VERS_1_6_1   DT_VERSION_NUMBER(1, 6, 1)
 #define        DT_VERS_1_6_2   DT_VERSION_NUMBER(1, 6, 2)
 #define        DT_VERS_1_6_3   DT_VERSION_NUMBER(1, 6, 3)
-#define        DT_VERS_LATEST  DT_VERS_1_6_3
-#define        DT_VERS_STRING  "Sun D 1.6.3"
+#define        DT_VERS_1_7     DT_VERSION_NUMBER(1, 7, 0)
+#define        DT_VERS_LATEST  DT_VERS_1_7
+#define        DT_VERS_STRING  "Sun D 1.7"
 
 const dt_version_t _dtrace_versions[] = {
        DT_VERS_1_0,    /* D API 1.0.0 (PSARC 2001/466) Solaris 10 FCS */
@@ -131,6 +133,7 @@ const dt_version_t _dtrace_versions[] = 
        DT_VERS_1_6_1,  /* D API 1.6.1 */
        DT_VERS_1_6_2,  /* D API 1.6.2 */
        DT_VERS_1_6_3,  /* D API 1.6.3 */
+       DT_VERS_1_7,    /* D API 1.7 */
        0
 };
 
@@ -287,6 +290,9 @@ static const dt_ident_t _dtrace_globals[
        &dt_idops_func, "stack(...)" },
 { "lltostr", DT_IDENT_FUNC, 0, DIF_SUBR_LLTOSTR, DT_ATTR_STABCMN, DT_VERS_1_0,
        &dt_idops_func, "string(int64_t)" },
+{ "llquantize", DT_IDENT_AGGFUNC, 0, DTRACEAGG_LLQUANTIZE, DT_ATTR_STABCMN,
+       DT_VERS_1_7, &dt_idops_func,
+       "void(@, int32_t, int32_t, int32_t, int32_t, ...)" },
 { "lquantize", DT_IDENT_AGGFUNC, 0, DTRACEAGG_LQUANTIZE,
        DT_ATTR_STABCMN, DT_VERS_1_0,
        &dt_idops_func, "void(@, int32_t, int32_t, ...)" },

Modified: stable/9/cddl/contrib/opensolaris/lib/libdtrace/common/dt_printf.c
==============================================================================
--- stable/9/cddl/contrib/opensolaris/lib/libdtrace/common/dt_printf.c  Sun Jul 
 1 04:09:42 2012        (r237869)
+++ stable/9/cddl/contrib/opensolaris/lib/libdtrace/common/dt_printf.c  Sun Jul 
 1 04:15:14 2012        (r237870)
@@ -21,6 +21,7 @@
 
 /*
  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, Joyent, Inc. All rights reserved.
  */
 
 #if defined(sun)
@@ -1322,6 +1323,14 @@ pfprint_lquantize(dtrace_hdl_t *dtp, FIL
        return (dt_print_lquantize(dtp, fp, addr, size, normal));
 }
 
+/*ARGSUSED*/
+static int
+pfprint_llquantize(dtrace_hdl_t *dtp, FILE *fp, const char *format,
+    const dt_pfargd_t *pfd, const void *addr, size_t size, uint64_t normal)
+{
+       return (dt_print_llquantize(dtp, fp, addr, size, normal));
+}
+
 static int
 dt_printf_format(dtrace_hdl_t *dtp, FILE *fp, const dt_pfargv_t *pfv,
     const dtrace_recdesc_t *recs, uint_t nrecs, const void *buf,
@@ -1507,6 +1516,9 @@ dt_printf_format(dtrace_hdl_t *dtp, FILE
                case DTRACEAGG_LQUANTIZE:
                        func = pfprint_lquantize;
                        break;
+               case DTRACEAGG_LLQUANTIZE:
+                       func = pfprint_llquantize;
+                       break;
                case DTRACEACT_MOD:
                        func = pfprint_mod;
                        break;

Modified: stable/9/cddl/contrib/opensolaris/lib/libdtrace/common/dtrace.h
==============================================================================
--- stable/9/cddl/contrib/opensolaris/lib/libdtrace/common/dtrace.h     Sun Jul 
 1 04:09:42 2012        (r237869)
+++ stable/9/cddl/contrib/opensolaris/lib/libdtrace/common/dtrace.h     Sun Jul 
 1 04:15:14 2012        (r237870)
@@ -24,11 +24,13 @@
  * Use is subject to license terms.
  */
 
+/*
+ * Copyright (c) 2011, Joyent, Inc. All rights reserved.
+ */
+
 #ifndef        _DTRACE_H
 #define        _DTRACE_H
 
-#pragma ident  "%Z%%M% %I%     %E% SMI"
-
 #include <sys/dtrace.h>
 #include <stdarg.h>
 #include <stdio.h>

Modified: stable/9/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c
==============================================================================
--- stable/9/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c    Sun Jul 
 1 04:09:42 2012        (r237869)
+++ stable/9/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c    Sun Jul 
 1 04:15:14 2012        (r237870)
@@ -1913,6 +1913,75 @@ dtrace_aggregate_lquantize(uint64_t *lqu
        lquanta[levels + 1] += incr;
 }
 
+static int
+dtrace_aggregate_llquantize_bucket(uint16_t factor, uint16_t low,
+    uint16_t high, uint16_t nsteps, int64_t value)
+{
+       int64_t this = 1, last, next;
+       int base = 1, order;
+
+       ASSERT(factor <= nsteps);
+       ASSERT(nsteps % factor == 0);
+
+       for (order = 0; order < low; order++)
+               this *= factor;
+
+       /*
+        * If our value is less than our factor taken to the power of the
+        * low order of magnitude, it goes into the zeroth bucket.
+        */
+       if (value < (last = this))
+               return (0);
+
+       for (this *= factor; order <= high; order++) {
+               int nbuckets = this > nsteps ? nsteps : this;
+
+               if ((next = this * factor) < this) {
+                       /*
+                        * We should not generally get log/linear quantizations
+                        * with a high magnitude that allows 64-bits to
+                        * overflow, but we nonetheless protect against this
+                        * by explicitly checking for overflow, and clamping
+                        * our value accordingly.
+                        */
+                       value = this - 1;
+               }
+
+               if (value < this) {
+                       /*
+                        * If our value lies within this order of magnitude,
+                        * determine its position by taking the offset within
+                        * the order of magnitude, dividing by the bucket
+                        * width, and adding to our (accumulated) base.
+                        */
+                       return (base + (value - last) / (this / nbuckets));
+               }
+
+               base += nbuckets - (nbuckets / factor);
+               last = this;
+               this = next;
+       }
+
+       /*
+        * Our value is greater than or equal to our factor taken to the
+        * power of one plus the high magnitude -- return the top bucket.
+        */
+       return (base);
+}
+
+static void
+dtrace_aggregate_llquantize(uint64_t *llquanta, uint64_t nval, uint64_t incr)
+{
+       uint64_t arg = *llquanta++;
+       uint16_t factor = DTRACE_LLQUANTIZE_FACTOR(arg);
+       uint16_t low = DTRACE_LLQUANTIZE_LOW(arg);
+       uint16_t high = DTRACE_LLQUANTIZE_HIGH(arg);
+       uint16_t nsteps = DTRACE_LLQUANTIZE_NSTEP(arg);
+
+       llquanta[dtrace_aggregate_llquantize_bucket(factor,
+           low, high, nsteps, nval)] += incr;
+}
+
 /*ARGSUSED*/
 static void
 dtrace_aggregate_avg(uint64_t *data, uint64_t nval, uint64_t arg)
@@ -9853,6 +9922,35 @@ dtrace_ecb_aggregation_create(dtrace_ecb
                break;
        }
 
+       case DTRACEAGG_LLQUANTIZE: {
+               uint16_t factor = DTRACE_LLQUANTIZE_FACTOR(desc->dtad_arg);
+               uint16_t low = DTRACE_LLQUANTIZE_LOW(desc->dtad_arg);
+               uint16_t high = DTRACE_LLQUANTIZE_HIGH(desc->dtad_arg);
+               uint16_t nsteps = DTRACE_LLQUANTIZE_NSTEP(desc->dtad_arg);
+               int64_t v;
+
+               agg->dtag_initial = desc->dtad_arg;
+               agg->dtag_aggregate = dtrace_aggregate_llquantize;
+
+               if (factor < 2 || low >= high || nsteps < factor)
+                       goto err;
+
+               /*
+                * Now check that the number of steps evenly divides a power
+                * of the factor.  (This assures both integer bucket size and
+                * linearity within each magnitude.)
+                */
+               for (v = factor; v < nsteps; v *= factor)
+                       continue;
+
+               if ((v % nsteps) || (nsteps % factor))
+                       goto err;
+
+               size = (dtrace_aggregate_llquantize_bucket(factor,
+                   low, high, nsteps, INT64_MAX) + 2) * sizeof (uint64_t);
+               break;
+       }
+
        case DTRACEAGG_AVG:
                agg->dtag_aggregate = dtrace_aggregate_avg;
                size = sizeof (uint64_t) * 2;

Modified: stable/9/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h
==============================================================================
--- stable/9/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h       Sun Jul 
 1 04:09:42 2012        (r237869)
+++ stable/9/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h       Sun Jul 
 1 04:15:14 2012        (r237870)
@@ -24,6 +24,10 @@
  * Use is subject to license terms.
  */
 
+/*
+ * Copyright (c) 2011, Joyent, Inc. All rights reserved.
+ */
+
 #ifndef _SYS_DTRACE_H
 #define        _SYS_DTRACE_H
 
@@ -481,6 +485,7 @@ typedef struct dtrace_difv {
 #define        DTRACEAGG_STDDEV                (DTRACEACT_AGGREGATION + 6)
 #define        DTRACEAGG_QUANTIZE              (DTRACEACT_AGGREGATION + 7)
 #define        DTRACEAGG_LQUANTIZE             (DTRACEACT_AGGREGATION + 8)
+#define        DTRACEAGG_LLQUANTIZE            (DTRACEACT_AGGREGATION + 9)
 
 #define        DTRACEACT_ISAGG(x)              \
        (DTRACEACT_CLASS(x) == DTRACEACT_AGGREGATION)
@@ -515,6 +520,31 @@ typedef struct dtrace_difv {
        (int32_t)(((x) & DTRACE_LQUANTIZE_BASEMASK) >> \
        DTRACE_LQUANTIZE_BASESHIFT)
 
+#define        DTRACE_LLQUANTIZE_FACTORSHIFT           48
+#define        DTRACE_LLQUANTIZE_FACTORMASK            ((uint64_t)UINT16_MAX 
<< 48)
+#define        DTRACE_LLQUANTIZE_LOWSHIFT              32
+#define        DTRACE_LLQUANTIZE_LOWMASK               ((uint64_t)UINT16_MAX 
<< 32)
+#define        DTRACE_LLQUANTIZE_HIGHSHIFT             16
+#define        DTRACE_LLQUANTIZE_HIGHMASK              ((uint64_t)UINT16_MAX 
<< 16)
+#define        DTRACE_LLQUANTIZE_NSTEPSHIFT            0
+#define        DTRACE_LLQUANTIZE_NSTEPMASK             UINT16_MAX
+
+#define        DTRACE_LLQUANTIZE_FACTOR(x)             \
+       (uint16_t)(((x) & DTRACE_LLQUANTIZE_FACTORMASK) >> \
+       DTRACE_LLQUANTIZE_FACTORSHIFT)
+
+#define        DTRACE_LLQUANTIZE_LOW(x)                \
+       (uint16_t)(((x) & DTRACE_LLQUANTIZE_LOWMASK) >> \
+       DTRACE_LLQUANTIZE_LOWSHIFT)
+
+#define        DTRACE_LLQUANTIZE_HIGH(x)               \
+       (uint16_t)(((x) & DTRACE_LLQUANTIZE_HIGHMASK) >> \
+       DTRACE_LLQUANTIZE_HIGHSHIFT)
+
+#define        DTRACE_LLQUANTIZE_NSTEP(x)              \
+       (uint16_t)(((x) & DTRACE_LLQUANTIZE_NSTEPMASK) >> \
+       DTRACE_LLQUANTIZE_NSTEPSHIFT)
+
 #define        DTRACE_USTACK_NFRAMES(x)        (uint32_t)((x) & UINT32_MAX)
 #define        DTRACE_USTACK_STRSIZE(x)        (uint32_t)((x) >> 32)
 #define        DTRACE_USTACK_ARG(x, y)         \
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-stable-9
To unsubscribe, send any mail to "[email protected]"

Reply via email to