LKML Archive on lore.kernel.org
 help / color / Atom feed
From: Steven Rostedt <rostedt@goodmis.org>
To: linux-kernel@vger.kernel.org
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>,
	Ingo Molnar <mingo@kernel.org>, Jiri Olsa <jolsa@redhat.com>,
	Namhyung Kim <namhyung@kernel.org>,
	Andrew Morton <akpm@linux-foundation.org>,
	Tzvetomir Stoyanov <tstoyanov@vmware.com>
Subject: [PATCH 03/15] tools lib traceevent: Implement a new API, tep_list_events_copy()
Date: Mon, 01 Apr 2019 12:43:08 -0400
Message-ID: <20190401164343.117437443@goodmis.org> (raw)
In-Reply-To: <20190401164305.359125441@goodmis.org>

From: Tzvetomir Stoyanov <tstoyanov@vmware.com>

Existing API tep_list_events() is not thread safe, it uses the internal
array sort_events to keep cache of the sorted events and reuses it. This
patch implements a new API, tep_list_events_copy(), which allocates new
sorted array each time it is called. It could be used when a sorted events
functionality is needed in thread safe use cases. It is up to the caller to
free the array.

Link: http://lore.kernel.org/linux-trace-devel/20181218133013.31094-1-tstoyanov@vmware.com

Signed-off-by: Tzvetomir Stoyanov <tstoyanov@vmware.com>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
---
 tools/lib/traceevent/event-parse.c | 109 +++++++++++++++++++++++------
 tools/lib/traceevent/event-parse.h |   5 +-
 2 files changed, 91 insertions(+), 23 deletions(-)

diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c
index 666e23ded6ed..c00aebab3c33 100644
--- a/tools/lib/traceevent/event-parse.c
+++ b/tools/lib/traceevent/event-parse.c
@@ -5651,32 +5651,26 @@ static int events_system_cmp(const void *a, const void *b)
 	return events_id_cmp(a, b);
 }
 
-struct tep_event **tep_list_events(struct tep_handle *pevent, enum tep_event_sort_type sort_type)
+static struct tep_event **list_events_copy(struct tep_handle *tep)
 {
 	struct tep_event **events;
-	int (*sort)(const void *a, const void *b);
-
-	events = pevent->sort_events;
-
-	if (events && pevent->last_type == sort_type)
-		return events;
 
-	if (!events) {
-		events = malloc(sizeof(*events) * (pevent->nr_events + 1));
-		if (!events)
-			return NULL;
+	if (!tep)
+		return NULL;
 
-		memcpy(events, pevent->events, sizeof(*events) * pevent->nr_events);
-		events[pevent->nr_events] = NULL;
+	events = malloc(sizeof(*events) * (tep->nr_events + 1));
+	if (!events)
+		return NULL;
 
-		pevent->sort_events = events;
+	memcpy(events, tep->events, sizeof(*events) * tep->nr_events);
+	events[tep->nr_events] = NULL;
+	return events;
+}
 
-		/* the internal events are sorted by id */
-		if (sort_type == TEP_EVENT_SORT_ID) {
-			pevent->last_type = sort_type;
-			return events;
-		}
-	}
+static void list_events_sort(struct tep_event **events, int nr_events,
+			     enum tep_event_sort_type sort_type)
+{
+	int (*sort)(const void *a, const void *b);
 
 	switch (sort_type) {
 	case TEP_EVENT_SORT_ID:
@@ -5689,11 +5683,82 @@ struct tep_event **tep_list_events(struct tep_handle *pevent, enum tep_event_sor
 		sort = events_system_cmp;
 		break;
 	default:
+		sort = NULL;
+	}
+
+	if (sort)
+		qsort(events, nr_events, sizeof(*events), sort);
+}
+
+/**
+ * tep_list_events - Get events, sorted by given criteria.
+ * @tep: a handle to the tep context
+ * @sort_type: desired sort order of the events in the array
+ *
+ * Returns an array of pointers to all events, sorted by the given
+ * @sort_type criteria. The last element of the array is NULL. The returned
+ * memory must not be freed, it is managed by the library.
+ * The function is not thread safe.
+ */
+struct tep_event **tep_list_events(struct tep_handle *tep,
+				   enum tep_event_sort_type sort_type)
+{
+	struct tep_event **events;
+
+	if (!tep)
+		return NULL;
+
+	events = tep->sort_events;
+	if (events && tep->last_type == sort_type)
 		return events;
+
+	if (!events) {
+		events = list_events_copy(tep);
+		if (!events)
+			return NULL;
+
+		tep->sort_events = events;
+
+		/* the internal events are sorted by id */
+		if (sort_type == TEP_EVENT_SORT_ID) {
+			tep->last_type = sort_type;
+			return events;
+		}
 	}
 
-	qsort(events, pevent->nr_events, sizeof(*events), sort);
-	pevent->last_type = sort_type;
+	list_events_sort(events, tep->nr_events, sort_type);
+	tep->last_type = sort_type;
+
+	return events;
+}
+
+
+/**
+ * tep_list_events_copy - Thread safe version of tep_list_events()
+ * @tep: a handle to the tep context
+ * @sort_type: desired sort order of the events in the array
+ *
+ * Returns an array of pointers to all events, sorted by the given
+ * @sort_type criteria. The last element of the array is NULL. The returned
+ * array is newly allocated inside the function and must be freed by the caller
+ */
+struct tep_event **tep_list_events_copy(struct tep_handle *tep,
+					enum tep_event_sort_type sort_type)
+{
+	struct tep_event **events;
+
+	if (!tep)
+		return NULL;
+
+	events = list_events_copy(tep);
+	if (!events)
+		return NULL;
+
+	/* the internal events are sorted by id */
+	if (sort_type == TEP_EVENT_SORT_ID)
+		return events;
+
+	list_events_sort(events, tep->nr_events, sort_type);
 
 	return events;
 }
diff --git a/tools/lib/traceevent/event-parse.h b/tools/lib/traceevent/event-parse.h
index aec48f2aea8a..41159358abc2 100644
--- a/tools/lib/traceevent/event-parse.h
+++ b/tools/lib/traceevent/event-parse.h
@@ -544,7 +544,10 @@ void tep_event_info(struct trace_seq *s, struct tep_event *event,
 int tep_strerror(struct tep_handle *pevent, enum tep_errno errnum,
 		 char *buf, size_t buflen);
 
-struct tep_event **tep_list_events(struct tep_handle *pevent, enum tep_event_sort_type);
+struct tep_event **tep_list_events(struct tep_handle *tep,
+				   enum tep_event_sort_type);
+struct tep_event **tep_list_events_copy(struct tep_handle *tep,
+					enum tep_event_sort_type);
 struct tep_format_field **tep_event_common_fields(struct tep_event *event);
 struct tep_format_field **tep_event_fields(struct tep_event *event);
 
-- 
2.20.1



  parent reply index

Thread overview: 55+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-04-01 16:43 [PATCH 00/15] tools/lib/traceevent: Continuing on the path to a stand alone library Steven Rostedt
2019-04-01 16:43 ` [PATCH 01/15] tools lib traceevent: Handle trace_printk() "%px" Steven Rostedt
2019-04-05 11:41   ` [tip:perf/core] " tip-bot for Steven Rostedt (VMware)
2019-04-01 16:43 ` [PATCH 02/15] tools/lib/traceevent: Add mono clocks to be parsed in seconds Steven Rostedt
2019-04-05 11:42   ` [tip:perf/core] tools lib traceevent: " tip-bot for Steven Rostedt (VMware)
2019-04-01 16:43 ` Steven Rostedt [this message]
2019-04-05 11:42   ` [tip:perf/core] tools lib traceevent: Implement a new API, tep_list_events_copy() tip-bot for Tzvetomir Stoyanov
2019-04-01 16:43 ` [PATCH 04/15] tools/lib/traceevent: Add more debugging to see various internal ring buffer entries Steven Rostedt
2019-04-05 11:43   ` [tip:perf/core] tools lib traceevent: " tip-bot for Steven Rostedt (Red Hat)
2019-04-01 16:43 ` [PATCH 05/15] tools/lib/traceevent: Change description of few APIs Steven Rostedt
2019-04-05 11:44   ` [tip:perf/core] tools lib traceevent: " tip-bot for Tzvetomir Stoyanov
2019-04-01 16:43 ` [PATCH 06/15] tools/lib/traceevent: Coding style fixes Steven Rostedt
2019-04-05 11:44   ` [tip:perf/core] tools lib traceevent: " tip-bot for Tzvetomir Stoyanov
2019-04-01 16:43 ` [PATCH 07/15] tools/lib/traceevent: Implement new traceevent APIs for accessing struct tep_handler fields Steven Rostedt
2019-04-05 11:45   ` [tip:perf/core] tools lib traceevent: " tip-bot for Tzvetomir Stoyanov
2019-04-01 16:43 ` [PATCH 08/15] tools/lib/traceevent: Removed unneeded !! and return parenthesis Steven Rostedt
2019-04-05 11:46   ` [tip:perf/core] tools lib traceevent: " tip-bot for Steven Rostedt (VMware)
2019-04-01 16:43 ` [PATCH 09/15] tools/lib/traceevent: Remove tep filter trivial APIs Steven Rostedt
2019-04-05 11:47   ` [tip:perf/core] tools lib traceevent: " tip-bot for Tzvetomir Stoyanov
2019-04-01 16:43 ` [PATCH 10/15] tools/lib/traceevent: Remove call to exit() from tep_filter_add_filter_str() Steven Rostedt
2019-04-05 11:47   ` [tip:perf/core] tools lib traceevent: " tip-bot for Tzvetomir Stoyanov
2019-04-01 16:43 ` [PATCH 11/15] tools/perf,tools/lib/traceevent: Make traceevent APIs more consistent Steven Rostedt
2019-04-05 11:48   ` [tip:perf/core] tools tools, tools lib traceevent: " tip-bot for Tzvetomir Stoyanov
2019-04-01 16:43 ` [PATCH 12/15] tools/lib/traceevent: Rename input arguments of libtraceevent APIs from pevent to tep Steven Rostedt
2019-04-05 11:49   ` [tip:perf/core] tools lib traceevent: " tip-bot for Tzvetomir Stoyanov
2019-04-01 16:43 ` [PATCH 13/15] tools/perf,tools/lib/traceevent: Rename "pevent" member of struct tep_event to "tep" Steven Rostedt
2019-04-05 11:49   ` [tip:perf/core] perf tools, tools lib traceevent: " tip-bot for Tzvetomir Stoyanov
2019-04-01 16:43 ` [PATCH 14/15] tools/perf,tools/lib/traceevent: Rename "pevent" member of struct tep_event_filter " Steven Rostedt
2019-04-05 11:50   ` [tip:perf/core] perf tools, tools lib traceevent: " tip-bot for Tzvetomir Stoyanov
2019-04-01 16:43 ` [PATCH 15/15] tools/lib/traceevent: Rename input arguments and local variables of libtraceevent from pevent to tep Steven Rostedt
2019-04-05 11:51   ` [tip:perf/core] tools lib traceevent: " tip-bot for Tzvetomir Stoyanov
2019-04-01 18:17 ` [PATCH 00/15] tools/lib/traceevent: Continuing on the path to a stand alone library Arnaldo Carvalho de Melo
  -- strict thread matches above, loose matches on Subject: below --
2019-03-27 14:19 [PATCH v2 0/5] Cleanup traceevent API and make it more consistent Tzvetomir Stoyanov
2019-03-27 14:19 ` [PATCH v2 1/5] tools/perf,tools/lib/traceevent: Make traceevent APIs " Tzvetomir Stoyanov
2019-03-27 14:41   ` Steven Rostedt
2019-03-27 14:19 ` [PATCH v2 2/5] tools/lib/traceevent: Rename input arguments of libtraceevent APIs from pevent to tep Tzvetomir Stoyanov
2019-03-27 15:06   ` Steven Rostedt
2019-03-27 14:19 ` [PATCH v2 3/5] tools/perf,tools/lib/traceevent: Rename "pevent" member of struct tep_event to "tep" Tzvetomir Stoyanov
2019-03-27 14:19 ` [PATCH v2 4/5] tools/perf,tools/lib/traceevent: Rename "pevent" member of struct tep_event_filter " Tzvetomir Stoyanov
2019-03-27 14:19 ` [PATCH v2 5/5] tools/lib/traceevent: Rename input arguments and local variables of libtraceevent from pevent to tep Tzvetomir Stoyanov
2019-03-26 15:43 [PATCH 0/8] Cleanup traceevent API and make it more consistent Tzvetomir Stoyanov
2019-03-26 15:43 ` [PATCH 1/8] tools/perf,tools/lib/traceevent: Make traceevent APIs " Tzvetomir Stoyanov
2019-03-26 19:43   ` Steven Rostedt
2019-03-26 15:43 ` [PATCH 2/8] tools/lib/traceevent: Add counter to track parsing failures Tzvetomir Stoyanov
2019-03-26 19:48   ` Steven Rostedt
2019-03-26 15:43 ` [PATCH 3/8] tools/lib/traceevent: Remove tep filter trivial APIs Tzvetomir Stoyanov
2019-03-26 19:50   ` Steven Rostedt
2019-03-26 15:43 ` [PATCH 4/8] tools/lib/traceevent: rename input arguments of libtraceevent APIs from pevent to tep Tzvetomir Stoyanov
2019-03-26 19:57   ` Steven Rostedt
2019-03-26 19:58     ` Steven Rostedt
2019-03-26 15:43 ` [PATCH 5/8] tools/perf,tools/lib/traceevent: rename "pevent" member of struct tep_event to "tep" Tzvetomir Stoyanov
2019-03-26 15:43 ` [PATCH 6/8] tools/perf,tools/lib/traceevent: rename "pevent" member of struct tep_event_filter " Tzvetomir Stoyanov
2019-03-26 15:43 ` [PATCH 7/8] tools/lib/traceevent: rename input arguments and local variables of libtraceevent from pevent to tep Tzvetomir Stoyanov
2019-03-26 15:43 ` [PATCH 8/8] tools/lib/traceevent: remove call to exit() from tep_filter_add_filter_str() Tzvetomir Stoyanov
2019-03-26 20:02   ` Steven Rostedt

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=20190401164343.117437443@goodmis.org \
    --to=rostedt@goodmis.org \
    --cc=acme@kernel.org \
    --cc=akpm@linux-foundation.org \
    --cc=jolsa@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@kernel.org \
    --cc=namhyung@kernel.org \
    --cc=tstoyanov@vmware.com \
    /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

LKML Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/lkml/0 lkml/git/0.git
	git clone --mirror https://lore.kernel.org/lkml/1 lkml/git/1.git
	git clone --mirror https://lore.kernel.org/lkml/2 lkml/git/2.git
	git clone --mirror https://lore.kernel.org/lkml/3 lkml/git/3.git
	git clone --mirror https://lore.kernel.org/lkml/4 lkml/git/4.git
	git clone --mirror https://lore.kernel.org/lkml/5 lkml/git/5.git
	git clone --mirror https://lore.kernel.org/lkml/6 lkml/git/6.git
	git clone --mirror https://lore.kernel.org/lkml/7 lkml/git/7.git
	git clone --mirror https://lore.kernel.org/lkml/8 lkml/git/8.git
	git clone --mirror https://lore.kernel.org/lkml/9 lkml/git/9.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 lkml lkml/ https://lore.kernel.org/lkml \
		linux-kernel@vger.kernel.org
	public-inbox-index lkml

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.linux-kernel


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git