From owner-svn-src-stable@FreeBSD.ORG Sun Jul 1 04:26:52 2012 Return-Path: Delivered-To: svn-src-stable@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 69408106564A; Sun, 1 Jul 2012 04:26:52 +0000 (UTC) (envelope-from pfg@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 4EAFC8FC12; Sun, 1 Jul 2012 04:26:52 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id q614QqZh065300; Sun, 1 Jul 2012 04:26:52 GMT (envelope-from pfg@svn.freebsd.org) Received: (from pfg@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q614QqjI065289; Sun, 1 Jul 2012 04:26:52 GMT (envelope-from pfg@svn.freebsd.org) Message-Id: <201207010426.q614QqjI065289@svn.freebsd.org> From: "Pedro F. Giffuni" Date: Sun, 1 Jul 2012 04:26:52 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org X-SVN-Group: stable-8 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r237872 - in stable/8: cddl/contrib/opensolaris/lib/libdtrace/common sys/cddl/contrib/opensolaris/uts/common/dtrace sys/cddl/contrib/opensolaris/uts/common/sys X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 01 Jul 2012 04:26:52 -0000 Author: pfg Date: Sun Jul 1 04:26:51 2012 New Revision: 237872 URL: http://svn.freebsd.org/changeset/base/237872 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. Illumos Revision: 13355:15b74a2a9a9d Reference: https://www.illumos/issues/905 Obtained from: Illumos Added: - copied from r237868, head/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/ Directory Properties: stable/8/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/llquantize/ (props changed) Modified: stable/8/cddl/contrib/opensolaris/lib/libdtrace/common/dt_aggregate.c stable/8/cddl/contrib/opensolaris/lib/libdtrace/common/dt_cc.c stable/8/cddl/contrib/opensolaris/lib/libdtrace/common/dt_consume.c stable/8/cddl/contrib/opensolaris/lib/libdtrace/common/dt_errtags.h stable/8/cddl/contrib/opensolaris/lib/libdtrace/common/dt_impl.h stable/8/cddl/contrib/opensolaris/lib/libdtrace/common/dt_open.c stable/8/cddl/contrib/opensolaris/lib/libdtrace/common/dt_printf.c stable/8/cddl/contrib/opensolaris/lib/libdtrace/common/dtrace.h stable/8/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c stable/8/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h Directory Properties: stable/8/cddl/ (props changed) stable/8/cddl/contrib/opensolaris/ (props changed) stable/8/sys/ (props changed) stable/8/sys/cddl/ (props changed) stable/8/sys/cddl/contrib/opensolaris/ (props changed) Modified: stable/8/cddl/contrib/opensolaris/lib/libdtrace/common/dt_aggregate.c ============================================================================== --- stable/8/cddl/contrib/opensolaris/lib/libdtrace/common/dt_aggregate.c Sun Jul 1 04:25:49 2012 (r237871) +++ stable/8/cddl/contrib/opensolaris/lib/libdtrace/common/dt_aggregate.c Sun Jul 1 04:26:51 2012 (r237872) @@ -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 #include @@ -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/8/cddl/contrib/opensolaris/lib/libdtrace/common/dt_cc.c ============================================================================== --- stable/8/cddl/contrib/opensolaris/lib/libdtrace/common/dt_cc.c Sun Jul 1 04:25:49 2012 (r237871) +++ stable/8/cddl/contrib/opensolaris/lib/libdtrace/common/dt_cc.c Sun Jul 1 04:26:51 2012 (r237872) @@ -82,6 +82,7 @@ #include #include +#include #include #include @@ -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/8/cddl/contrib/opensolaris/lib/libdtrace/common/dt_consume.c ============================================================================== --- stable/8/cddl/contrib/opensolaris/lib/libdtrace/common/dt_consume.c Sun Jul 1 04:25:49 2012 (r237871) +++ stable/8/cddl/contrib/opensolaris/lib/libdtrace/common/dt_consume.c Sun Jul 1 04:26:51 2012 (r237872) @@ -23,6 +23,10 @@ * Use is subject to license terms. */ +/* + * Copyright (c) 2011, Joyent, Inc. All rights reserved. + */ + #include #include #include @@ -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, @@ -1710,6 +1829,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/8/cddl/contrib/opensolaris/lib/libdtrace/common/dt_errtags.h ============================================================================== --- stable/8/cddl/contrib/opensolaris/lib/libdtrace/common/dt_errtags.h Sun Jul 1 04:25:49 2012 (r237871) +++ stable/8/cddl/contrib/opensolaris/lib/libdtrace/common/dt_errtags.h Sun Jul 1 04:26:51 2012 (r237872) @@ -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/8/cddl/contrib/opensolaris/lib/libdtrace/common/dt_impl.h ============================================================================== --- stable/8/cddl/contrib/opensolaris/lib/libdtrace/common/dt_impl.h Sun Jul 1 04:25:49 2012 (r237871) +++ stable/8/cddl/contrib/opensolaris/lib/libdtrace/common/dt_impl.h Sun Jul 1 04:26:51 2012 (r237872) @@ -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/8/cddl/contrib/opensolaris/lib/libdtrace/common/dt_open.c ============================================================================== --- stable/8/cddl/contrib/opensolaris/lib/libdtrace/common/dt_open.c Sun Jul 1 04:25:49 2012 (r237871) +++ stable/8/cddl/contrib/opensolaris/lib/libdtrace/common/dt_open.c Sun Jul 1 04:26:51 2012 (r237872) @@ -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 @@ -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/8/cddl/contrib/opensolaris/lib/libdtrace/common/dt_printf.c ============================================================================== --- stable/8/cddl/contrib/opensolaris/lib/libdtrace/common/dt_printf.c Sun Jul 1 04:25:49 2012 (r237871) +++ stable/8/cddl/contrib/opensolaris/lib/libdtrace/common/dt_printf.c Sun Jul 1 04:26:51 2012 (r237872) @@ -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/8/cddl/contrib/opensolaris/lib/libdtrace/common/dtrace.h ============================================================================== --- stable/8/cddl/contrib/opensolaris/lib/libdtrace/common/dtrace.h Sun Jul 1 04:25:49 2012 (r237871) +++ stable/8/cddl/contrib/opensolaris/lib/libdtrace/common/dtrace.h Sun Jul 1 04:26:51 2012 (r237872) @@ -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 #include #include Modified: stable/8/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c ============================================================================== --- stable/8/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c Sun Jul 1 04:25:49 2012 (r237871) +++ stable/8/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c Sun Jul 1 04:26:51 2012 (r237872) @@ -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/8/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h ============================================================================== --- stable/8/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h Sun Jul 1 04:25:49 2012 (r237871) +++ stable/8/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h Sun Jul 1 04:26:51 2012 (r237872) @@ -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) \