diff options
Diffstat (limited to 'trace.c')
-rw-r--r-- | trace.c | 120 |
1 files changed, 81 insertions, 39 deletions
@@ -18,33 +18,21 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ #include "cache.h" #include "quote.h" -/* - * "Normalize" a key argument by converting NULL to our trace_default, - * and otherwise passing through the value. All caller-facing functions - * should normalize their inputs in this way, though most get it - * for free by calling get_trace_fd() (directly or indirectly). - */ -static void normalize_trace_key(struct trace_key **key) -{ - static struct trace_key trace_default = { "GIT_TRACE" }; - if (!*key) - *key = &trace_default; -} +struct trace_key trace_default_key = { "GIT_TRACE", 0, 0, 0 }; +struct trace_key trace_perf_key = TRACE_KEY_INIT(PERFORMANCE); +struct trace_key trace_setup_key = TRACE_KEY_INIT(SETUP); /* Get a trace file descriptor from "key" env variable. */ static int get_trace_fd(struct trace_key *key) { const char *trace; - normalize_trace_key(&key); - /* don't open twice */ if (key->initialized) return key->fd; @@ -82,8 +70,6 @@ static int get_trace_fd(struct trace_key *key) void trace_disable(struct trace_key *key) { - normalize_trace_key(&key); - if (key->need_close) close(key->fd); key->fd = 0; @@ -129,7 +115,6 @@ static int prepare_trace_line(const char *file, int line, static void trace_write(struct trace_key *key, const void *buf, unsigned len) { if (write_in_full(get_trace_fd(key), buf, len) < 0) { - normalize_trace_key(&key); warning("unable to write trace for %s: %s", key->key, strerror(errno)); trace_disable(key); @@ -147,7 +132,6 @@ static void print_trace_line(struct trace_key *key, struct strbuf *buf) { strbuf_complete_line(buf); trace_write(key, buf->buf, buf->len); - strbuf_release(buf); } static void trace_vprintf_fl(const char *file, int line, struct trace_key *key, @@ -160,6 +144,7 @@ static void trace_vprintf_fl(const char *file, int line, struct trace_key *key, strbuf_vaddf(&buf, format, ap); print_trace_line(key, &buf); + strbuf_release(&buf); } static void trace_argv_vprintf_fl(const char *file, int line, @@ -168,13 +153,14 @@ static void trace_argv_vprintf_fl(const char *file, int line, { struct strbuf buf = STRBUF_INIT; - if (!prepare_trace_line(file, line, NULL, &buf)) + if (!prepare_trace_line(file, line, &trace_default_key, &buf)) return; strbuf_vaddf(&buf, format, ap); - sq_quote_argv(&buf, argv, 0); - print_trace_line(NULL, &buf); + sq_quote_argv_pretty(&buf, argv); + print_trace_line(&trace_default_key, &buf); + strbuf_release(&buf); } void trace_strbuf_fl(const char *file, int line, struct trace_key *key, @@ -187,14 +173,33 @@ void trace_strbuf_fl(const char *file, int line, struct trace_key *key, strbuf_addbuf(&buf, data); print_trace_line(key, &buf); + strbuf_release(&buf); } -static struct trace_key trace_perf_key = TRACE_KEY_INIT(PERFORMANCE); +static uint64_t perf_start_times[10]; +static int perf_indent; + +uint64_t trace_performance_enter(void) +{ + uint64_t now; + + if (!trace_want(&trace_perf_key)) + return 0; + + now = getnanotime(); + perf_start_times[perf_indent] = now; + if (perf_indent + 1 < ARRAY_SIZE(perf_start_times)) + perf_indent++; + else + BUG("Too deep indentation"); + return now; +} static void trace_performance_vprintf_fl(const char *file, int line, uint64_t nanos, const char *format, va_list ap) { + static const char space[] = " "; struct strbuf buf = STRBUF_INIT; if (!prepare_trace_line(file, line, &trace_perf_key, &buf)) @@ -203,11 +208,15 @@ static void trace_performance_vprintf_fl(const char *file, int line, strbuf_addf(&buf, "performance: %.9f s", (double) nanos / 1000000000); if (format && *format) { - strbuf_addstr(&buf, ": "); + if (perf_indent >= strlen(space)) + BUG("Too deep indentation"); + + strbuf_addf(&buf, ":%.*s ", perf_indent, space); strbuf_vaddf(&buf, format, ap); } print_trace_line(&trace_perf_key, &buf); + strbuf_release(&buf); } #ifndef HAVE_VARIADIC_MACROS @@ -216,7 +225,7 @@ void trace_printf(const char *format, ...) { va_list ap; va_start(ap, format); - trace_vprintf_fl(NULL, 0, NULL, format, ap); + trace_vprintf_fl(NULL, 0, &trace_default_key, format, ap); va_end(ap); } @@ -258,6 +267,24 @@ void trace_performance_since(uint64_t start, const char *format, ...) va_end(ap); } +void trace_performance_leave(const char *format, ...) +{ + va_list ap; + uint64_t since; + + if (perf_indent) + perf_indent--; + + if (!format) /* Allow callers to leave without tracing anything */ + return; + + since = perf_start_times[perf_indent]; + va_start(ap, format); + trace_performance_vprintf_fl(NULL, 0, getnanotime() - since, + format, ap); + va_end(ap); +} + #else void trace_printf_key_fl(const char *file, int line, struct trace_key *key, @@ -287,6 +314,24 @@ void trace_performance_fl(const char *file, int line, uint64_t nanos, va_end(ap); } +void trace_performance_leave_fl(const char *file, int line, + uint64_t nanos, const char *format, ...) +{ + va_list ap; + uint64_t since; + + if (perf_indent) + perf_indent--; + + if (!format) /* Allow callers to leave without tracing anything */ + return; + + since = perf_start_times[perf_indent]; + va_start(ap, format); + trace_performance_vprintf_fl(file, line, nanos - since, format, ap); + va_end(ap); +} + #endif /* HAVE_VARIADIC_MACROS */ @@ -315,11 +360,10 @@ 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 struct trace_key key = TRACE_KEY_INIT(SETUP); const char *git_work_tree; char *cwd; - if (!trace_want(&key)) + if (!trace_want(&trace_setup_key)) return; cwd = xgetcwd(); @@ -330,11 +374,11 @@ 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: git_common_dir: %s\n", quote_crnl(get_git_common_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(&trace_setup_key, "setup: git_dir: %s\n", quote_crnl(get_git_dir())); + trace_printf_key(&trace_setup_key, "setup: git_common_dir: %s\n", quote_crnl(get_git_common_dir())); + trace_printf_key(&trace_setup_key, "setup: worktree: %s\n", quote_crnl(git_work_tree)); + trace_printf_key(&trace_setup_key, "setup: cwd: %s\n", quote_crnl(cwd)); + trace_printf_key(&trace_setup_key, "setup: prefix: %s\n", quote_crnl(prefix)); free(cwd); } @@ -426,13 +470,11 @@ uint64_t getnanotime(void) } } -static uint64_t command_start_time; static struct strbuf command_line = STRBUF_INIT; static void print_command_performance_atexit(void) { - trace_performance_since(command_start_time, "git command:%s", - command_line.buf); + trace_performance_leave("git command:%s", command_line.buf); } void trace_command_performance(const char **argv) @@ -440,10 +482,10 @@ void trace_command_performance(const char **argv) if (!trace_want(&trace_perf_key)) return; - if (!command_start_time) + if (!command_line.len) atexit(print_command_performance_atexit); strbuf_reset(&command_line); - sq_quote_argv(&command_line, argv, 0); - command_start_time = getnanotime(); + sq_quote_argv_pretty(&command_line, argv); + trace_performance_enter(); } |