linux-trace-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Yordan Karadzhov (VMware)" <y.karadz@gmail.com>
To: linux-trace-devel@vger.kernel.org
Cc: "Yordan Karadzhov (VMware)" <y.karadz@gmail.com>
Subject: [PATCH 4/5] trace-cruncher: Add APIs for histogram control
Date: Tue,  7 Dec 2021 16:28:10 +0200	[thread overview]
Message-ID: <20211207142811.398929-5-y.karadz@gmail.com> (raw)
In-Reply-To: <20211207142811.398929-1-y.karadz@gmail.com>

This is an almost direct wrapping of the corresponding APIs defined in
libtracefs. The 'continue' API (tracefs_hist_continue()) gets renamed
to resume(), because 'continue' is a keyword in Python.

Signed-off-by: Yordan Karadzhov (VMware) <y.karadz@gmail.com>
---
 src/ftracepy-utils.c | 202 ++++++++++++++++++++++++++++++++++---------
 src/ftracepy-utils.h |  18 ++++
 src/ftracepy.c       |  30 +++++++
 3 files changed, 207 insertions(+), 43 deletions(-)

diff --git a/src/ftracepy-utils.c b/src/ftracepy-utils.c
index d7e6d6a..a735d88 100644
--- a/src/ftracepy-utils.c
+++ b/src/ftracepy-utils.c
@@ -836,6 +836,165 @@ PyObject *PyTraceHist_sort_key_direction(PyTraceHist *self, PyObject *args,
 	Py_RETURN_NONE;
 }
 
+static bool get_optional_instance(PyObject *py_obj,
+				  struct tracefs_instance **instance)
+{
+	PyTfsInstance *py_inst;
+
+	if (!py_obj) {
+		*instance = NULL;
+		return true;
+	}
+
+	if (!PyTfsInstance_Check(py_obj)) {
+		PyErr_SetString(TRACECRUNCHER_ERROR,
+				"Passing argument \'instance\' with incompatible type.");
+		return false;
+	}
+
+	py_inst = (PyTfsInstance *)py_obj;
+	*instance = py_inst->ptrObj;
+
+	return true;
+}
+
+bool get_instance_from_arg(PyObject *args, PyObject *kwargs,
+			   struct tracefs_instance **instance)
+{
+	static char *kwlist[] = {"instance", NULL};
+	PyObject *py_inst = NULL;
+	*instance = NULL;
+
+	if (!PyArg_ParseTupleAndKeywords(args,
+					 kwargs,
+					 "|O",
+					 kwlist,
+					 &py_inst)) {
+		return false;
+	}
+
+	if (!get_optional_instance(py_inst, instance))
+		return NULL;
+
+	return true;
+}
+
+static bool hist_cmd(PyTraceHist *self, PyObject *args, PyObject *kwargs,
+		     enum tracefs_hist_command cmd,
+		     const char *err_msg)
+{
+	struct tracefs_instance *instance;
+
+	if (!get_instance_from_arg(args, kwargs, &instance))
+		return NULL;
+
+	if (tracefs_hist_command(instance, self->ptrObj, cmd) < 0) {
+		char *buff;
+
+		if (asprintf(&buff, "%s %s",
+			     err_msg, get_hist_name(self->ptrObj)) <= 0) {
+			MEM_ERROR;
+			return false;
+		}
+
+		TfsError_setstr(instance, buff);
+		free(buff);
+
+		return false;
+	}
+
+	return true;
+}
+
+PyObject *PyTraceHist_start(PyTraceHist *self, PyObject *args,
+					       PyObject *kwargs)
+{
+	if (!hist_cmd(self, args, kwargs,
+		      TRACEFS_HIST_CMD_START,
+		      "Failed to start filling the histogram"))
+		return false;
+
+	Py_RETURN_NONE;
+}
+
+PyObject *PyTraceHist_stop(PyTraceHist *self, PyObject *args,
+					      PyObject *kwargs)
+{
+	if (!hist_cmd(self, args, kwargs,
+		      TRACEFS_HIST_CMD_PAUSE,
+		      "Failed to stop filling the histogram"))
+		return false;
+
+	Py_RETURN_NONE;
+}
+
+PyObject *PyTraceHist_resume(PyTraceHist *self, PyObject *args,
+						PyObject *kwargs)
+{
+	if (!hist_cmd(self, args, kwargs,
+		      TRACEFS_HIST_CMD_CONT,
+		      "Failed to resume filling the histogram"))
+		return false;
+
+	Py_RETURN_NONE;
+}
+
+PyObject *PyTraceHist_clear(PyTraceHist *self, PyObject *args,
+					       PyObject *kwargs)
+{
+	if (!hist_cmd(self, args, kwargs,
+		      TRACEFS_HIST_CMD_CLEAR,
+		      "Failed to clear the histogram"))
+		return false;
+
+	Py_RETURN_NONE;
+}
+
+static char *hist_read(PyTraceHist *self, PyObject *args,
+					  PyObject *kwargs)
+{
+	struct tracefs_instance *instance;
+	const char *hist_file = "hist";
+	char *data;
+
+	if (!get_instance_from_arg(args, kwargs, &instance))
+		return NULL;
+
+	data = tracefs_event_file_read(instance,
+				       tracefs_hist_get_system(self->ptrObj),
+				       tracefs_hist_get_event(self->ptrObj),
+				       hist_file,
+				       NULL);
+	if (!data) {
+		TfsError_fmt(instance,
+			     "Failed read data from histogram \'%s\'.",
+			     get_hist_name(self->ptrObj));
+	}
+
+	return data;
+}
+
+PyObject *PyTraceHist_read(PyTraceHist *self, PyObject *args,
+					      PyObject *kwargs)
+{
+	char *data = hist_read(self, args, kwargs);
+	PyObject *ret = PyUnicode_FromString(data);
+
+	free(data);
+	return ret;
+}
+
+PyObject *PyTraceHist_close(PyTraceHist *self, PyObject *args,
+					       PyObject *kwargs)
+{
+	if (!hist_cmd(self, args, kwargs,
+		      TRACEFS_HIST_CMD_DESTROY,
+		      "Failed to close the histogram"))
+		return false;
+
+	Py_RETURN_NONE;
+}
+
 PyObject *PyFtrace_dir(PyObject *self)
 {
 	return PyUnicode_FromString(tracefs_tracing_dir());
@@ -967,49 +1126,6 @@ PyObject *PyFtrace_find_instance(PyObject *self, PyObject *args,
 	return py_inst;
 }
 
-static bool get_optional_instance(PyObject *py_obj,
-				  struct tracefs_instance **instance)
-{
-	PyTfsInstance *py_inst;
-
-	if (!py_obj) {
-		*instance = NULL;
-		return true;
-	}
-
-	if (!PyTfsInstance_Check(py_obj)) {
-		PyErr_SetString(TRACECRUNCHER_ERROR,
-				"Passing argument \'instance\' with incompatible type.");
-		return false;
-	}
-
-	py_inst = (PyTfsInstance *)py_obj;
-	*instance = py_inst->ptrObj;
-
-	return true;
-}
-
-bool get_instance_from_arg(PyObject *args, PyObject *kwargs,
-			   struct tracefs_instance **instance)
-{
-	static char *kwlist[] = {"instance", NULL};
-	PyObject *py_inst = NULL;
-	*instance = NULL;
-
-	if (!PyArg_ParseTupleAndKeywords(args,
-					 kwargs,
-					 "|O",
-					 kwlist,
-					 &py_inst)) {
-		return false;
-	}
-
-	if (!get_optional_instance(py_inst, instance))
-		return NULL;
-
-	return true;
-}
-
 PyObject *PyFtrace_available_tracers(PyObject *self, PyObject *args,
 						     PyObject *kwargs)
 {
diff --git a/src/ftracepy-utils.h b/src/ftracepy-utils.h
index 07d2cac..d09c8bf 100644
--- a/src/ftracepy-utils.h
+++ b/src/ftracepy-utils.h
@@ -101,6 +101,24 @@ PyObject *PyTraceHist_sort_keys(PyTraceHist *self, PyObject *args,
 PyObject *PyTraceHist_sort_key_direction(PyTraceHist *self, PyObject *args,
 							    PyObject *kwargs);
 
+PyObject *PyTraceHist_start(PyTraceHist *self, PyObject *args,
+					       PyObject *kwargs);
+
+PyObject *PyTraceHist_stop(PyTraceHist *self, PyObject *args,
+					      PyObject *kwargs);
+
+PyObject *PyTraceHist_resume(PyTraceHist *self, PyObject *args,
+						PyObject *kwargs);
+
+PyObject *PyTraceHist_clear(PyTraceHist *self, PyObject *args,
+					       PyObject *kwargs);
+
+PyObject *PyTraceHist_read(PyTraceHist *self, PyObject *args,
+					      PyObject *kwargs);
+
+PyObject *PyTraceHist_close(PyTraceHist *self, PyObject *args,
+					       PyObject *kwargs);
+
 PyObject *PyFtrace_dir(PyObject *self);
 
 PyObject *PyFtrace_detach(PyObject *self, PyObject *args, PyObject *kwargs);
diff --git a/src/ftracepy.c b/src/ftracepy.c
index b91cda9..b270b71 100644
--- a/src/ftracepy.c
+++ b/src/ftracepy.c
@@ -184,6 +184,36 @@ static PyMethodDef PyTraceHist_methods[] = {
 	 METH_VARARGS | METH_KEYWORDS,
 	 "Set the direction of a sort key field."
 	},
+	{"start",
+	 (PyCFunction) PyTraceHist_start,
+	 METH_VARARGS | METH_KEYWORDS,
+	 "Start acquiring data."
+	},
+	{"stop",
+	 (PyCFunction) PyTraceHist_stop,
+	 METH_VARARGS | METH_KEYWORDS,
+	 "Pause acquiring data."
+	},
+	{"resume",
+	 (PyCFunction) PyTraceHist_resume,
+	 METH_VARARGS | METH_KEYWORDS,
+	 "Continue acquiring data."
+	},
+	{"clear",
+	 (PyCFunction) PyTraceHist_clear,
+	 METH_VARARGS | METH_KEYWORDS,
+	 "Reset the histogram."
+	},
+	{"read",
+	 (PyCFunction) PyTraceHist_read,
+	 METH_VARARGS | METH_KEYWORDS,
+	 "Read the content of the histogram."
+	},
+	{"close",
+	 (PyCFunction) PyTraceHist_close,
+	 METH_VARARGS | METH_KEYWORDS,
+	 "Destroy the histogram."
+	},
 	{NULL, NULL, 0, NULL}
 };
 
-- 
2.32.0


  parent reply	other threads:[~2021-12-07 14:29 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-12-07 14:28 [PATCH 0/5] trace-cruncher: Kernel histograms Yordan Karadzhov (VMware)
2021-12-07 14:28 ` [PATCH 1/5] trace-cruncher: Define Python type for trace histograms Yordan Karadzhov (VMware)
2021-12-07 14:28 ` [PATCH 2/5] trace-cruncher: Define constructor " Yordan Karadzhov (VMware)
2021-12-07 14:28 ` [PATCH 3/5] trace-cruncher: Add APIs to setup a histogram Yordan Karadzhov (VMware)
2021-12-07 14:28 ` Yordan Karadzhov (VMware) [this message]
2021-12-07 14:28 ` [PATCH 5/5] trace-cruncher: Add kernel histogram example Yordan Karadzhov (VMware)

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20211207142811.398929-5-y.karadz@gmail.com \
    --to=y.karadz@gmail.com \
    --cc=linux-trace-devel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).