linux-trace-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/2] convert traceevent into a thread safe library
@ 2018-12-05  9:22 Tzvetomir Stoyanov
  2018-12-05  9:22 ` [PATCH 1/2] tools/lib/traceevent: make libtraceevent thread safe Tzvetomir Stoyanov
  2018-12-05  9:22 ` [PATCH 2/2] tools/lib/traceevent: make few libtraceevent internal variables to be per thread Tzvetomir Stoyanov
  0 siblings, 2 replies; 6+ messages in thread
From: Tzvetomir Stoyanov @ 2018-12-05  9:22 UTC (permalink / raw)
  To: rostedt; +Cc: linux-trace-devel

thread safe library. It implements per thread local storage for 
tep->last_event cache, and converts input_buf, input_buf_ptr
and input_buf_siz internal variables to be thread specific.

[backported from Linux kernel tree]

Tzvetomir Stoyanov (2):
  tools/lib/traceevent: make libtraceevent thread safe
  tools/lib/traceevent: make few libtraceevent internal variables to be
    per thread

 lib/traceevent/Makefile             |  1 +
 lib/traceevent/event-parse-local.h  | 15 +++++--
 lib/traceevent/event-parse-thread.c | 63 +++++++++++++++++++++++++++++
 lib/traceevent/event-parse.c        | 45 +++++++++++----------
 4 files changed, 100 insertions(+), 24 deletions(-)
 create mode 100644 lib/traceevent/event-parse-thread.c

-- 
2.19.2

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 1/2] tools/lib/traceevent: make libtraceevent thread safe
  2018-12-05  9:22 [PATCH 0/2] convert traceevent into a thread safe library Tzvetomir Stoyanov
@ 2018-12-05  9:22 ` Tzvetomir Stoyanov
  2018-12-11 16:56   ` Steven Rostedt
  2018-12-11 17:29   ` Steven Rostedt
  2018-12-05  9:22 ` [PATCH 2/2] tools/lib/traceevent: make few libtraceevent internal variables to be per thread Tzvetomir Stoyanov
  1 sibling, 2 replies; 6+ messages in thread
From: Tzvetomir Stoyanov @ 2018-12-05  9:22 UTC (permalink / raw)
  To: rostedt; +Cc: linux-trace-devel

This patch begins tranformation of libtraceevent into a
thread safe library. It implements per thread local storage
of tep hadler thread sensitive data and internal
APIs to access it. It covers tep->last_event cache,
more library's thread sensitive data will be added with
additional patches.

Signed-off-by: Tzvetomir Stoyanov <tstoyanov@vmware.com>
---
 lib/traceevent/Makefile             |  1 +
 lib/traceevent/event-parse-local.h  | 15 +++++--
 lib/traceevent/event-parse-thread.c | 63 +++++++++++++++++++++++++++++
 lib/traceevent/event-parse.c        | 39 +++++++++---------
 4 files changed, 97 insertions(+), 21 deletions(-)
 create mode 100644 lib/traceevent/event-parse-thread.c

diff --git a/lib/traceevent/Makefile b/lib/traceevent/Makefile
index bfbb6a3..8e34a97 100644
--- a/lib/traceevent/Makefile
+++ b/lib/traceevent/Makefile
@@ -14,6 +14,7 @@ OBJS += trace-seq.o
 OBJS += parse-filter.o
 OBJS += parse-utils.o
 OBJS += event-parse-api.o
+OBJS += event-parse-thread.o
 
 # Additional util objects
 OBJS += str_error_r.o
diff --git a/lib/traceevent/event-parse-local.h b/lib/traceevent/event-parse-local.h
index 70693b8..2c75f9e 100644
--- a/lib/traceevent/event-parse-local.h
+++ b/lib/traceevent/event-parse-local.h
@@ -14,6 +14,12 @@ struct func_list;
 struct event_handler;
 struct func_resolver;
 
+/* cache */
+struct tep_thread_data {
+	struct tep_handle *tep;
+	struct tep_event *last_event;
+};
+
 struct tep_handle {
 	int ref_count;
 
@@ -85,9 +91,6 @@ struct tep_handle {
 
 	int parsing_failures;
 
-	/* cache */
-	struct tep_event *last_event;
-
 	char *trace_clock;
 };
 
@@ -98,4 +101,10 @@ unsigned short tep_data2host2(struct tep_handle *pevent, unsigned short data);
 unsigned int tep_data2host4(struct tep_handle *pevent, unsigned int data);
 unsigned long long tep_data2host8(struct tep_handle *pevent, unsigned long long data);
 
+/* tep cache per thread */
+struct tep_event *get_thread_local_event_by_id(struct tep_handle *tep, int id);
+struct tep_event *
+get_thread_local_event_by_name(struct tep_handle *tep, const char *name, const char *sys);
+void set_thread_local_event_cache(struct tep_handle *tep, struct tep_event *event);
+
 #endif /* _PARSE_EVENTS_INT_H */
diff --git a/lib/traceevent/event-parse-thread.c b/lib/traceevent/event-parse-thread.c
new file mode 100644
index 0000000..f846350
--- /dev/null
+++ b/lib/traceevent/event-parse-thread.c
@@ -0,0 +1,63 @@
+// SPDX-License-Identifier: LGPL-2.1
+/*
+ * Copyright (C) 2009, 2010 Red Hat Inc, Steven Rostedt <srostedt@redhat.com>
+ *
+ */
+
+#include "event-parse.h"
+#include "event-parse-local.h"
+#include "event-utils.h"
+
+static __thread struct tep_thread_data tep_thread_local;
+
+/**
+ * get_thread_local_event_by_id - Find event with given id in the cache
+ * @tep: a handle to the tep context
+ * @id: event's id
+ *
+ * Searches in the cache for event with given id
+ */
+struct tep_event *get_thread_local_event_by_id(struct tep_handle *tep, int id)
+{
+
+	if (tep_thread_local.last_event && tep_thread_local.tep == tep &&
+	    tep_thread_local.last_event->id == id)
+		return tep_thread_local.last_event;
+
+	return NULL;
+}
+
+/**
+ * get_thread_local_event_by_name - Find event with given name and sys in the cache
+ * @tep: a handle to the tep context
+ * @name: event's name
+ * @sys: event's system
+ *
+ * Searches in the cache for event with given name and system
+ */
+struct tep_event *
+get_thread_local_event_by_name(struct tep_handle *tep, const char *name, const char *sys)
+{
+	if (tep_thread_local.last_event &&
+	    tep_thread_local.tep == tep &&
+	    strcmp(tep_thread_local.last_event->name, name) == 0 &&
+	    (!sys || strcmp(tep_thread_local.last_event->system, sys) == 0))
+		return tep_thread_local.last_event;
+
+	return NULL;
+}
+
+/**
+ * set_thread_local_event_cache - set last used event in the cache
+ * @tep: a handle to the tep context
+ * @event: pointer to the last used event
+ *
+ * Sets last used event in the cache, to speed up the next searches
+ */
+void set_thread_local_event_cache(struct tep_handle *tep, struct tep_event *event)
+{
+	tep_thread_local.tep = tep;
+	tep_thread_local.last_event = event;
+}
+
+
diff --git a/lib/traceevent/event-parse.c b/lib/traceevent/event-parse.c
index bc35dc8..cacdcc4 100644
--- a/lib/traceevent/event-parse.c
+++ b/lib/traceevent/event-parse.c
@@ -3461,28 +3461,29 @@ static int events_id_cmp(const void *a, const void *b);
 
 /**
  * tep_find_event - find an event by given id
- * @pevent: a handle to the pevent
+ * @tep: a handle to the tep context
  * @id: the id of the event
  *
  * Returns an event that has a given @id.
  */
-struct tep_event *tep_find_event(struct tep_handle *pevent, int id)
+struct tep_event *tep_find_event(struct tep_handle *tep, int id)
 {
 	struct tep_event **eventptr;
 	struct tep_event key;
 	struct tep_event *pkey = &key;
+	struct tep_event *event_cache = get_thread_local_event_by_id(tep, id);
 
 	/* Check cache first */
-	if (pevent->last_event && pevent->last_event->id == id)
-		return pevent->last_event;
+	if (event_cache)
+		return event_cache;
 
 	key.id = id;
 
-	eventptr = bsearch(&pkey, pevent->events, pevent->nr_events,
-			   sizeof(*pevent->events), events_id_cmp);
+	eventptr = bsearch(&pkey, tep->events, tep->nr_events,
+			   sizeof(*tep->events), events_id_cmp);
 
 	if (eventptr) {
-		pevent->last_event = *eventptr;
+		set_thread_local_event_cache(tep, *eventptr);
 		return *eventptr;
 	}
 
@@ -3491,7 +3492,7 @@ struct tep_event *tep_find_event(struct tep_handle *pevent, int id)
 
 /**
  * tep_find_event_by_name - find an event by given name
- * @pevent: a handle to the pevent
+ * @tep: a handle to the tep context
  * @sys: the system name to search for
  * @name: the name of the event to search for
  *
@@ -3499,19 +3500,19 @@ struct tep_event *tep_find_event(struct tep_handle *pevent, int id)
  * @sys. If @sys is NULL the first event with @name is returned.
  */
 struct tep_event *
-tep_find_event_by_name(struct tep_handle *pevent,
+tep_find_event_by_name(struct tep_handle *tep,
 		       const char *sys, const char *name)
 {
-	struct tep_event *event;
 	int i;
+	struct tep_event *event = NULL;
+	struct tep_event *event_cache = get_thread_local_event_by_name(tep, name, sys);
 
-	if (pevent->last_event &&
-	    strcmp(pevent->last_event->name, name) == 0 &&
-	    (!sys || strcmp(pevent->last_event->system, sys) == 0))
-		return pevent->last_event;
+	/* Check cache first */
+	if (event_cache)
+		return event_cache;
 
-	for (i = 0; i < pevent->nr_events; i++) {
-		event = pevent->events[i];
+	for (i = 0; i < tep->nr_events; i++) {
+		event = tep->events[i];
 		if (strcmp(event->name, name) == 0) {
 			if (!sys)
 				break;
@@ -3519,10 +3520,12 @@ tep_find_event_by_name(struct tep_handle *pevent,
 				break;
 		}
 	}
-	if (i == pevent->nr_events)
+
+	if (i == tep->nr_events)
 		event = NULL;
+	if (event)
+		set_thread_local_event_cache(tep, event);
 
-	pevent->last_event = event;
 	return event;
 }
 
-- 
2.19.2

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 2/2] tools/lib/traceevent: make few libtraceevent internal variables to be per thread
  2018-12-05  9:22 [PATCH 0/2] convert traceevent into a thread safe library Tzvetomir Stoyanov
  2018-12-05  9:22 ` [PATCH 1/2] tools/lib/traceevent: make libtraceevent thread safe Tzvetomir Stoyanov
@ 2018-12-05  9:22 ` Tzvetomir Stoyanov
  1 sibling, 0 replies; 6+ messages in thread
From: Tzvetomir Stoyanov @ 2018-12-05  9:22 UTC (permalink / raw)
  To: rostedt; +Cc: linux-trace-devel

This patch continues the effort to transform libtraceevent
into a thread safe library. It converts input_buf, input_buf_ptr
and input_buf_siz internal variables to be thread specific. This
buffer is not related to a specific tep context. It is used
internally by the library during the parsing of various strings.

Signed-off-by: Tzvetomir Stoyanov <tstoyanov@vmware.com>
---
 lib/traceevent/event-parse.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/lib/traceevent/event-parse.c b/lib/traceevent/event-parse.c
index cacdcc4..1cab1a5 100644
--- a/lib/traceevent/event-parse.c
+++ b/lib/traceevent/event-parse.c
@@ -28,9 +28,9 @@
 #include "event-utils.h"
 #include "trace-seq.h"
 
-static const char *input_buf;
-static unsigned long long input_buf_ptr;
-static unsigned long long input_buf_siz;
+static __thread const char *input_buf;
+static __thread unsigned long long input_buf_ptr;
+static __thread unsigned long long input_buf_siz;
 
 static int is_flag_field;
 static int is_symbolic_field;
-- 
2.19.2

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH 1/2] tools/lib/traceevent: make libtraceevent thread safe
  2018-12-05  9:22 ` [PATCH 1/2] tools/lib/traceevent: make libtraceevent thread safe Tzvetomir Stoyanov
@ 2018-12-11 16:56   ` Steven Rostedt
  2018-12-11 17:29   ` Steven Rostedt
  1 sibling, 0 replies; 6+ messages in thread
From: Steven Rostedt @ 2018-12-11 16:56 UTC (permalink / raw)
  To: Tzvetomir Stoyanov; +Cc: linux-trace-devel

On Wed, 5 Dec 2018 09:22:12 +0000
Tzvetomir Stoyanov <tstoyanov@vmware.com> wrote:

> +void set_thread_local_event_cache(struct tep_handle *tep, struct tep_event *event)
> +{
> +	tep_thread_local.tep = tep;
> +	tep_thread_local.last_event = event;
> +}
> +
> +

FYI,

Your file ended up with an extra blank line at the end. I deleted it,
but that does make git complain when applying this patch.

-- Steve

> diff --git a/lib/traceevent/event-parse.c b/lib/traceevent/event-parse.c
> index bc35dc8..cacdcc4 100644

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 1/2] tools/lib/traceevent: make libtraceevent thread safe
  2018-12-05  9:22 ` [PATCH 1/2] tools/lib/traceevent: make libtraceevent thread safe Tzvetomir Stoyanov
  2018-12-11 16:56   ` Steven Rostedt
@ 2018-12-11 17:29   ` Steven Rostedt
  1 sibling, 0 replies; 6+ messages in thread
From: Steven Rostedt @ 2018-12-11 17:29 UTC (permalink / raw)
  To: Tzvetomir Stoyanov; +Cc: linux-trace-devel

On Wed, 5 Dec 2018 09:22:12 +0000
Tzvetomir Stoyanov <tstoyanov@vmware.com> wrote:

> @@ -3499,19 +3500,19 @@ struct tep_event *tep_find_event(struct tep_handle *pevent, int id)
>   * @sys. If @sys is NULL the first event with @name is returned.
>   */
>  struct tep_event *
> -tep_find_event_by_name(struct tep_handle *pevent,
> +tep_find_event_by_name(struct tep_handle *tep,
>  		       const char *sys, const char *name)
>  {
> -	struct tep_event *event;
>  	int i;
> +	struct tep_event *event = NULL;
> +	struct tep_event *event_cache = get_thread_local_event_by_name(tep, name, sys);

BTW, I modified this to keep with the "upside down christmas tree"
method. That is, instead of:

	int i;
	struct tep_event *event = NULL;
	struct tep_event *event_cache = get_thread_local_event_by_name(tep, name, sys);

I made it:

	struct tep_event *event_cache = get_thread_local_event_by_name(tep, name, sys);
	struct tep_event *event = NULL;
	int i;

to make it look better, and some kernel developers (as well as the perf
developers) require that for declarations.

-- Steve

>  
> -	if (pevent->last_event &&
> -	    strcmp(pevent->last_event->name, name) == 0 &&
> -	    (!sys || strcmp(pevent->last_event->system, sys) == 0))
> -		return pevent->last_event;
> +	/* Check cache first */
> +	if (event_cache)
> +		return event_cache;
>  
> -	for (i = 0; i < pevent->nr_events; i++) {
> -		event = pevent->events[i];
> +	for (i = 0; i < tep->nr_events; i++) {
> +		event = tep->events[i];
>  		if (strcmp(event->name, name) == 0) {
>  			if (!sys)
>  				break;

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 2/2] tools/lib/traceevent: make few libtraceevent internal variables to be per thread
  2018-11-30 13:13 [PATCH 0/2] convert traceevent into a thread safe library Tzvetomir Stoyanov
@ 2018-11-30 13:13 ` Tzvetomir Stoyanov
  0 siblings, 0 replies; 6+ messages in thread
From: Tzvetomir Stoyanov @ 2018-11-30 13:13 UTC (permalink / raw)
  To: rostedt; +Cc: linux-trace-devel

This patch continues the effort to transform libtraceevent
into a thread safe library. It converts input_buf, input_buf_ptr
and input_buf_siz internal variables to be thread specific. This
buffer is not related to a specific tep context. It is used
internally by the library during the parsing of various strings.

Signed-off-by: Tzvetomir Stoyanov <tstoyanov@vmware.com>
---
 tools/lib/traceevent/event-parse.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c
index 8f19dcdd06ec..f6c926467fa3 100644
--- a/tools/lib/traceevent/event-parse.c
+++ b/tools/lib/traceevent/event-parse.c
@@ -42,9 +42,9 @@
 #include "event-utils.h"
 #include "trace-seq.h"
 
-static const char *input_buf;
-static unsigned long long input_buf_ptr;
-static unsigned long long input_buf_siz;
+static __thread const char *input_buf;
+static __thread unsigned long long input_buf_ptr;
+static __thread unsigned long long input_buf_siz;
 
 static int is_flag_field;
 static int is_symbolic_field;
-- 
2.19.1

^ permalink raw reply related	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2018-12-11 17:29 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-12-05  9:22 [PATCH 0/2] convert traceevent into a thread safe library Tzvetomir Stoyanov
2018-12-05  9:22 ` [PATCH 1/2] tools/lib/traceevent: make libtraceevent thread safe Tzvetomir Stoyanov
2018-12-11 16:56   ` Steven Rostedt
2018-12-11 17:29   ` Steven Rostedt
2018-12-05  9:22 ` [PATCH 2/2] tools/lib/traceevent: make few libtraceevent internal variables to be per thread Tzvetomir Stoyanov
  -- strict thread matches above, loose matches on Subject: below --
2018-11-30 13:13 [PATCH 0/2] convert traceevent into a thread safe library Tzvetomir Stoyanov
2018-11-30 13:13 ` [PATCH 2/2] tools/lib/traceevent: make few libtraceevent internal variables to be per thread Tzvetomir Stoyanov

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