From: acme@infradead.org (Arnaldo Carvalho de Melo)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v1 1/1] Extended events (platform-specific) support in perf
Date: Fri, 22 Jan 2010 10:26:07 -0200 [thread overview]
Message-ID: <20100122122607.GE1244@ghostprotocols.net> (raw)
In-Reply-To: <1264162139-26788-2-git-send-email-t.fujak@samsung.com>
Em Fri, Jan 22, 2010 at 01:08:59PM +0100, Tomasz Fujak escreveu:
> Signed-off-by: Tomasz Fujak <t.fujak@samsung.com>
> Reviewed-by: Pawel Osciak <p.osciak@samsung.com>
> Reviewed-by: Marek Szyprowski <m.szyprowski@samsung.com>
> Reviewed-by: Kyungmin Park <kuyngmin.park@samsung.com>
"Extended" seems vague, I think in this context "platform_" would be a
better namespace specifier.
> ---
> tools/perf/util/parse-events.c | 224 ++++++++++++++++++++++++++++++++++++++--
> 1 files changed, 213 insertions(+), 11 deletions(-)
>
> diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
> index 05d0c5c..3e32198 100644
> --- a/tools/perf/util/parse-events.c
> +++ b/tools/perf/util/parse-events.c
> @@ -9,6 +9,9 @@
> #include "header.h"
> #include "debugfs.h"
>
> +#define EXTENDED_EVENT_PATH \
> + "/sys/devices/system/cpu/perf_events/extevents"
> +
> int nr_counters;
>
> struct perf_event_attr attrs[MAX_COUNTERS];
> @@ -60,6 +63,10 @@ static struct event_symbol event_symbols[] = {
> #define PERF_EVENT_TYPE(config) __PERF_EVENT_FIELD(config, TYPE)
> #define PERF_EVENT_ID(config) __PERF_EVENT_FIELD(config, EVENT)
>
> +static struct event_symbol *extended_event_symbols;
> +static unsigned int extended_event_count;
> +static int extended_events_initialized;
> +
> static const char *hw_event_names[] = {
> "cycles",
> "instructions",
> @@ -241,6 +248,157 @@ static const char *tracepoint_id_to_name(u64 config)
> return buf;
> }
>
> +static unsigned count_lines(const char *str, unsigned size)
> +{
> + unsigned count = 0;
> +
> + while (size--)
> + count += ('\n' == *str++);
> + return count;
> +}
> +
> +#define BYTES_PER_CHUNK 4096
> +/* returns the number of lines read;
> + on fail the return is negative and no memory is allocated
> + otherwise the *buf contains a memory chunk of which first
> + *size bytes are used for file contents
> + */
> +static int read_file(int fd, char **buf, unsigned *size)
> +{
> + unsigned bytes = BYTES_PER_CHUNK;
> + int lines = 0;
> + char *ptr = malloc(bytes);
malloc can fail... Also why is that you can't process the lines one by
one instead of reading the whole (albeit small) file at once?
> + *size = 0;
> + do {
> + int ret = read(fd, ptr + *size, bytes - *size);
> + if (ret < 0) {
> + if (EINTR == errno)
> + continue;
> + else {
> + free(ptr);
> + return -1;
> + }
> + }
> +
> + if (!ret)
> + break;
> +
> + lines += count_lines(ptr + *size, ret);
> + *size += ret;
> +
> + if (*size == bytes) {
> + char *tmp = realloc(ptr, bytes <<= 1);
> + if (!tmp) {
> + free(ptr);
> + return -1;
> + }
> + ptr = tmp;
> + }
> + } while (1);
> +
> + *buf = ptr;
> + return lines;
> +}
> +
> +static int parse_extevent_file(struct event_symbol *symbols,
> + unsigned lines, char *buf)
> +{
> + char *name, *description, *ptr, *end;
> + unsigned offset = 0, count = 0;
> + int items, eaten;
> + unsigned long long discard;
> +
> +/* each line format should be "0x%llx\t%s\t%lld-%lld\t%s\n" */
> + while (lines--) {
> + items = sscanf(buf + offset + 2, "%llx",
> + &symbols[count].config);
> + if (1 != items)
> + continue;
> +
> + /* skip 0x%llx\t */
> + ptr = strchr(buf + offset, '\t') + 1;
> +
> + name = description = NULL;
> +
> + end = strchr(ptr, '\t');
> + if (end) {
> + name = strndup(ptr, end - ptr);
> + ptr = end + 1;
> + }
> +
> + ptr = end;
> + items = sscanf(ptr, "%lld-%lld\t%n", &discard, &discard,
> + &eaten);
> + if (2 != items)
> + continue;
> +
> + ptr += eaten;
> + end = strchr(ptr, '\n');
> + if (end) {
> + description = strndup(ptr, end - ptr);
> + offset = end - buf + 1;
> + } else
> + break;
> +
> + if (name && description) {
> + symbols[count].symbol = name;
> + symbols[count].alias = "";
> + ++count;
> + /* description gets lost here */
> + free(description);
> + } else {
> + free(description);
> + free(name);
> + }
Having "free(description);" in both cases seems funny :-)
- Arnaldo
WARNING: multiple messages have this Message-ID (diff)
From: Arnaldo Carvalho de Melo <acme@infradead.org>
To: Tomasz Fujak <t.fujak@samsung.com>
Cc: linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org, jamie.iles@picochip.com,
will.deacon@arm.com, jpihet@mvista.com, mingo@elte.hu,
peterz@infradead.org, p.osciak@samsung.com,
m.szyprowski@samsung.com, kyungmin.park@samsung.com
Subject: Re: [PATCH v1 1/1] Extended events (platform-specific) support in perf
Date: Fri, 22 Jan 2010 10:26:07 -0200 [thread overview]
Message-ID: <20100122122607.GE1244@ghostprotocols.net> (raw)
In-Reply-To: <1264162139-26788-2-git-send-email-t.fujak@samsung.com>
Em Fri, Jan 22, 2010 at 01:08:59PM +0100, Tomasz Fujak escreveu:
> Signed-off-by: Tomasz Fujak <t.fujak@samsung.com>
> Reviewed-by: Pawel Osciak <p.osciak@samsung.com>
> Reviewed-by: Marek Szyprowski <m.szyprowski@samsung.com>
> Reviewed-by: Kyungmin Park <kuyngmin.park@samsung.com>
"Extended" seems vague, I think in this context "platform_" would be a
better namespace specifier.
> ---
> tools/perf/util/parse-events.c | 224 ++++++++++++++++++++++++++++++++++++++--
> 1 files changed, 213 insertions(+), 11 deletions(-)
>
> diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
> index 05d0c5c..3e32198 100644
> --- a/tools/perf/util/parse-events.c
> +++ b/tools/perf/util/parse-events.c
> @@ -9,6 +9,9 @@
> #include "header.h"
> #include "debugfs.h"
>
> +#define EXTENDED_EVENT_PATH \
> + "/sys/devices/system/cpu/perf_events/extevents"
> +
> int nr_counters;
>
> struct perf_event_attr attrs[MAX_COUNTERS];
> @@ -60,6 +63,10 @@ static struct event_symbol event_symbols[] = {
> #define PERF_EVENT_TYPE(config) __PERF_EVENT_FIELD(config, TYPE)
> #define PERF_EVENT_ID(config) __PERF_EVENT_FIELD(config, EVENT)
>
> +static struct event_symbol *extended_event_symbols;
> +static unsigned int extended_event_count;
> +static int extended_events_initialized;
> +
> static const char *hw_event_names[] = {
> "cycles",
> "instructions",
> @@ -241,6 +248,157 @@ static const char *tracepoint_id_to_name(u64 config)
> return buf;
> }
>
> +static unsigned count_lines(const char *str, unsigned size)
> +{
> + unsigned count = 0;
> +
> + while (size--)
> + count += ('\n' == *str++);
> + return count;
> +}
> +
> +#define BYTES_PER_CHUNK 4096
> +/* returns the number of lines read;
> + on fail the return is negative and no memory is allocated
> + otherwise the *buf contains a memory chunk of which first
> + *size bytes are used for file contents
> + */
> +static int read_file(int fd, char **buf, unsigned *size)
> +{
> + unsigned bytes = BYTES_PER_CHUNK;
> + int lines = 0;
> + char *ptr = malloc(bytes);
malloc can fail... Also why is that you can't process the lines one by
one instead of reading the whole (albeit small) file at once?
> + *size = 0;
> + do {
> + int ret = read(fd, ptr + *size, bytes - *size);
> + if (ret < 0) {
> + if (EINTR == errno)
> + continue;
> + else {
> + free(ptr);
> + return -1;
> + }
> + }
> +
> + if (!ret)
> + break;
> +
> + lines += count_lines(ptr + *size, ret);
> + *size += ret;
> +
> + if (*size == bytes) {
> + char *tmp = realloc(ptr, bytes <<= 1);
> + if (!tmp) {
> + free(ptr);
> + return -1;
> + }
> + ptr = tmp;
> + }
> + } while (1);
> +
> + *buf = ptr;
> + return lines;
> +}
> +
> +static int parse_extevent_file(struct event_symbol *symbols,
> + unsigned lines, char *buf)
> +{
> + char *name, *description, *ptr, *end;
> + unsigned offset = 0, count = 0;
> + int items, eaten;
> + unsigned long long discard;
> +
> +/* each line format should be "0x%llx\t%s\t%lld-%lld\t%s\n" */
> + while (lines--) {
> + items = sscanf(buf + offset + 2, "%llx",
> + &symbols[count].config);
> + if (1 != items)
> + continue;
> +
> + /* skip 0x%llx\t */
> + ptr = strchr(buf + offset, '\t') + 1;
> +
> + name = description = NULL;
> +
> + end = strchr(ptr, '\t');
> + if (end) {
> + name = strndup(ptr, end - ptr);
> + ptr = end + 1;
> + }
> +
> + ptr = end;
> + items = sscanf(ptr, "%lld-%lld\t%n", &discard, &discard,
> + &eaten);
> + if (2 != items)
> + continue;
> +
> + ptr += eaten;
> + end = strchr(ptr, '\n');
> + if (end) {
> + description = strndup(ptr, end - ptr);
> + offset = end - buf + 1;
> + } else
> + break;
> +
> + if (name && description) {
> + symbols[count].symbol = name;
> + symbols[count].alias = "";
> + ++count;
> + /* description gets lost here */
> + free(description);
> + } else {
> + free(description);
> + free(name);
> + }
Having "free(description);" in both cases seems funny :-)
- Arnaldo
next prev parent reply other threads:[~2010-01-22 12:26 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-01-22 12:08 [PATCH/RFC v1 0/1] Platform-specific event support in the perf Tomasz Fujak
2010-01-22 12:08 ` Tomasz Fujak
2010-01-22 12:08 ` [PATCH v1 1/1] Extended events (platform-specific) support in perf Tomasz Fujak
2010-01-22 12:08 ` Tomasz Fujak
2010-01-22 12:26 ` Arnaldo Carvalho de Melo [this message]
2010-01-22 12:26 ` Arnaldo Carvalho de Melo
2010-01-22 13:08 ` Tomasz Fujak
2010-01-22 13:08 ` Tomasz Fujak
2010-01-27 11:35 ` Peter Zijlstra
2010-01-27 11:35 ` Peter Zijlstra
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=20100122122607.GE1244@ghostprotocols.net \
--to=acme@infradead.org \
--cc=linux-arm-kernel@lists.infradead.org \
/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
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.