From: Namhyung Kim <namhyung@kernel.org>
To: David Ahern <dsahern@gmail.com>
Cc: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>,
Peter Zijlstra <a.p.zijlstra@chello.nl>,
Paul Mackerras <paulus@samba.org>, Ingo Molnar <mingo@kernel.org>,
Namhyung Kim <namhyung.kim@lge.com>,
LKML <linux-kernel@vger.kernel.org>, Jiri Olsa <jolsa@redhat.com>
Subject: Re: [PATCH 4/8] perf tools: Introduce struct perf_log
Date: Fri, 03 Jan 2014 17:49:35 +0900 [thread overview]
Message-ID: <8761q1fo0w.fsf@sejong.aot.lge.com> (raw)
In-Reply-To: <52BC426D.8020408@gmail.com> (David Ahern's message of "Thu, 26 Dec 2013 09:51:25 -0500")
Hi David,
On Thu, 26 Dec 2013 09:51:25 -0500, David Ahern wrote:
> On 12/26/13, 12:38 AM, Namhyung Kim wrote:
>> diff --git a/tools/perf/util/log.c b/tools/perf/util/log.c
>> new file mode 100644
>> index 000000000000..3838d49f82de
>> --- /dev/null
>> +++ b/tools/perf/util/log.c
>> @@ -0,0 +1,105 @@
>> +#include <stdio.h>
>> +#include <stdlib.h>
>> +#include "util/debug.h"
>> +
>> +#define LINEMAP_GROW 128
>> +
>> +struct perf_log perf_log = {
>> + .seen_newline = true,
>> +};
>> +
>> +int perf_log_init(void)
>
> Why return int if the rc is not checked? Failure here is not going to
> stop the perf command right?
Right. I'll add a debug print if it's failed.
>
>> +{
>> + FILE *fp;
>> + char name[] = "/tmp/perf-log-XXXXXX";
>> + int fd = mkstemp(name);
>> +
>> + if (fd < 0)
>> + return -1;
>> +
>> + fp = fdopen(fd, "r+");
>> + if (fp == NULL) {
>> + close(fd);
>> + return -1;
>> + }
>> +
>> + perf_log.fp = fp;
>
> Add 'unlink(name);' here to ensure the file is removed regardless of
> how perf terminates.
Ah, okay. I thought the mkstemp() unlinked the file after open()
returns. It seems this is what tmpfile(3) does. I'll switch to
tmpfile() then.
>
>> +
>> + return 0;
>> +}
>> +
>> +int perf_log_exit(void)
>> +{
>> + FILE *fp = perf_log.fp;
>> + if (fp)
>> + fclose(fp);
>> +
>> + free(perf_log.linemap);
>> +
>> + perf_log.fp = NULL;
>> + perf_log.linemap = NULL;
>> + return 0;
>> +}
>> +
>> +static int grow_linemap(struct perf_log *log)
>> +{
>> + off_t *newmap;
>> + int newsize = log->nr_alloc + LINEMAP_GROW;
>> +
>> + newmap = realloc(log->linemap, newsize * sizeof(*log->linemap));
>> + if (newmap == NULL)
>> + return -1;
>> +
>> + log->nr_alloc = newsize;
>> + log->linemap = newmap;
>> + return 0;
>> +}
>
> What's the point of linemap?
To save an offset of each line. We need to keep it in order to move to
an arbitraty line in the browser.
>
>> +
>> +static int __add_to_linemap(struct perf_log *log, off_t idx)
>> +{
>> + if (log->lines == log->nr_alloc)
>> + if (grow_linemap(log) < 0)
>> + return -1;
>> +
>> + log->linemap[log->lines++] = idx;
>> + return 0;
>> +}
>> +
>> +static void add_to_linemap(struct perf_log *log, const char *msg, off_t base)
>> +{
>> + const char *pos;
>> +
>> + if (strlen(msg) == 0)
>> + return;
>> +
>> + if (log->seen_newline) {
>> + if (__add_to_linemap(log, base) < 0)
>> + return;
>> + }
>> +
>> + if ((pos = strchr(msg, '\n')) != NULL) {
>> + log->seen_newline = true;
>> + pos++;
>> + add_to_linemap(log, pos, base + (pos - msg));
>> + } else {
>> + log->seen_newline = false;
>> + }
>> +}
>> +
>> +void perf_log_add(const char *msg)
>> +{
>> + FILE *fp = perf_log.fp;
>
> Don't assume every user of libperf calls perf_log_init() or that the
> file was actually created. i.e., add 'if (fp == NULL) return;'
Okay.
>
>
>> + off_t offset = ftello(fp);
>> +
>> + add_to_linemap(&perf_log, msg, offset);
>> +
>> + fwrite(msg, 1, strlen(msg), fp);
>
> And if write fails?
Hmm.. it's a problem. We might go back to original linemap position for
a failure case. I'll save the offset and line number and restore them.
>
>> +}
>> +
>> +void perf_log_addv(const char *fmt, va_list ap)
>> +{
>> + char buf[4096];
>
> Add as an optimization add the fp != NULL check here too. Don't need
> to do the vsnprintf only to drop it.
Okay.
>
>> +
>> + vsnprintf(buf, sizeof(buf), fmt, ap);
>> + perf_log_add(buf);
>> +}
>>
>
> What limits the size of the file - other than the obvious out of space
> in /tmp? Allow the file to grow without bounds in case a user wants
> the messages seems dangerous.
Hmm. I don't have an idea what the reasonable size. It's a temp file
anyway and usually it contains not much data - well, 'perf top -vvv' is
different and might need some surgery.
>
> What about using a circular buffer instead?
Instead of a file? Yes, it's possible but I think it might not be a
good choice for the browser since it could alter the index during the
circulation so that the browser can confuse to update the entries.
Thanks,
Namhyung
next prev parent reply other threads:[~2014-01-03 8:49 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-12-26 5:37 [PATCHSET 0/8] perf tools: A couple of TUI improvements (v3) Namhyung Kim
2013-12-26 5:37 ` [PATCH 1/8] perf ui/tui: Protect windows by ui__lock Namhyung Kim
2014-01-12 18:39 ` [tip:perf/core] " tip-bot for Namhyung Kim
2013-12-26 5:37 ` [PATCH 2/8] perf ui/tui: Split help message for perf top and report Namhyung Kim
2013-12-26 14:05 ` Arnaldo Carvalho de Melo
2013-12-26 14:12 ` Arnaldo Carvalho de Melo
2014-01-12 18:39 ` [tip:perf/core] " tip-bot for Namhyung Kim
2013-12-26 5:37 ` [PATCH 3/8] perf ui/tui: Implement header window Namhyung Kim
2014-01-12 18:39 ` [tip:perf/core] " tip-bot for Namhyung Kim
2013-12-26 5:38 ` [PATCH 4/8] perf tools: Introduce struct perf_log Namhyung Kim
2013-12-26 14:50 ` Arnaldo Carvalho de Melo
2014-01-03 8:23 ` Namhyung Kim
2013-12-26 14:51 ` David Ahern
2014-01-03 8:49 ` Namhyung Kim [this message]
2013-12-26 5:38 ` [PATCH 5/8] perf tools: Save message when pr_*() was called Namhyung Kim
2013-12-26 5:38 ` [PATCH 6/8] perf ui/tui: Implement log window Namhyung Kim
2013-12-26 5:38 ` [PATCH 7/8] perf ui/tui: Filter messages in " Namhyung Kim
2013-12-26 5:38 ` [PATCH 8/8] perf ui/tui: Remember last log line for filtering Namhyung Kim
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=8761q1fo0w.fsf@sejong.aot.lge.com \
--to=namhyung@kernel.org \
--cc=a.p.zijlstra@chello.nl \
--cc=acme@ghostprotocols.net \
--cc=dsahern@gmail.com \
--cc=jolsa@redhat.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@kernel.org \
--cc=namhyung.kim@lge.com \
--cc=paulus@samba.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Powered by JetHome