[DTrace-devel] [PATCH 24/47] Introduce internal dt_probe_iter() function

Kris Van Hees kris.van.hees at oracle.com
Sun May 3 20:17:34 PDT 2020


DTrace provides a dtrace_probe_iter() function that can be used by
consumers to iterate over all probes, having a callback function
called for every probe that matches the provided probe description
(which can contain globbing elements).  The callback function is
passed the exact description (id, and fully specified name elements)
for a probe.

For internal purposes callback functions need to pass a pointer to
the actual dt_probe_t structure.

This patch changes the exported dtrace_probe_iter() to simply call
dt_probe_iter() which now provides the actual imeplementation of the
iterator logic.  The dt_probe_id() function accepts two possible
callback functions: one that will be called with a probe description
and one that will be called with a dt_probe_t pointer.  The callback
functions are mutually exclusive, but it is valid to not provide
either.

Orabug: 31220519
Signed-off-by: Kris Van Hees <kris.van.hees at oracle.com>
Reviewed-by: Kris Van Hees <kris.van.hees at oracle.com>
Reviewed-by: Eugene Loh <eugene.loh at oracle.com>
---
 libdtrace/dt_probe.c | 51 +++++++++++++++++++++++++++++++++++++-------
 libdtrace/dt_probe.h |  6 +++++-
 2 files changed, 48 insertions(+), 9 deletions(-)

diff --git a/libdtrace/dt_probe.c b/libdtrace/dt_probe.c
index 15c4cd64..ee344881 100644
--- a/libdtrace/dt_probe.c
+++ b/libdtrace/dt_probe.c
@@ -1064,16 +1064,19 @@ dtrace_probe_info(dtrace_hdl_t *dtp, const dtrace_probedesc_t *pdp,
 }
 
 int
-dtrace_probe_iter(dtrace_hdl_t *dtp, const dtrace_probedesc_t *pdp,
-		  dtrace_probe_f *func, void *arg)
+dt_probe_iter(dtrace_hdl_t *dtp, const dtrace_probedesc_t *pdp,
+	      dt_probe_f *pfunc, dtrace_probe_f *dfunc, void *arg)
 {
 	dtrace_probedesc_t	desc;
 	dt_probe_t		tmpl;
 	dt_probe_t		*prp;
-	int			i, rv;
+	int			i;
 	int			p_is_glob, m_is_glob, f_is_glob, n_is_glob;
+	int			rv = 0;
 	int			matches = 0;
 
+	assert(dfunc == NULL || pfunc == NULL);
+
 	/*
 	 * Special case: if no probe description is provided, we need to loop
 	 * over all registered probes.
@@ -1082,7 +1085,12 @@ dtrace_probe_iter(dtrace_hdl_t *dtp, const dtrace_probedesc_t *pdp,
 		for (i = 0; i < dtp->dt_probe_id; i++) {
 			if (!dtp->dt_probes[i])
 				continue;
-			if ((rv = func(dtp, dtp->dt_probes[i]->desc, arg)) != 0)
+			if (dfunc != NULL)
+				rv = dfunc(dtp, dtp->dt_probes[i]->desc, arg);
+			else if (pfunc != NULL)
+				rv = pfunc(dtp, dtp->dt_probes[i], arg);
+
+			if (rv != 0)
 				return rv;
 
 			matches++;
@@ -1102,7 +1110,12 @@ dtrace_probe_iter(dtrace_hdl_t *dtp, const dtrace_probedesc_t *pdp,
 		if (!prp)
 			goto done;
 
-		if ((rv = func(dtp, prp->desc, arg)) != 0)
+		if (dfunc != NULL)
+			rv = dfunc(dtp, prp->desc, arg);
+		else if (pfunc != NULL)
+			rv = pfunc(dtp, prp, arg);
+
+		if (rv != 0)
 			return rv;
 
 		matches = 1;
@@ -1126,7 +1139,12 @@ dtrace_probe_iter(dtrace_hdl_t *dtp, const dtrace_probedesc_t *pdp,
 		if (!prp)
 			goto done;
 
-		if ((rv = func(dtp, prp->desc, arg)) != 0)
+		if (dfunc != NULL)
+			rv = dfunc(dtp, prp->desc, arg);
+		else if (pfunc != NULL)
+			rv = pfunc(dtp, prp, arg);
+
+		if (rv != 0)
 			return rv;
 
 		matches = 1;
@@ -1164,7 +1182,12 @@ dtrace_probe_iter(dtrace_hdl_t *dtp, const dtrace_probedesc_t *pdp,
 			if (!dt_probe_gmatch(prp, &desc))		\
 				continue;				\
 									\
-			if ((rv = func(dtp, prp->desc, arg)) != 0)	\
+			if (dfunc != NULL)				\
+				rv = dfunc(dtp, prp->desc, arg);	\
+			else if (pfunc != NULL)				\
+				rv = pfunc(dtp, prp, arg);		\
+									\
+			if (rv != 0)					\
 				return rv;				\
 									\
 			matches++;					\
@@ -1190,7 +1213,12 @@ dtrace_probe_iter(dtrace_hdl_t *dtp, const dtrace_probedesc_t *pdp,
 		if (!dt_probe_gmatch(prp, &desc))
 			continue;
 
-		if ((rv = func(dtp, prp->desc, arg)) != 0)
+		if (dfunc != NULL)
+			rv = dfunc(dtp, prp->desc, arg);
+		else if (pfunc != NULL)
+			rv = pfunc(dtp, prp, arg);
+
+		if (rv != 0)
 			return rv;
 
 		matches++;
@@ -1201,6 +1229,13 @@ done:
 		       : dt_set_errno(dtp, EDT_NOPROBE);
 }
 
+int
+dtrace_probe_iter(dtrace_hdl_t *dtp, const dtrace_probedesc_t *pdp,
+		  dtrace_probe_f *func, void *arg)
+{
+	return dt_probe_iter(dtp, pdp, NULL, func, arg);
+}
+
 void
 dt_probe_init(dtrace_hdl_t *dtp)
 {
diff --git a/libdtrace/dt_probe.h b/libdtrace/dt_probe.h
index a0e4133e..5814836b 100644
--- a/libdtrace/dt_probe.h
+++ b/libdtrace/dt_probe.h
@@ -1,6 +1,6 @@
 /*
  * Oracle Linux DTrace.
- * Copyright (c) 2006, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2020, Oracle and/or its affiliates. All rights reserved.
  * Licensed under the Universal Permissive License v 1.0 as shown at
  * http://oss.oracle.com/licenses/upl.
  */
@@ -77,6 +77,10 @@ extern dt_probe_t *dt_probe_lookup(dtrace_hdl_t *dtp,
 extern dt_probe_t *dt_probe_lookup_by_name(dtrace_hdl_t *dtp, const char *name);
 extern void dt_probe_delete(dtrace_hdl_t *dtp, dt_probe_t *prp);
 
+typedef int dt_probe_f(dtrace_hdl_t *dtp, const dt_probe_t *prp, void *arg);
+extern int dt_probe_iter(dtrace_hdl_t *dtp, const dtrace_probedesc_t *pdp,
+			 dt_probe_f *pfunc, dtrace_probe_f *dfunc, void *arg);
+
 extern void dt_probe_init(dtrace_hdl_t *dtp);
 extern void dt_probe_stats(dtrace_hdl_t *dtp);
 
-- 
2.26.0




More information about the DTrace-devel mailing list