Em Thu, Sep 07, 2017 at 10:55:50AM -0700, kan.li...@intel.com escreveu: > From: Kan Liang <kan.li...@intel.com> > > Add comm_str_lock to protect comm_str rb tree. > > Signed-off-by: Kan Liang <kan.li...@intel.com> > --- > tools/perf/util/comm.c | 18 ++++++++++++++---- > 1 file changed, 14 insertions(+), 4 deletions(-) > > diff --git a/tools/perf/util/comm.c b/tools/perf/util/comm.c > index 7bc981b..1bdfef1 100644 > --- a/tools/perf/util/comm.c > +++ b/tools/perf/util/comm.c > @@ -5,6 +5,7 @@ > #include <stdio.h> > #include <string.h> > #include <linux/refcount.h> > +#include <pthread.h> > > struct comm_str { > char *str; > @@ -14,6 +15,7 @@ struct comm_str { > > /* Should perhaps be moved to struct machine */ > static struct rb_root comm_str_root; > +static pthread_mutex_t comm_str_lock = PTHREAD_MUTEX_INITIALIZER; > > static struct comm_str *comm_str__get(struct comm_str *cs) > { > @@ -24,11 +26,13 @@ static struct comm_str *comm_str__get(struct comm_str *cs) > > static void comm_str__put(struct comm_str *cs) > { > + pthread_mutex_lock(&comm_str_lock); > if (cs && refcount_dec_and_test(&cs->refcnt)) { > rb_erase(&cs->rb_node, &comm_str_root); > zfree(&cs->str); > free(cs); > } > + pthread_mutex_unlock(&comm_str_lock); > }
The above should use a smaller locked section, i.e.: static void comm_str__put(struct comm_str *cs) { if (cs && refcount_dec_and_test(&cs->refcnt)) { + pthread_mutex_lock(&comm_str_lock); rb_erase(&cs->rb_node, &comm_str_root); + pthread_mutex_unlock(&comm_str_lock); zfree(&cs->str); free(cs); } } > static struct comm_str *comm_str__alloc(const char *str) > @@ -52,18 +56,22 @@ static struct comm_str *comm_str__alloc(const char *str) > > static struct comm_str *comm_str__findnew(const char *str, struct rb_root > *root) The usual way is to just rename the above to __comm_str__findnew(), leaving it unlocked, and then add a locked wrapper: static struct comm_str *comm_str__findnew(const char *str, struct rb_root *root) { struct comm_str *cs; pthread_mutex_lock(&comm_str_lock); cs = __comm_str__findnew(str, root); pthread_mutex_unlock(&comm_str_lock); return cs; } > { > - struct rb_node **p = &root->rb_node; > struct rb_node *parent = NULL; > struct comm_str *iter, *new; > + struct rb_node **p; > int cmp; > > + pthread_mutex_lock(&comm_str_lock); > + p = &root->rb_node; > while (*p != NULL) { > parent = *p; > iter = rb_entry(parent, struct comm_str, rb_node); > > cmp = strcmp(str, iter->str); > - if (!cmp) > - return comm_str__get(iter); > + if (!cmp) { > + new = comm_str__get(iter); > + goto unlock; > + } > > if (cmp < 0) > p = &(*p)->rb_left; > @@ -73,11 +81,13 @@ static struct comm_str *comm_str__findnew(const char > *str, struct rb_root *root) > > new = comm_str__alloc(str); > if (!new) > - return NULL; > + goto unlock; > > rb_link_node(&new->rb_node, parent, p); > rb_insert_color(&new->rb_node, root); > > +unlock: > + pthread_mutex_unlock(&comm_str_lock); > return new; > } > > -- > 2.5.5