All of lore.kernel.org
 help / color / mirror / Atom feed
From: tip-bot for Adrian Hunter <tipbot@zytor.com>
To: linux-tip-commits@vger.kernel.org
Cc: acme@redhat.com, linux-kernel@vger.kernel.org,
	eranian@google.com, paulus@samba.org, hpa@zytor.com,
	mingo@kernel.org, peterz@infradead.org, namhyung@gmail.com,
	jolsa@redhat.com, fweisbec@gmail.com, adrian.hunter@intel.com,
	dsahern@gmail.com, tglx@linutronix.de
Subject: [tip:perf/core] perf script python: Add helpers for calling Python objects
Date: Thu, 14 Aug 2014 01:51:16 -0700	[thread overview]
Message-ID: <tip-a5563edfa1bd25d052d81f5ad7fe74ba71c3d44e@git.kernel.org> (raw)
In-Reply-To: <1406786474-9306-19-git-send-email-adrian.hunter@intel.com>

Commit-ID:  a5563edfa1bd25d052d81f5ad7fe74ba71c3d44e
Gitweb:     http://git.kernel.org/tip/a5563edfa1bd25d052d81f5ad7fe74ba71c3d44e
Author:     Adrian Hunter <adrian.hunter@intel.com>
AuthorDate: Thu, 31 Jul 2014 09:01:01 +0300
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Wed, 13 Aug 2014 19:22:01 -0300

perf script python: Add helpers for calling Python objects

The Python script API repeatedly uses the same lines of code to get and
call objects.  Make that into helper functions instead.

A side-effect is that some reference counting bugs disappear because the
new call_object() function always decrements the reference count of
'retval'.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/r/1406786474-9306-19-git-send-email-adrian.hunter@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 .../util/scripting-engines/trace-event-python.c    | 114 +++++++++------------
 1 file changed, 47 insertions(+), 67 deletions(-)

diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c
index cbce254..26e5f14 100644
--- a/tools/perf/util/scripting-engines/trace-event-python.c
+++ b/tools/perf/util/scripting-engines/trace-event-python.c
@@ -73,6 +73,35 @@ static void pydict_set_item_string_decref(PyObject *dict, const char *key, PyObj
 	Py_DECREF(val);
 }
 
+static PyObject *get_handler(const char *handler_name)
+{
+	PyObject *handler;
+
+	handler = PyDict_GetItemString(main_dict, handler_name);
+	if (handler && !PyCallable_Check(handler))
+		return NULL;
+	return handler;
+}
+
+static void call_object(PyObject *handler, PyObject *args, const char *die_msg)
+{
+	PyObject *retval;
+
+	retval = PyObject_CallObject(handler, args);
+	if (retval == NULL)
+		handler_call_die(die_msg);
+	Py_DECREF(retval);
+}
+
+static void try_call_object(const char *handler_name, PyObject *args)
+{
+	PyObject *handler;
+
+	handler = get_handler(handler_name);
+	if (handler)
+		call_object(handler, args, handler_name);
+}
+
 static void define_value(enum print_arg_type field_type,
 			 const char *ev_name,
 			 const char *field_name,
@@ -80,7 +109,7 @@ static void define_value(enum print_arg_type field_type,
 			 const char *field_str)
 {
 	const char *handler_name = "define_flag_value";
-	PyObject *handler, *t, *retval;
+	PyObject *t;
 	unsigned long long value;
 	unsigned n = 0;
 
@@ -98,13 +127,7 @@ static void define_value(enum print_arg_type field_type,
 	PyTuple_SetItem(t, n++, PyInt_FromLong(value));
 	PyTuple_SetItem(t, n++, PyString_FromString(field_str));
 
-	handler = PyDict_GetItemString(main_dict, handler_name);
-	if (handler && PyCallable_Check(handler)) {
-		retval = PyObject_CallObject(handler, t);
-		if (retval == NULL)
-			handler_call_die(handler_name);
-		Py_DECREF(retval);
-	}
+	try_call_object(handler_name, t);
 
 	Py_DECREF(t);
 }
@@ -127,7 +150,7 @@ static void define_field(enum print_arg_type field_type,
 			 const char *delim)
 {
 	const char *handler_name = "define_flag_field";
-	PyObject *handler, *t, *retval;
+	PyObject *t;
 	unsigned n = 0;
 
 	if (field_type == PRINT_SYMBOL)
@@ -145,13 +168,7 @@ static void define_field(enum print_arg_type field_type,
 	if (field_type == PRINT_FLAGS)
 		PyTuple_SetItem(t, n++, PyString_FromString(delim));
 
-	handler = PyDict_GetItemString(main_dict, handler_name);
-	if (handler && PyCallable_Check(handler)) {
-		retval = PyObject_CallObject(handler, t);
-		if (retval == NULL)
-			handler_call_die(handler_name);
-		Py_DECREF(retval);
-	}
+	try_call_object(handler_name, t);
 
 	Py_DECREF(t);
 }
@@ -362,7 +379,7 @@ static void python_process_tracepoint(struct perf_sample *sample,
 				      struct thread *thread,
 				      struct addr_location *al)
 {
-	PyObject *handler, *retval, *context, *t, *obj, *callchain;
+	PyObject *handler, *context, *t, *obj, *callchain;
 	PyObject *dict = NULL;
 	static char handler_name[256];
 	struct format_field *field;
@@ -387,9 +404,7 @@ static void python_process_tracepoint(struct perf_sample *sample,
 
 	sprintf(handler_name, "%s__%s", event->system, event->name);
 
-	handler = PyDict_GetItemString(main_dict, handler_name);
-	if (handler && !PyCallable_Check(handler))
-		handler = NULL;
+	handler = get_handler(handler_name);
 	if (!handler) {
 		dict = PyDict_New();
 		if (!dict)
@@ -450,19 +465,9 @@ static void python_process_tracepoint(struct perf_sample *sample,
 		Py_FatalError("error resizing Python tuple");
 
 	if (handler) {
-		retval = PyObject_CallObject(handler, t);
-		if (retval == NULL)
-			handler_call_die(handler_name);
-		Py_DECREF(retval);
+		call_object(handler, t, handler_name);
 	} else {
-		handler = PyDict_GetItemString(main_dict, "trace_unhandled");
-		if (handler && PyCallable_Check(handler)) {
-
-			retval = PyObject_CallObject(handler, t);
-			if (retval == NULL)
-				handler_call_die("trace_unhandled");
-			Py_DECREF(retval);
-		}
+		try_call_object("trace_unhandled", t);
 		Py_DECREF(dict);
 	}
 
@@ -474,7 +479,7 @@ static void python_process_general_event(struct perf_sample *sample,
 					 struct thread *thread,
 					 struct addr_location *al)
 {
-	PyObject *handler, *retval, *t, *dict, *callchain, *dict_sample;
+	PyObject *handler, *t, *dict, *callchain, *dict_sample;
 	static char handler_name[64];
 	unsigned n = 0;
 
@@ -496,8 +501,8 @@ static void python_process_general_event(struct perf_sample *sample,
 
 	snprintf(handler_name, sizeof(handler_name), "%s", "process_event");
 
-	handler = PyDict_GetItemString(main_dict, handler_name);
-	if (!handler || !PyCallable_Check(handler))
+	handler = get_handler(handler_name);
+	if (!handler)
 		goto exit;
 
 	pydict_set_item_string_decref(dict, "ev_name", PyString_FromString(perf_evsel__name(evsel)));
@@ -539,10 +544,7 @@ static void python_process_general_event(struct perf_sample *sample,
 	if (_PyTuple_Resize(&t, n) == -1)
 		Py_FatalError("error resizing Python tuple");
 
-	retval = PyObject_CallObject(handler, t);
-	if (retval == NULL)
-		handler_call_die(handler_name);
-	Py_DECREF(retval);
+	call_object(handler, t, handler_name);
 exit:
 	Py_DECREF(dict);
 	Py_DECREF(t);
@@ -566,36 +568,24 @@ static void python_process_event(union perf_event *event __maybe_unused,
 
 static int run_start_sub(void)
 {
-	PyObject *handler, *retval;
-	int err = 0;
-
 	main_module = PyImport_AddModule("__main__");
 	if (main_module == NULL)
 		return -1;
 	Py_INCREF(main_module);
 
 	main_dict = PyModule_GetDict(main_module);
-	if (main_dict == NULL) {
-		err = -1;
+	if (main_dict == NULL)
 		goto error;
-	}
 	Py_INCREF(main_dict);
 
-	handler = PyDict_GetItemString(main_dict, "trace_begin");
-	if (handler == NULL || !PyCallable_Check(handler))
-		goto out;
+	try_call_object("trace_begin", NULL);
 
-	retval = PyObject_CallObject(handler, NULL);
-	if (retval == NULL)
-		handler_call_die("trace_begin");
+	return 0;
 
-	Py_DECREF(retval);
-	return err;
 error:
 	Py_XDECREF(main_dict);
 	Py_XDECREF(main_module);
-out:
-	return err;
+	return -1;
 }
 
 /*
@@ -654,23 +644,13 @@ error:
  */
 static int python_stop_script(void)
 {
-	PyObject *handler, *retval;
-	int err = 0;
+	try_call_object("trace_end", NULL);
 
-	handler = PyDict_GetItemString(main_dict, "trace_end");
-	if (handler == NULL || !PyCallable_Check(handler))
-		goto out;
-
-	retval = PyObject_CallObject(handler, NULL);
-	if (retval == NULL)
-		handler_call_die("trace_end");
-	Py_DECREF(retval);
-out:
 	Py_XDECREF(main_dict);
 	Py_XDECREF(main_module);
 	Py_Finalize();
 
-	return err;
+	return 0;
 }
 
 static int python_generate_script(struct pevent *pevent, const char *outfile)

  reply	other threads:[~2014-08-14  8:52 UTC|newest]

Thread overview: 47+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-07-31  6:00 [PATCH 00/31] perf tools: Yet more preparation for call graph from Intel BTS Adrian Hunter
2014-07-31  6:00 ` [PATCH 01/31] perf tools: Identify which comms are from exec Adrian Hunter
2014-08-14  8:51   ` [tip:perf/core] " tip-bot for Adrian Hunter
2014-07-31  6:00 ` [PATCH 02/31] perf tools: Add machine__thread_exec_comm() Adrian Hunter
2014-08-14  8:51   ` [tip:perf/core] perf machine: " tip-bot for Adrian Hunter
2014-07-31  6:00 ` [PATCH 03/31] perf tools: Fix missing label symbols Adrian Hunter
2014-08-14  8:50   ` [tip:perf/core] perf symbols: " tip-bot for Adrian Hunter
2014-07-31  6:00 ` [PATCH 04/31] perf tools: Add machine__kernel_ip() Adrian Hunter
2014-07-31  6:00 ` [PATCH 05/31] perf tools: Let a user specify a PMU event without any config terms Adrian Hunter
2014-07-31  6:00 ` [PATCH 06/31] perf tools: Let default config be defined for a PMU Adrian Hunter
2014-09-19  5:20   ` [tip:perf/core] " tip-bot for Adrian Hunter
2014-07-31  6:00 ` [PATCH 07/31] perf tools: Add perf_pmu__scan_file() Adrian Hunter
2014-09-19  5:21   ` [tip:perf/core] " tip-bot for Adrian Hunter
2014-07-31  6:00 ` [PATCH 08/31] perf evlist: Add 'system_wide' option Adrian Hunter
2014-08-14  8:50   ` [tip:perf/core] " tip-bot for Adrian Hunter
2014-07-31  6:00 ` [PATCH 09/31] perf evlist: Add perf_evlist__set_tracking_event() Adrian Hunter
2014-08-14  8:50   ` [tip:perf/core] perf evlist: Add perf_evlist__set_tracking_event( ) tip-bot for Adrian Hunter
2014-07-31  6:00 ` [PATCH 10/31] perf tools: Add id index Adrian Hunter
2014-07-31  6:00 ` [PATCH 11/31] perf pmu: Let pmu's with no events show up on perf list Adrian Hunter
2014-07-31  6:00 ` [PATCH 12/31] perf session: Add perf_session__deliver_synth_event() Adrian Hunter
2014-07-31  6:00 ` [PATCH 13/31] perf evlist: Add perf_evlist__enable_event_idx() Adrian Hunter
2014-08-14  8:52   ` [tip:perf/core] " tip-bot for Adrian Hunter
2014-07-31  6:00 ` [PATCH 14/31] perf session: Add perf_session__peek_event() Adrian Hunter
2014-08-14  8:50   ` [tip:perf/core] " tip-bot for Adrian Hunter
2014-07-31  6:00 ` [PATCH 15/31] perf tools: Add a thread stack for synthesizing call chains Adrian Hunter
2014-07-31  6:00 ` [PATCH 16/31] perf script: Allow callchains if any event samples them Adrian Hunter
2014-08-14  8:51   ` [tip:perf/core] " tip-bot for Adrian Hunter
2014-07-31  6:01 ` [PATCH 17/31] perf tools: Add facility to export data in database-friendly way Adrian Hunter
2014-07-31  6:01 ` [PATCH 18/31] perf tools: Add helpers for calling Python objects Adrian Hunter
2014-08-14  8:51   ` tip-bot for Adrian Hunter [this message]
2014-07-31  6:01 ` [PATCH 19/31] perf tools: Extend Python script interface to export data in a database-friendly way Adrian Hunter
2014-07-31  6:01 ` [PATCH 20/31] perf tools: Add Python script to export to postgresql Adrian Hunter
2014-07-31  6:01 ` [PATCH 21/31] perf tools: Add flags and insn_len to struct sample Adrian Hunter
2014-08-14  8:51   ` [tip:perf/core] " tip-bot for Adrian Hunter
2014-07-31  6:01 ` [PATCH 22/31] perf tools: Add branch type to db export Adrian Hunter
2014-07-31  6:01 ` [PATCH 23/31] perf tools: Add branch_type and in_tx to Python export Adrian Hunter
2014-07-31  6:01 ` [PATCH 24/31] perf tools: Enhance the thread stack to output call/return data Adrian Hunter
2014-07-31  6:01 ` [PATCH 25/31] perf tools: Add call information to the database export API Adrian Hunter
2014-07-31  6:01 ` [PATCH 26/31] perf tools: Add call information to Python export Adrian Hunter
2014-07-31  6:01 ` [PATCH 27/31] perf tools: Add 'flush' callback to scripting API Adrian Hunter
2014-07-31  6:01 ` [PATCH 28/31] perf tools: Defer export of comms that were not 'set' Adrian Hunter
2014-07-31  6:01 ` [PATCH 29/31] perf tools: Add perf-with-kcore script Adrian Hunter
2014-09-19  5:20   ` [tip:perf/core] " tip-bot for Adrian Hunter
2014-07-31  6:01 ` [PATCH 30/31] perf tools: Build programs to copy 32-bit compatibility VDSOs Adrian Hunter
2014-07-31  6:01 ` [PATCH 31/31] perf tools: Add support for " Adrian Hunter
2014-08-04 21:58 ` [PATCH 00/31] perf tools: Yet more preparation for call graph from Intel BTS Arnaldo Carvalho de Melo
2014-08-05 17:13   ` Adrian Hunter

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=tip-a5563edfa1bd25d052d81f5ad7fe74ba71c3d44e@git.kernel.org \
    --to=tipbot@zytor.com \
    --cc=acme@redhat.com \
    --cc=adrian.hunter@intel.com \
    --cc=dsahern@gmail.com \
    --cc=eranian@google.com \
    --cc=fweisbec@gmail.com \
    --cc=hpa@zytor.com \
    --cc=jolsa@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-tip-commits@vger.kernel.org \
    --cc=mingo@kernel.org \
    --cc=namhyung@gmail.com \
    --cc=paulus@samba.org \
    --cc=peterz@infradead.org \
    --cc=tglx@linutronix.de \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.