svn commit: r237870 - in stable/9: cddl/contrib/opensolaris/lib/libdtrace/common sys/cddl/contrib/opensolaris/uts/common/dtrace sys/cddl/contrib/opensolaris/uts/common/sys

Pedro F. Giffuni pfg at FreeBSD.org
Sun Jul 1 04:15:15 UTC 2012


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)		\


More information about the svn-src-stable-9 mailing list