Skip to content

Commit

Permalink
perf pmu: Make parser reentrant
Browse files Browse the repository at this point in the history
By default bison uses global state for compatibility with yacc. Make
the parser reentrant so that it may be used in asynchronous and
multithreaded situations.

Signed-off-by: Ian Rogers <irogers@google.com>
Acked-by: Jiri Olsa <jolsa@kernel.org>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Gaosheng Cui <cuigaosheng1@huawei.com>
Cc: German Gomez <german.gomez@arm.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: James Clark <james.clark@arm.com>
Cc: Jing Zhang <renyu.zj@linux.alibaba.com>
Cc: Leo Yan <leo.yan@linaro.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Ravi Bangoria <ravi.bangoria@amd.com>
Cc: Rob Herring <robh@kernel.org>
Cc: Sean Christopherson <seanjc@google.com>
Cc: Suzuki Poulouse <suzuki.poulose@arm.com>
Link: https://lore.kernel.org/r/20230406065224.2553640-1-irogers@google.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
  • Loading branch information
Ian Rogers authored and Arnaldo Carvalho de Melo committed Apr 7, 2023
1 parent e5116f4 commit 3d88aec
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 13 deletions.
26 changes: 20 additions & 6 deletions tools/perf/util/pmu.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
#include "evsel.h"
#include "pmu.h"
#include "pmus.h"
#include "pmu-bison.h"
#include "pmu-flex.h"
#include "parse-events.h"
#include "print-events.h"
#include "header.h"
Expand Down Expand Up @@ -57,9 +59,6 @@ struct perf_pmu_format {
struct list_head list;
};

int perf_pmu_parse(struct list_head *list, char *name);
extern FILE *perf_pmu_in;

static bool hybrid_scanned;

static struct perf_pmu *perf_pmu__find2(int dirfd, const char *name);
Expand All @@ -81,6 +80,8 @@ int perf_pmu__format_parse(int dirfd, struct list_head *head)
while (!ret && (evt_ent = readdir(format_dir))) {
char *name = evt_ent->d_name;
int fd;
void *scanner;
FILE *file;

if (!strcmp(name, ".") || !strcmp(name, ".."))
continue;
Expand All @@ -91,9 +92,22 @@ int perf_pmu__format_parse(int dirfd, struct list_head *head)
if (fd < 0)
break;

perf_pmu_in = fdopen(fd, "r");
ret = perf_pmu_parse(head, name);
fclose(perf_pmu_in);
file = fdopen(fd, "r");
if (!file) {
close(fd);
break;
}

ret = perf_pmu_lex_init(&scanner);
if (ret) {
fclose(file);
break;
}

perf_pmu_set_in(file, scanner);
ret = perf_pmu_parse(head, name, scanner);
perf_pmu_lex_destroy(scanner);
fclose(file);
}

closedir(format_dir);
Expand Down
2 changes: 1 addition & 1 deletion tools/perf/util/pmu.h
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ int perf_pmu__check_alias(struct perf_pmu *pmu, struct list_head *head_terms,
struct perf_pmu_info *info);
struct list_head *perf_pmu__alias(struct perf_pmu *pmu,
struct list_head *head_terms);
void perf_pmu_error(struct list_head *list, char *name, char const *msg);
void perf_pmu_error(struct list_head *list, char *name, void *scanner, char const *msg);

int perf_pmu__new_format(struct list_head *list, char *name,
int config, unsigned long *bits);
Expand Down
17 changes: 12 additions & 5 deletions tools/perf/util/pmu.l
Original file line number Diff line number Diff line change
@@ -1,21 +1,28 @@
%option prefix="perf_pmu_"
%option reentrant
%option bison-bridge

%{
#include <stdlib.h>
#include <linux/bitops.h>
#include "pmu.h"
#include "pmu-bison.h"

static int value(int base)
char *perf_pmu_get_text(yyscan_t yyscanner);
YYSTYPE *perf_pmu_get_lval(yyscan_t yyscanner);

static int value(yyscan_t scanner, int base)
{
YYSTYPE *yylval = perf_pmu_get_lval(scanner);
char *text = perf_pmu_get_text(scanner);
long num;

errno = 0;
num = strtoul(perf_pmu_text, NULL, base);
num = strtoul(text, NULL, base);
if (errno)
return PP_ERROR;

perf_pmu_lval.num = num;
yylval->num = num;
return PP_VALUE;
}

Expand All @@ -25,7 +32,7 @@ num_dec [0-9]+

%%

{num_dec} { return value(10); }
{num_dec} { return value(yyscanner, 10); }
config { return PP_CONFIG; }
- { return '-'; }
: { return ':'; }
Expand All @@ -35,7 +42,7 @@ config { return PP_CONFIG; }

%%

int perf_pmu_wrap(void)
int perf_pmu_wrap(void *scanner __maybe_unused)
{
return 1;
}
5 changes: 4 additions & 1 deletion tools/perf/util/pmu.y
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@

%define api.pure full
%parse-param {struct list_head *format}
%parse-param {char *name}
%parse-param {void *scanner}
%lex-param {void* scanner}

%{

Expand Down Expand Up @@ -78,6 +80,7 @@ PP_VALUE

void perf_pmu_error(struct list_head *list __maybe_unused,
char *name __maybe_unused,
void *scanner __maybe_unused,
char const *msg __maybe_unused)
{
}

0 comments on commit 3d88aec

Please sign in to comment.