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
next prev 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).