[DTrace-devel] [PATCH 5/6] Implement aggrate-based aggregation snapshots

Kris Van Hees kris.van.hees at oracle.com
Wed Feb 22 15:17:24 UTC 2023


Some aggregation operations like clear() depend on aggregation snapshot
frequency.

Signed-off-by: Kris Van Hees <kris.van.hees at oracle.com>
---
 libdtrace/dt_aggregate.c | 19 ++++++++++++++++++-
 libdtrace/dt_consume.c   |  1 +
 libdtrace/dt_impl.h      |  1 +
 libdtrace/dt_open.c      |  1 +
 libdtrace/dt_work.c      |  5 +++++
 5 files changed, 26 insertions(+), 1 deletion(-)

diff --git a/libdtrace/dt_aggregate.c b/libdtrace/dt_aggregate.c
index 41fa0da1..2129c867 100644
--- a/libdtrace/dt_aggregate.c
+++ b/libdtrace/dt_aggregate.c
@@ -608,15 +608,32 @@ dt_aggregate_snap_cpu(dtrace_hdl_t *dtp, processorid_t cpu, int fd)
 int
 dtrace_aggregate_snap(dtrace_hdl_t *dtp)
 {
+	dtrace_optval_t	interval = dtp->dt_options[DTRACEOPT_AGGRATE];
 	dt_aggregate_t	*agp = &dtp->dt_aggregate;
+	hrtime_t	now = gethrtime();
 	int		i, rval;
 
+	/* Has tracing started yet? */
+	if (!dtp->dt_active)
+		return dt_set_errno(dtp, EINVAL);
+
 	/*
 	 * If we do not have a buffer initialized, we will not be processing
 	 * aggregations, so there is nothing to be done here.
 	 */
 	if (agp->dtat_buf == NULL)
-		return 0;
+		return DTRACE_WORKSTATUS_OKAY;
+
+	/* Do not retrieve at a rate higher than 'aggrate'. */
+	if (interval > 0) {
+		if (dtp->dt_lastagg != 0) {
+			if (now - dtp->dt_lastagg < interval)
+				return DTRACE_WORKSTATUS_OKAY;
+
+			dtp->dt_lastagg += interval;
+		} else
+			dtp->dt_lastagg = now;
+	}
 
 	dtrace_aggregate_clear(dtp);
 
diff --git a/libdtrace/dt_consume.c b/libdtrace/dt_consume.c
index 1c2223be..34009e6b 100644
--- a/libdtrace/dt_consume.c
+++ b/libdtrace/dt_consume.c
@@ -3058,6 +3058,7 @@ dtrace_consume(dtrace_hdl_t *dtp, FILE *fp, dtrace_consume_probe_f *pf,
 			return rval;
 
 		/* Force data retrieval since BEGIN was processed. */
+		dtp->dt_lastagg = 0;
 		dtp->dt_lastswitch = 0;
 	}
 
diff --git a/libdtrace/dt_impl.h b/libdtrace/dt_impl.h
index e9e4bbcf..9edef5ab 100644
--- a/libdtrace/dt_impl.h
+++ b/libdtrace/dt_impl.h
@@ -392,6 +392,7 @@ struct dtrace_hdl {
 	dtrace_status_t dt_status[2]; /* status cache */
 	int dt_statusgen;	/* current status generation */
 	hrtime_t dt_lastswitch;	/* last switch of buffer data */
+	hrtime_t dt_lastagg;	/* last snapshot of aggregation data */
 	dt_list_t dt_spec_bufs_draining; /* List of spec bufs being drained */
 	dt_htab_t *dt_spec_bufs;/* spec ID -> list of dt_spec_bufs_head_t */
 	char *dt_sprintf_buf;	/* buffer for dtrace_sprintf() */
diff --git a/libdtrace/dt_open.c b/libdtrace/dt_open.c
index f282c900..d01bc9df 100644
--- a/libdtrace/dt_open.c
+++ b/libdtrace/dt_open.c
@@ -800,6 +800,7 @@ dt_vopen(int version, int flags, int *errp,
 	 * Set the default data rates.
 	 */
 	dtp->dt_options[DTRACEOPT_SWITCHRATE] = NANOSEC;
+	dtp->dt_options[DTRACEOPT_AGGRATE] = NANOSEC;
 
 	dtp->dt_cpp_argv[0] = (char *)strbasename(dtp->dt_cpp_path);
 
diff --git a/libdtrace/dt_work.c b/libdtrace/dt_work.c
index f1292761..9f79d875 100644
--- a/libdtrace/dt_work.c
+++ b/libdtrace/dt_work.c
@@ -174,6 +174,7 @@ dtrace_work(dtrace_hdl_t *dtp, FILE *fp, dtrace_consume_probe_f *pfunc,
 	case DTRACE_STATUS_EXITED:
 	case DTRACE_STATUS_STOPPED:
 		dtp->dt_lastswitch = 0;
+		dtp->dt_lastagg = 0;
 		rval = DTRACE_WORKSTATUS_DONE;
 		break;
 	case DTRACE_STATUS_NONE:
@@ -184,6 +185,10 @@ dtrace_work(dtrace_hdl_t *dtp, FILE *fp, dtrace_consume_probe_f *pfunc,
 		return DTRACE_WORKSTATUS_ERROR;
 	}
 
+	if (dtrace_aggregate_snap(dtp) ==
+	    DTRACE_WORKSTATUS_ERROR)
+		return DTRACE_WORKSTATUS_ERROR;
+
 	if (dtrace_consume(dtp, fp, pfunc, rfunc, arg) ==
 	    DTRACE_WORKSTATUS_ERROR)
 		return DTRACE_WORKSTATUS_ERROR;
-- 
2.39.1




More information about the DTrace-devel mailing list