From: Junio C Hamano <gitster@pobox•com>
To: Karsten Blees <karsten.blees@gmail•com>
Cc: Git List <git@vger•kernel.org>, msysGit <msysgit@googlegroups•com>
Subject: Re: [PATCH v7 04/16] trace: improve trace performance
Date: Wed, 02 Jul 2014 11:15:52 -0700 [thread overview]
Message-ID: <xmqqsimjhbjb.fsf@gitster.dls.corp.google.com> (raw)
In-Reply-To: <53B33CD2.6000607@gmail.com> (Karsten Blees's message of "Wed, 02 Jul 2014 00:57:22 +0200")
Karsten Blees <karsten.blees@gmail•com> writes:
> Replace the 'const char *key' parameter in the API with a pointer to a
> 'struct trace_key' that bundles the environment variable name with
> additional, trace-internal state. Change the call sites of these APIs to
> use a static 'struct trace_key' instead of a string constant.
Nice. Very nice ;-).
> In trace.c::get_trace_fd(), save and reuse the file descriptor in 'struct
> trace_key'.
>
> Add a 'trace_disable()' API, so that packet_trace() can cleanly disable
> tracing when it encounters packed data (instead of using unsetenv()).
Again, very nice.
> Signed-off-by: Karsten Blees <blees@dcon•de>
> ---
> builtin/receive-pack.c | 2 +-
> commit.h | 1 +
> pkt-line.c | 8 ++--
> shallow.c | 10 ++---
> trace.c | 100 ++++++++++++++++++++++++++-----------------------
> trace.h | 16 ++++++--
> 6 files changed, 78 insertions(+), 59 deletions(-)
>
> diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c
> index c323081..1451050 100644
> --- a/builtin/receive-pack.c
> +++ b/builtin/receive-pack.c
> @@ -438,7 +438,7 @@ static int update_shallow_ref(struct command *cmd, struct shallow_info *si)
> uint32_t mask = 1 << (cmd->index % 32);
> int i;
>
> - trace_printf_key("GIT_TRACE_SHALLOW",
> + trace_printf_key(&trace_shallow,
> "shallow: update_shallow_ref %s\n", cmd->ref_name);
> for (i = 0; i < si->shallow->nr; i++)
> if (si->used_shallow[i] &&
> diff --git a/commit.h b/commit.h
> index a9f177b..08ef643 100644
> --- a/commit.h
> +++ b/commit.h
> @@ -235,6 +235,7 @@ extern void assign_shallow_commits_to_refs(struct shallow_info *info,
> int *ref_status);
> extern int delayed_reachability_test(struct shallow_info *si, int c);
> extern void prune_shallow(int show_only);
> +extern struct trace_key trace_shallow;
>
> int is_descendant_of(struct commit *, struct commit_list *);
> int in_merge_bases(struct commit *, struct commit *);
> diff --git a/pkt-line.c b/pkt-line.c
> index bc63b3b..8bc89b1 100644
> --- a/pkt-line.c
> +++ b/pkt-line.c
> @@ -3,7 +3,7 @@
>
> char packet_buffer[LARGE_PACKET_MAX];
> static const char *packet_trace_prefix = "git";
> -static const char trace_key[] = "GIT_TRACE_PACKET";
> +static struct trace_key trace_packet = TRACE_KEY_INIT(PACKET);
>
> void packet_trace_identity(const char *prog)
> {
> @@ -15,7 +15,7 @@ static void packet_trace(const char *buf, unsigned int len, int write)
> int i;
> struct strbuf out;
>
> - if (!trace_want(trace_key))
> + if (!trace_want(&trace_packet))
> return;
>
> /* +32 is just a guess for header + quoting */
> @@ -27,7 +27,7 @@ static void packet_trace(const char *buf, unsigned int len, int write)
> if ((len >= 4 && starts_with(buf, "PACK")) ||
> (len >= 5 && starts_with(buf+1, "PACK"))) {
> strbuf_addstr(&out, "PACK ...");
> - unsetenv(trace_key);
> + trace_disable(&trace_packet);
> }
> else {
> /* XXX we should really handle printable utf8 */
> @@ -43,7 +43,7 @@ static void packet_trace(const char *buf, unsigned int len, int write)
> }
>
> strbuf_addch(&out, '\n');
> - trace_strbuf(trace_key, &out);
> + trace_strbuf(&trace_packet, &out);
> strbuf_release(&out);
> }
>
> diff --git a/shallow.c b/shallow.c
> index 0b267b6..de07709 100644
> --- a/shallow.c
> +++ b/shallow.c
> @@ -325,7 +325,7 @@ void prune_shallow(int show_only)
> strbuf_release(&sb);
> }
>
> -#define TRACE_KEY "GIT_TRACE_SHALLOW"
> +struct trace_key trace_shallow = TRACE_KEY_INIT(SHALLOW);
>
> /*
> * Step 1, split sender shallow commits into "ours" and "theirs"
> @@ -334,7 +334,7 @@ void prune_shallow(int show_only)
> void prepare_shallow_info(struct shallow_info *info, struct sha1_array *sa)
> {
> int i;
> - trace_printf_key(TRACE_KEY, "shallow: prepare_shallow_info\n");
> + trace_printf_key(&trace_shallow, "shallow: prepare_shallow_info\n");
> memset(info, 0, sizeof(*info));
> info->shallow = sa;
> if (!sa)
> @@ -365,7 +365,7 @@ void remove_nonexistent_theirs_shallow(struct shallow_info *info)
> {
> unsigned char (*sha1)[20] = info->shallow->sha1;
> int i, dst;
> - trace_printf_key(TRACE_KEY, "shallow: remove_nonexistent_theirs_shallow\n");
> + trace_printf_key(&trace_shallow, "shallow: remove_nonexistent_theirs_shallow\n");
> for (i = dst = 0; i < info->nr_theirs; i++) {
> if (i != dst)
> info->theirs[dst] = info->theirs[i];
> @@ -516,7 +516,7 @@ void assign_shallow_commits_to_refs(struct shallow_info *info,
> int *shallow, nr_shallow = 0;
> struct paint_info pi;
>
> - trace_printf_key(TRACE_KEY, "shallow: assign_shallow_commits_to_refs\n");
> + trace_printf_key(&trace_shallow, "shallow: assign_shallow_commits_to_refs\n");
> shallow = xmalloc(sizeof(*shallow) * (info->nr_ours + info->nr_theirs));
> for (i = 0; i < info->nr_ours; i++)
> shallow[nr_shallow++] = info->ours[i];
> @@ -622,7 +622,7 @@ static void post_assign_shallow(struct shallow_info *info,
> int bitmap_nr = (info->ref->nr + 31) / 32;
> struct commit_array ca;
>
> - trace_printf_key(TRACE_KEY, "shallow: post_assign_shallow\n");
> + trace_printf_key(&trace_shallow, "shallow: post_assign_shallow\n");
> if (ref_status)
> memset(ref_status, 0, sizeof(*ref_status) * info->ref->nr);
>
> diff --git a/trace.c b/trace.c
> index 3e31558..8662b79 100644
> --- a/trace.c
> +++ b/trace.c
> @@ -26,43 +26,66 @@
> #include "quote.h"
>
> /* Get a trace file descriptor from "key" env variable. */
> -static int get_trace_fd(const char *key, int *need_close)
> +static int get_trace_fd(struct trace_key *key)
> {
> - char *trace = getenv(key);
> + static struct trace_key trace_default = { "GIT_TRACE" };
> + const char *trace;
> +
> + /* use default "GIT_TRACE" if NULL */
> + if (!key)
> + key = &trace_default;
> +
> + /* don't open twice */
> + if (key->initialized)
> + return key->fd;
> +
> + trace = getenv(key->key);
>
> if (!trace || !strcmp(trace, "") ||
> !strcmp(trace, "0") || !strcasecmp(trace, "false"))
> - return 0;
> - if (!strcmp(trace, "1") || !strcasecmp(trace, "true"))
> - return STDERR_FILENO;
> - if (strlen(trace) == 1 && isdigit(*trace))
> - return atoi(trace);
> - if (is_absolute_path(trace)) {
> + key->fd = 0;
> + else if (!strcmp(trace, "1") || !strcasecmp(trace, "true"))
> + key->fd = STDERR_FILENO;
> + else if (strlen(trace) == 1 && isdigit(*trace))
> + key->fd = atoi(trace);
> + else if (is_absolute_path(trace)) {
> int fd = open(trace, O_WRONLY | O_APPEND | O_CREAT, 0666);
> if (fd == -1) {
> fprintf(stderr,
> "Could not open '%s' for tracing: %s\n"
> "Defaulting to tracing on stderr...\n",
> trace, strerror(errno));
> - return STDERR_FILENO;
> + key->fd = STDERR_FILENO;
> + } else {
> + key->fd = fd;
> + key->need_close = 1;
> }
> - *need_close = 1;
> - return fd;
> + } else {
> + fprintf(stderr, "What does '%s' for %s mean?\n"
> + "If you want to trace into a file, then please set "
> + "%s to an absolute pathname (starting with /).\n"
> + "Defaulting to tracing on stderr...\n",
> + trace, key->key, key->key);
> + key->fd = STDERR_FILENO;
> }
>
> - fprintf(stderr, "What does '%s' for %s mean?\n", trace, key);
> - fprintf(stderr, "If you want to trace into a file, "
> - "then please set %s to an absolute pathname "
> - "(starting with /).\n", key);
> - fprintf(stderr, "Defaulting to tracing on stderr...\n");
> + key->initialized = 1;
> + return key->fd;
> +}
>
> - return STDERR_FILENO;
> +void trace_disable(struct trace_key *key)
> +{
> + if (key->need_close)
> + close(key->fd);
> + key->fd = 0;
> + key->initialized = 1;
> + key->need_close = 0;
> }
>
> static const char err_msg[] = "Could not trace into fd given by "
> "GIT_TRACE environment variable";
>
> -static void trace_vprintf(const char *key, const char *format, va_list ap)
> +static void trace_vprintf(struct trace_key *key, const char *format, va_list ap)
> {
> struct strbuf buf = STRBUF_INIT;
>
> @@ -75,7 +98,7 @@ static void trace_vprintf(const char *key, const char *format, va_list ap)
> strbuf_release(&buf);
> }
>
> -void trace_printf_key(const char *key, const char *format, ...)
> +void trace_printf_key(struct trace_key *key, const char *format, ...)
> {
> va_list ap;
> va_start(ap, format);
> @@ -87,31 +110,24 @@ void trace_printf(const char *format, ...)
> {
> va_list ap;
> va_start(ap, format);
> - trace_vprintf("GIT_TRACE", format, ap);
> + trace_vprintf(NULL, format, ap);
> va_end(ap);
> }
>
> -void trace_strbuf(const char *key, const struct strbuf *buf)
> +void trace_strbuf(struct trace_key *key, const struct strbuf *buf)
> {
> - int fd, need_close = 0;
> -
> - fd = get_trace_fd(key, &need_close);
> + int fd = get_trace_fd(key);
> if (!fd)
> return;
>
> write_or_whine_pipe(fd, buf->buf, buf->len, err_msg);
> -
> - if (need_close)
> - close(fd);
> }
>
> void trace_argv_printf(const char **argv, const char *format, ...)
> {
> struct strbuf buf = STRBUF_INIT;
> va_list ap;
> - int fd, need_close = 0;
> -
> - fd = get_trace_fd("GIT_TRACE", &need_close);
> + int fd = get_trace_fd(NULL);
> if (!fd)
> return;
>
> @@ -124,9 +140,6 @@ void trace_argv_printf(const char **argv, const char *format, ...)
> strbuf_addch(&buf, '\n');
> write_or_whine_pipe(fd, buf.buf, buf.len, err_msg);
> strbuf_release(&buf);
> -
> - if (need_close)
> - close(fd);
> }
>
> static const char *quote_crnl(const char *path)
> @@ -155,11 +168,11 @@ static const char *quote_crnl(const char *path)
> /* FIXME: move prefix to startup_info struct and get rid of this arg */
> void trace_repo_setup(const char *prefix)
> {
> - static const char *key = "GIT_TRACE_SETUP";
> + static struct trace_key key = TRACE_KEY_INIT(SETUP);
> const char *git_work_tree;
> char cwd[PATH_MAX];
>
> - if (!trace_want(key))
> + if (!trace_want(&key))
> return;
>
> if (!getcwd(cwd, PATH_MAX))
> @@ -171,18 +184,13 @@ void trace_repo_setup(const char *prefix)
> if (!prefix)
> prefix = "(null)";
>
> - trace_printf_key(key, "setup: git_dir: %s\n", quote_crnl(get_git_dir()));
> - trace_printf_key(key, "setup: worktree: %s\n", quote_crnl(git_work_tree));
> - trace_printf_key(key, "setup: cwd: %s\n", quote_crnl(cwd));
> - trace_printf_key(key, "setup: prefix: %s\n", quote_crnl(prefix));
> + trace_printf_key(&key, "setup: git_dir: %s\n", quote_crnl(get_git_dir()));
> + trace_printf_key(&key, "setup: worktree: %s\n", quote_crnl(git_work_tree));
> + trace_printf_key(&key, "setup: cwd: %s\n", quote_crnl(cwd));
> + trace_printf_key(&key, "setup: prefix: %s\n", quote_crnl(prefix));
> }
>
> -int trace_want(const char *key)
> +int trace_want(struct trace_key *key)
> {
> - const char *trace = getenv(key);
> -
> - if (!trace || !strcmp(trace, "") ||
> - !strcmp(trace, "0") || !strcasecmp(trace, "false"))
> - return 0;
> - return 1;
> + return !!get_trace_fd(key);
> }
> diff --git a/trace.h b/trace.h
> index 8fea50b..fbfd9f4 100644
> --- a/trace.h
> +++ b/trace.h
> @@ -4,14 +4,24 @@
> #include "git-compat-util.h"
> #include "strbuf.h"
>
> +struct trace_key {
> + const char const *key;
> + int fd;
> + char initialized : 1;
> + char need_close : 1;
> +};
> +
> +#define TRACE_KEY_INIT(name) { "GIT_TRACE_" #name }
> +
> __attribute__((format (printf, 1, 2)))
> extern void trace_printf(const char *format, ...);
> __attribute__((format (printf, 2, 3)))
> extern void trace_argv_printf(const char **argv, const char *format, ...);
> extern void trace_repo_setup(const char *prefix);
> -extern int trace_want(const char *key);
> +extern int trace_want(struct trace_key *key);
> +extern void trace_disable(struct trace_key *key);
> __attribute__((format (printf, 2, 3)))
> -extern void trace_printf_key(const char *key, const char *format, ...);
> -extern void trace_strbuf(const char *key, const struct strbuf *buf);
> +extern void trace_printf_key(struct trace_key *key, const char *format, ...);
> +extern void trace_strbuf(struct trace_key *key, const struct strbuf *buf);
>
> #endif /* TRACE_H */
> --
> 2.0.0.406.ge74f8ff
>
> --
--
--
*** Please reply-to-all at all times ***
*** (do not pretend to know who is subscribed and who is not) ***
*** Please avoid top-posting. ***
The msysGit Wiki is here: https://github.com/msysgit/msysgit/wiki - Github accounts are free.
You received this message because you are subscribed to the Google
Groups "msysGit" group.
To post to this group, send email to msysgit@googlegroups•com
To unsubscribe from this group, send email to
msysgit+unsubscribe@googlegroups•com
For more options, and view previous threads, visit this group at
http://groups.google.com/group/msysgit?hl=en_US?hl=en
---
You received this message because you are subscribed to the Google Groups "msysGit" group.
To unsubscribe from this group and stop receiving emails from it, send an email to msysgit+unsubscribe@googlegroups•com.
For more options, visit https://groups.google.com/d/optout.
next prev parent reply other threads:[~2014-07-02 18:16 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-07-01 22:53 [PATCH v7 00/16] add performance tracing facility Karsten Blees
2014-07-01 22:55 ` [PATCH v7 01/16] trace: move trace declarations from cache.h to new trace.h Karsten Blees
2014-07-01 22:56 ` [PATCH v7 02/16] trace: consistently name the format parameter Karsten Blees
2014-07-01 22:56 ` [PATCH v7 03/16] trace: remove redundant printf format attribute Karsten Blees
2014-07-01 22:57 ` [PATCH v7 04/16] trace: improve trace performance Karsten Blees
2014-07-02 18:15 ` Junio C Hamano [this message]
2014-07-01 22:58 ` [PATCH v7 05/16] Documentation/git.txt: improve documentation of 'GIT_TRACE*' variables Karsten Blees
2014-07-01 22:58 ` [PATCH v7 06/16] sha1_file: change GIT_TRACE_PACK_ACCESS logging to use trace API Karsten Blees
2014-07-01 22:59 ` [PATCH v7 07/16] trace: add infrastructure to augment trace output with additional info Karsten Blees
2014-07-01 22:59 ` [PATCH v7 08/16] trace: disable additional trace output for unit tests Karsten Blees
2014-07-01 23:00 ` [PATCH v7 09/16] trace: add current timestamp to all trace output Karsten Blees
2014-07-01 23:01 ` [PATCH v7 10/16] trace: move code around, in preparation to file:line output Karsten Blees
2014-07-01 23:02 ` [PATCH v7 11/16] trace: add 'file:line' to all trace output Karsten Blees
2014-07-02 18:57 ` Junio C Hamano
2014-07-02 19:05 ` Karsten Blees
2014-07-02 19:12 ` Junio C Hamano
2014-07-01 23:02 ` [PATCH v7 12/16] trace: add high resolution timer function to debug performance issues Karsten Blees
2014-07-01 23:03 ` [PATCH v7 13/16] trace: add trace_performance facility " Karsten Blees
2014-07-01 23:03 ` [PATCH v7 14/16] git: add performance tracing for git's main() function to debug scripts Karsten Blees
2014-07-01 23:04 ` [PATCH v7 15/16] wt-status: simplify performance measurement by using getnanotime() Karsten Blees
2014-07-01 23:05 ` [PATCH v7 16/16] progress: " Karsten Blees
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=xmqqsimjhbjb.fsf@gitster.dls.corp.google.com \
--to=gitster@pobox$(echo .)com \
--cc=git@vger$(echo .)kernel.org \
--cc=karsten.blees@gmail$(echo .)com \
--cc=msysgit@googlegroups$(echo .)com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
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