* [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@goodmis.org; +Cc: linux-trace-devel@vger.kernel.org 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@goodmis.org; +Cc: linux-trace-devel@vger.kernel.org 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
* 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@vger.kernel.org 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@vger.kernel.org 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-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@goodmis.org; +Cc: linux-trace-devel@vger.kernel.org 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
* [PATCH 0/2] convert traceevent into a thread safe library @ 2018-11-30 13:13 Tzvetomir Stoyanov 2018-11-30 13:13 ` [PATCH 2/2] tools/lib/traceevent: make few libtraceevent internal variables to be per thread Tzvetomir Stoyanov 0 siblings, 1 reply; 6+ messages in thread From: Tzvetomir Stoyanov @ 2018-11-30 13:13 UTC (permalink / raw) To: rostedt@goodmis.org; +Cc: linux-trace-devel@vger.kernel.org This short patch series begins tranformation of libtraceevent into a 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. Tzvetomir Stoyanov (2): tools/lib/traceevent: make libtraceevent thread safe tools/lib/traceevent: make few libtraceevent internal variables to be per thread tools/lib/traceevent/Build | 1 + tools/lib/traceevent/event-parse-local.h | 15 ++++-- tools/lib/traceevent/event-parse-thread.c | 63 +++++++++++++++++++++++ tools/lib/traceevent/event-parse.c | 45 ++++++++-------- 4 files changed, 100 insertions(+), 24 deletions(-) create mode 100644 tools/lib/traceevent/event-parse-thread.c -- 2.19.1 ^ 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@goodmis.org; +Cc: linux-trace-devel@vger.kernel.org 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).