diff options
Diffstat (limited to 'third_party/git/trace2')
-rw-r--r-- | third_party/git/trace2/tr2_cfg.c | 147 | ||||
-rw-r--r-- | third_party/git/trace2/tr2_cfg.h | 27 | ||||
-rw-r--r-- | third_party/git/trace2/tr2_cmd_name.c | 30 | ||||
-rw-r--r-- | third_party/git/trace2/tr2_cmd_name.h | 24 | ||||
-rw-r--r-- | third_party/git/trace2/tr2_dst.c | 391 | ||||
-rw-r--r-- | third_party/git/trace2/tr2_dst.h | 38 | ||||
-rw-r--r-- | third_party/git/trace2/tr2_sid.c | 112 | ||||
-rw-r--r-- | third_party/git/trace2/tr2_sid.h | 18 | ||||
-rw-r--r-- | third_party/git/trace2/tr2_sysenv.c | 132 | ||||
-rw-r--r-- | third_party/git/trace2/tr2_sysenv.h | 39 | ||||
-rw-r--r-- | third_party/git/trace2/tr2_tbuf.c | 47 | ||||
-rw-r--r-- | third_party/git/trace2/tr2_tbuf.h | 24 | ||||
-rw-r--r-- | third_party/git/trace2/tr2_tgt.h | 134 | ||||
-rw-r--r-- | third_party/git/trace2/tr2_tgt_event.c | 603 | ||||
-rw-r--r-- | third_party/git/trace2/tr2_tgt_normal.c | 325 | ||||
-rw-r--r-- | third_party/git/trace2/tr2_tgt_perf.c | 551 | ||||
-rw-r--r-- | third_party/git/trace2/tr2_tls.c | 180 | ||||
-rw-r--r-- | third_party/git/trace2/tr2_tls.h | 103 |
18 files changed, 0 insertions, 2925 deletions
diff --git a/third_party/git/trace2/tr2_cfg.c b/third_party/git/trace2/tr2_cfg.c deleted file mode 100644 index ec9ac1a6efd3..000000000000 --- a/third_party/git/trace2/tr2_cfg.c +++ /dev/null @@ -1,147 +0,0 @@ -#include "cache.h" -#include "config.h" -#include "trace2/tr2_cfg.h" -#include "trace2/tr2_sysenv.h" - -static struct strbuf **tr2_cfg_patterns; -static int tr2_cfg_count_patterns; -static int tr2_cfg_loaded; - -static struct strbuf **tr2_cfg_env_vars; -static int tr2_cfg_env_vars_count; -static int tr2_cfg_env_vars_loaded; - -/* - * Parse a string containing a comma-delimited list of config keys - * or wildcard patterns into a list of strbufs. - */ -static int tr2_cfg_load_patterns(void) -{ - struct strbuf **s; - const char *envvar; - - if (tr2_cfg_loaded) - return tr2_cfg_count_patterns; - tr2_cfg_loaded = 1; - - envvar = tr2_sysenv_get(TR2_SYSENV_CFG_PARAM); - if (!envvar || !*envvar) - return tr2_cfg_count_patterns; - - tr2_cfg_patterns = strbuf_split_buf(envvar, strlen(envvar), ',', -1); - for (s = tr2_cfg_patterns; *s; s++) { - struct strbuf *buf = *s; - - if (buf->len && buf->buf[buf->len - 1] == ',') - strbuf_setlen(buf, buf->len - 1); - strbuf_trim_trailing_newline(*s); - strbuf_trim(*s); - } - - tr2_cfg_count_patterns = s - tr2_cfg_patterns; - return tr2_cfg_count_patterns; -} - -void tr2_cfg_free_patterns(void) -{ - if (tr2_cfg_patterns) - strbuf_list_free(tr2_cfg_patterns); - tr2_cfg_count_patterns = 0; - tr2_cfg_loaded = 0; -} - -/* - * Parse a string containing a comma-delimited list of environment variable - * names into a list of strbufs. - */ -static int tr2_load_env_vars(void) -{ - struct strbuf **s; - const char *varlist; - - if (tr2_cfg_env_vars_loaded) - return tr2_cfg_env_vars_count; - tr2_cfg_env_vars_loaded = 1; - - varlist = tr2_sysenv_get(TR2_SYSENV_ENV_VARS); - if (!varlist || !*varlist) - return tr2_cfg_env_vars_count; - - tr2_cfg_env_vars = strbuf_split_buf(varlist, strlen(varlist), ',', -1); - for (s = tr2_cfg_env_vars; *s; s++) { - struct strbuf *buf = *s; - - if (buf->len && buf->buf[buf->len - 1] == ',') - strbuf_setlen(buf, buf->len - 1); - strbuf_trim_trailing_newline(*s); - strbuf_trim(*s); - } - - tr2_cfg_env_vars_count = s - tr2_cfg_env_vars; - return tr2_cfg_env_vars_count; -} - -void tr2_cfg_free_env_vars(void) -{ - if (tr2_cfg_env_vars) - strbuf_list_free(tr2_cfg_env_vars); - tr2_cfg_env_vars_count = 0; - tr2_cfg_env_vars_loaded = 0; -} - -struct tr2_cfg_data { - const char *file; - int line; -}; - -/* - * See if the given config key matches any of our patterns of interest. - */ -static int tr2_cfg_cb(const char *key, const char *value, void *d) -{ - struct strbuf **s; - struct tr2_cfg_data *data = (struct tr2_cfg_data *)d; - - for (s = tr2_cfg_patterns; *s; s++) { - struct strbuf *buf = *s; - int wm = wildmatch(buf->buf, key, WM_CASEFOLD); - if (wm == WM_MATCH) { - trace2_def_param_fl(data->file, data->line, key, value); - return 0; - } - } - - return 0; -} - -void tr2_cfg_list_config_fl(const char *file, int line) -{ - struct tr2_cfg_data data = { file, line }; - - if (tr2_cfg_load_patterns() > 0) - read_early_config(tr2_cfg_cb, &data); -} - -void tr2_list_env_vars_fl(const char *file, int line) -{ - struct strbuf **s; - - if (tr2_load_env_vars() <= 0) - return; - - for (s = tr2_cfg_env_vars; *s; s++) { - struct strbuf *buf = *s; - const char *val = getenv(buf->buf); - if (val && *val) - trace2_def_param_fl(file, line, buf->buf, val); - } -} - -void tr2_cfg_set_fl(const char *file, int line, const char *key, - const char *value) -{ - struct tr2_cfg_data data = { file, line }; - - if (tr2_cfg_load_patterns() > 0) - tr2_cfg_cb(key, value, &data); -} diff --git a/third_party/git/trace2/tr2_cfg.h b/third_party/git/trace2/tr2_cfg.h deleted file mode 100644 index a11d71feb5bf..000000000000 --- a/third_party/git/trace2/tr2_cfg.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef TR2_CFG_H -#define TR2_CFG_H - -/* - * Iterate over all config settings and emit 'def_param' events for the - * "interesting" ones to TRACE2. - */ -void tr2_cfg_list_config_fl(const char *file, int line); - -/* - * Iterate over all "interesting" environment variables and emit 'def_param' - * events for them to TRACE2. - */ -void tr2_list_env_vars_fl(const char *file, int line); - -/* - * Emit a "def_param" event for the given key/value pair IF we consider - * the key to be "interesting". - */ -void tr2_cfg_set_fl(const char *file, int line, const char *key, - const char *value); - -void tr2_cfg_free_patterns(void); - -void tr2_cfg_free_env_vars(void); - -#endif /* TR2_CFG_H */ diff --git a/third_party/git/trace2/tr2_cmd_name.c b/third_party/git/trace2/tr2_cmd_name.c deleted file mode 100644 index dd313204f517..000000000000 --- a/third_party/git/trace2/tr2_cmd_name.c +++ /dev/null @@ -1,30 +0,0 @@ -#include "cache.h" -#include "trace2/tr2_cmd_name.h" - -#define TR2_ENVVAR_PARENT_NAME "GIT_TRACE2_PARENT_NAME" - -static struct strbuf tr2cmdname_hierarchy = STRBUF_INIT; - -void tr2_cmd_name_append_hierarchy(const char *name) -{ - const char *parent_name = getenv(TR2_ENVVAR_PARENT_NAME); - - strbuf_reset(&tr2cmdname_hierarchy); - if (parent_name && *parent_name) { - strbuf_addstr(&tr2cmdname_hierarchy, parent_name); - strbuf_addch(&tr2cmdname_hierarchy, '/'); - } - strbuf_addstr(&tr2cmdname_hierarchy, name); - - setenv(TR2_ENVVAR_PARENT_NAME, tr2cmdname_hierarchy.buf, 1); -} - -const char *tr2_cmd_name_get_hierarchy(void) -{ - return tr2cmdname_hierarchy.buf; -} - -void tr2_cmd_name_release(void) -{ - strbuf_release(&tr2cmdname_hierarchy); -} diff --git a/third_party/git/trace2/tr2_cmd_name.h b/third_party/git/trace2/tr2_cmd_name.h deleted file mode 100644 index ab70b67a8e03..000000000000 --- a/third_party/git/trace2/tr2_cmd_name.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef TR2_CMD_NAME_H -#define TR2_CMD_NAME_H - -/* - * Append the current command name to the list being maintained - * in the environment. - * - * The hierarchy for a top-level git command is just the current - * command name. For a child git process, the hierarchy includes the - * names of the parent processes. - * - * The hierarchy for the current process will be exported to the - * environment and inherited by child processes. - */ -void tr2_cmd_name_append_hierarchy(const char *name); - -/* - * Get the command name hierarchy for the current process. - */ -const char *tr2_cmd_name_get_hierarchy(void); - -void tr2_cmd_name_release(void); - -#endif /* TR2_CMD_NAME_H */ diff --git a/third_party/git/trace2/tr2_dst.c b/third_party/git/trace2/tr2_dst.c deleted file mode 100644 index ae052a07fe2e..000000000000 --- a/third_party/git/trace2/tr2_dst.c +++ /dev/null @@ -1,391 +0,0 @@ -#include "cache.h" -#include "trace2/tr2_dst.h" -#include "trace2/tr2_sid.h" -#include "trace2/tr2_sysenv.h" - -/* - * How many attempts we will make at creating an automatically-named trace file. - */ -#define MAX_AUTO_ATTEMPTS 10 - -/* - * Sentinel file used to detect when we should discard new traces to avoid - * writing too many trace files to a directory. - */ -#define DISCARD_SENTINEL_NAME "git-trace2-discard" - -/* - * When set to zero, disables directory file count checks. Otherwise, controls - * how many files we can write to a directory before entering discard mode. - * This can be overridden via the TR2_SYSENV_MAX_FILES setting. - */ -static int tr2env_max_files = 0; - -static int tr2_dst_want_warning(void) -{ - static int tr2env_dst_debug = -1; - - if (tr2env_dst_debug == -1) { - const char *env_value = tr2_sysenv_get(TR2_SYSENV_DST_DEBUG); - if (!env_value || !*env_value) - tr2env_dst_debug = 0; - else - tr2env_dst_debug = atoi(env_value) > 0; - } - - return tr2env_dst_debug; -} - -void tr2_dst_trace_disable(struct tr2_dst *dst) -{ - if (dst->need_close) - close(dst->fd); - dst->fd = 0; - dst->initialized = 1; - dst->need_close = 0; -} - -/* - * Check to make sure we're not overloading the target directory with too many - * files. First get the threshold (if present) from the config or envvar. If - * it's zero or unset, disable this check. Next check for the presence of a - * sentinel file, then check file count. - * - * Returns 0 if tracing should proceed as normal. Returns 1 if the sentinel file - * already exists, which means tracing should be disabled. Returns -1 if there - * are too many files but there was no sentinel file, which means we have - * created and should write traces to the sentinel file. - * - * We expect that some trace processing system is gradually collecting files - * from the target directory; after it removes the sentinel file we'll start - * writing traces again. - */ -static int tr2_dst_too_many_files(struct tr2_dst *dst, const char *tgt_prefix) -{ - int file_count = 0, max_files = 0, ret = 0; - const char *max_files_var; - DIR *dirp; - struct strbuf path = STRBUF_INIT, sentinel_path = STRBUF_INIT; - struct stat statbuf; - - /* Get the config or envvar and decide if we should continue this check */ - max_files_var = tr2_sysenv_get(TR2_SYSENV_MAX_FILES); - if (max_files_var && *max_files_var && ((max_files = atoi(max_files_var)) >= 0)) - tr2env_max_files = max_files; - - if (!tr2env_max_files) { - ret = 0; - goto cleanup; - } - - strbuf_addstr(&path, tgt_prefix); - if (!is_dir_sep(path.buf[path.len - 1])) { - strbuf_addch(&path, '/'); - } - - /* check sentinel */ - strbuf_addbuf(&sentinel_path, &path); - strbuf_addstr(&sentinel_path, DISCARD_SENTINEL_NAME); - if (!stat(sentinel_path.buf, &statbuf)) { - ret = 1; - goto cleanup; - } - - /* check file count */ - dirp = opendir(path.buf); - while (file_count < tr2env_max_files && dirp && readdir(dirp)) - file_count++; - if (dirp) - closedir(dirp); - - if (file_count >= tr2env_max_files) { - dst->too_many_files = 1; - dst->fd = open(sentinel_path.buf, O_WRONLY | O_CREAT | O_EXCL, 0666); - ret = -1; - goto cleanup; - } - -cleanup: - strbuf_release(&path); - strbuf_release(&sentinel_path); - return ret; -} - -static int tr2_dst_try_auto_path(struct tr2_dst *dst, const char *tgt_prefix) -{ - int too_many_files; - const char *last_slash, *sid = tr2_sid_get(); - struct strbuf path = STRBUF_INIT; - size_t base_path_len; - unsigned attempt_count; - - last_slash = strrchr(sid, '/'); - if (last_slash) - sid = last_slash + 1; - - strbuf_addstr(&path, tgt_prefix); - if (!is_dir_sep(path.buf[path.len - 1])) - strbuf_addch(&path, '/'); - strbuf_addstr(&path, sid); - base_path_len = path.len; - - too_many_files = tr2_dst_too_many_files(dst, tgt_prefix); - if (!too_many_files) { - for (attempt_count = 0; attempt_count < MAX_AUTO_ATTEMPTS; attempt_count++) { - if (attempt_count > 0) { - strbuf_setlen(&path, base_path_len); - strbuf_addf(&path, ".%d", attempt_count); - } - - dst->fd = open(path.buf, O_WRONLY | O_CREAT | O_EXCL, 0666); - if (dst->fd != -1) - break; - } - } else if (too_many_files == 1) { - strbuf_release(&path); - if (tr2_dst_want_warning()) - warning("trace2: not opening %s trace file due to too " - "many files in target directory %s", - tr2_sysenv_display_name(dst->sysenv_var), - tgt_prefix); - return 0; - } - - if (dst->fd == -1) { - if (tr2_dst_want_warning()) - warning("trace2: could not open '%.*s' for '%s' tracing: %s", - (int) base_path_len, path.buf, - tr2_sysenv_display_name(dst->sysenv_var), - strerror(errno)); - - tr2_dst_trace_disable(dst); - strbuf_release(&path); - return 0; - } - - strbuf_release(&path); - - dst->need_close = 1; - dst->initialized = 1; - - return dst->fd; -} - -static int tr2_dst_try_path(struct tr2_dst *dst, const char *tgt_value) -{ - int fd = open(tgt_value, O_WRONLY | O_APPEND | O_CREAT, 0666); - if (fd == -1) { - if (tr2_dst_want_warning()) - warning("trace2: could not open '%s' for '%s' tracing: %s", - tgt_value, - tr2_sysenv_display_name(dst->sysenv_var), - strerror(errno)); - - tr2_dst_trace_disable(dst); - return 0; - } - - dst->fd = fd; - dst->need_close = 1; - dst->initialized = 1; - - return dst->fd; -} - -#ifndef NO_UNIX_SOCKETS -#define PREFIX_AF_UNIX "af_unix:" -#define PREFIX_AF_UNIX_STREAM "af_unix:stream:" -#define PREFIX_AF_UNIX_DGRAM "af_unix:dgram:" - -static int tr2_dst_try_uds_connect(const char *path, int sock_type, int *out_fd) -{ - int fd; - struct sockaddr_un sa; - - fd = socket(AF_UNIX, sock_type, 0); - if (fd == -1) - return errno; - - sa.sun_family = AF_UNIX; - strlcpy(sa.sun_path, path, sizeof(sa.sun_path)); - - if (connect(fd, (struct sockaddr *)&sa, sizeof(sa)) == -1) { - int e = errno; - close(fd); - return e; - } - - *out_fd = fd; - return 0; -} - -#define TR2_DST_UDS_TRY_STREAM (1 << 0) -#define TR2_DST_UDS_TRY_DGRAM (1 << 1) - -static int tr2_dst_try_unix_domain_socket(struct tr2_dst *dst, - const char *tgt_value) -{ - unsigned int uds_try = 0; - int fd; - int e; - const char *path = NULL; - - /* - * Allow "af_unix:[<type>:]<absolute_path>" - * - * Trace2 always writes complete individual messages (without - * chunking), so we can talk to either DGRAM or STREAM type sockets. - * - * Allow the user to explicitly request the socket type. - * - * If they omit the socket type, try one and then the other. - */ - - if (skip_prefix(tgt_value, PREFIX_AF_UNIX_STREAM, &path)) - uds_try |= TR2_DST_UDS_TRY_STREAM; - - else if (skip_prefix(tgt_value, PREFIX_AF_UNIX_DGRAM, &path)) - uds_try |= TR2_DST_UDS_TRY_DGRAM; - - else if (skip_prefix(tgt_value, PREFIX_AF_UNIX, &path)) - uds_try |= TR2_DST_UDS_TRY_STREAM | TR2_DST_UDS_TRY_DGRAM; - - if (!path || !*path) { - if (tr2_dst_want_warning()) - warning("trace2: invalid AF_UNIX value '%s' for '%s' tracing", - tgt_value, - tr2_sysenv_display_name(dst->sysenv_var)); - - tr2_dst_trace_disable(dst); - return 0; - } - - if (!is_absolute_path(path) || - strlen(path) >= sizeof(((struct sockaddr_un *)0)->sun_path)) { - if (tr2_dst_want_warning()) - warning("trace2: invalid AF_UNIX path '%s' for '%s' tracing", - path, tr2_sysenv_display_name(dst->sysenv_var)); - - tr2_dst_trace_disable(dst); - return 0; - } - - if (uds_try & TR2_DST_UDS_TRY_STREAM) { - e = tr2_dst_try_uds_connect(path, SOCK_STREAM, &fd); - if (!e) - goto connected; - if (e != EPROTOTYPE) - goto error; - } - if (uds_try & TR2_DST_UDS_TRY_DGRAM) { - e = tr2_dst_try_uds_connect(path, SOCK_DGRAM, &fd); - if (!e) - goto connected; - } - -error: - if (tr2_dst_want_warning()) - warning("trace2: could not connect to socket '%s' for '%s' tracing: %s", - path, tr2_sysenv_display_name(dst->sysenv_var), - strerror(e)); - - tr2_dst_trace_disable(dst); - return 0; - -connected: - dst->fd = fd; - dst->need_close = 1; - dst->initialized = 1; - - return dst->fd; -} -#endif - -static void tr2_dst_malformed_warning(struct tr2_dst *dst, - const char *tgt_value) -{ - warning("trace2: unknown value for '%s': '%s'", - tr2_sysenv_display_name(dst->sysenv_var), tgt_value); -} - -int tr2_dst_get_trace_fd(struct tr2_dst *dst) -{ - const char *tgt_value; - - /* don't open twice */ - if (dst->initialized) - return dst->fd; - - dst->initialized = 1; - - tgt_value = tr2_sysenv_get(dst->sysenv_var); - - if (!tgt_value || !strcmp(tgt_value, "") || !strcmp(tgt_value, "0") || - !strcasecmp(tgt_value, "false")) { - dst->fd = 0; - return dst->fd; - } - - if (!strcmp(tgt_value, "1") || !strcasecmp(tgt_value, "true")) { - dst->fd = STDERR_FILENO; - return dst->fd; - } - - if (strlen(tgt_value) == 1 && isdigit(*tgt_value)) { - dst->fd = atoi(tgt_value); - return dst->fd; - } - - if (is_absolute_path(tgt_value)) { - if (is_directory(tgt_value)) - return tr2_dst_try_auto_path(dst, tgt_value); - else - return tr2_dst_try_path(dst, tgt_value); - } - -#ifndef NO_UNIX_SOCKETS - if (starts_with(tgt_value, PREFIX_AF_UNIX)) - return tr2_dst_try_unix_domain_socket(dst, tgt_value); -#endif - - /* Always warn about malformed values. */ - tr2_dst_malformed_warning(dst, tgt_value); - tr2_dst_trace_disable(dst); - return 0; -} - -int tr2_dst_trace_want(struct tr2_dst *dst) -{ - return !!tr2_dst_get_trace_fd(dst); -} - -void tr2_dst_write_line(struct tr2_dst *dst, struct strbuf *buf_line) -{ - int fd = tr2_dst_get_trace_fd(dst); - - strbuf_complete_line(buf_line); /* ensure final NL on buffer */ - - /* - * We do not use write_in_full() because we do not want - * a short-write to try again. We are using O_APPEND mode - * files and the kernel handles the atomic seek+write. If - * another thread or git process is concurrently writing to - * this fd or file, our remainder-write may not be contiguous - * with our initial write of this message. And that will - * confuse readers. So just don't bother. - * - * It is assumed that TRACE2 messages are short enough that - * the system can write them in 1 attempt and we won't see - * a short-write. - * - * If we get an IO error, just close the trace dst. - */ - if (write(fd, buf_line->buf, buf_line->len) >= 0) - return; - - if (tr2_dst_want_warning()) - warning("unable to write trace to '%s': %s", - tr2_sysenv_display_name(dst->sysenv_var), - strerror(errno)); - tr2_dst_trace_disable(dst); -} diff --git a/third_party/git/trace2/tr2_dst.h b/third_party/git/trace2/tr2_dst.h deleted file mode 100644 index b1a8c144e073..000000000000 --- a/third_party/git/trace2/tr2_dst.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef TR2_DST_H -#define TR2_DST_H - -struct strbuf; -#include "trace2/tr2_sysenv.h" - -struct tr2_dst { - enum tr2_sysenv_variable sysenv_var; - int fd; - unsigned int initialized : 1; - unsigned int need_close : 1; - unsigned int too_many_files : 1; -}; - -/* - * Disable TRACE2 on the destination. In TRACE2 a destination (DST) - * wraps a file descriptor; it is associated with a TARGET which - * defines the formatting. - */ -void tr2_dst_trace_disable(struct tr2_dst *dst); - -/* - * Return the file descriptor for the DST. - * If 0, the dst is closed or disabled. - */ -int tr2_dst_get_trace_fd(struct tr2_dst *dst); - -/* - * Return true if the DST is opened for writing. - */ -int tr2_dst_trace_want(struct tr2_dst *dst); - -/* - * Write a single line/message to the trace file. - */ -void tr2_dst_write_line(struct tr2_dst *dst, struct strbuf *buf_line); - -#endif /* TR2_DST_H */ diff --git a/third_party/git/trace2/tr2_sid.c b/third_party/git/trace2/tr2_sid.c deleted file mode 100644 index dc6e75ef1315..000000000000 --- a/third_party/git/trace2/tr2_sid.c +++ /dev/null @@ -1,112 +0,0 @@ -#include "cache.h" -#include "trace2/tr2_tbuf.h" -#include "trace2/tr2_sid.h" - -#define TR2_ENVVAR_PARENT_SID "GIT_TRACE2_PARENT_SID" - -static struct strbuf tr2sid_buf = STRBUF_INIT; -static int tr2sid_nr_git_parents; - -/* - * Compute the final component of the SID representing the current process. - * This should uniquely identify the process and be a valid filename (to - * allow writing trace2 data to per-process files). It should also be fixed - * length for possible use as a database key. - * - * "<yyyymmdd>T<hhmmss>.<fraction>Z-<host>-<process>" - * - * where <host> is a 9 character string: - * "H<first_8_chars_of_sha1_of_hostname>" - * "Localhost" when no hostname. - * - * where <process> is a 9 character string containing the least significant - * 32 bits in the process-id. - * "P<pid>" - * (This is an abribrary choice. On most systems pid_t is a 32 bit value, - * so limit doesn't matter. On larger systems, a truncated value is fine - * for our purposes here.) - */ -static void tr2_sid_append_my_sid_component(void) -{ - const struct git_hash_algo *algo = &hash_algos[GIT_HASH_SHA1]; - struct tr2_tbuf tb_now; - git_hash_ctx ctx; - pid_t pid = getpid(); - unsigned char hash[GIT_MAX_RAWSZ + 1]; - char hex[GIT_MAX_HEXSZ + 1]; - char hostname[HOST_NAME_MAX + 1]; - - tr2_tbuf_utc_datetime(&tb_now); - strbuf_addstr(&tr2sid_buf, tb_now.buf); - - strbuf_addch(&tr2sid_buf, '-'); - if (xgethostname(hostname, sizeof(hostname))) - strbuf_add(&tr2sid_buf, "Localhost", 9); - else { - algo->init_fn(&ctx); - algo->update_fn(&ctx, hostname, strlen(hostname)); - algo->final_fn(hash, &ctx); - hash_to_hex_algop_r(hex, hash, algo); - strbuf_addch(&tr2sid_buf, 'H'); - strbuf_add(&tr2sid_buf, hex, 8); - } - - strbuf_addf(&tr2sid_buf, "-P%08"PRIx32, (uint32_t)pid); -} - -/* - * Compute a "unique" session id (SID) for the current process. This allows - * all events from this process to have a single label (much like a PID). - * - * Export this into our environment so that all child processes inherit it. - * - * If we were started by another git instance, use our parent's SID as a - * prefix. (This lets us track parent/child relationships even if there - * is an intermediate shell process.) - * - * Additionally, count the number of nested git processes. - */ -static void tr2_sid_compute(void) -{ - const char *parent_sid; - - if (tr2sid_buf.len) - return; - - parent_sid = getenv(TR2_ENVVAR_PARENT_SID); - if (parent_sid && *parent_sid) { - const char *p; - for (p = parent_sid; *p; p++) - if (*p == '/') - tr2sid_nr_git_parents++; - - strbuf_addstr(&tr2sid_buf, parent_sid); - strbuf_addch(&tr2sid_buf, '/'); - tr2sid_nr_git_parents++; - } - - tr2_sid_append_my_sid_component(); - - setenv(TR2_ENVVAR_PARENT_SID, tr2sid_buf.buf, 1); -} - -const char *tr2_sid_get(void) -{ - if (!tr2sid_buf.len) - tr2_sid_compute(); - - return tr2sid_buf.buf; -} - -int tr2_sid_depth(void) -{ - if (!tr2sid_buf.len) - tr2_sid_compute(); - - return tr2sid_nr_git_parents; -} - -void tr2_sid_release(void) -{ - strbuf_release(&tr2sid_buf); -} diff --git a/third_party/git/trace2/tr2_sid.h b/third_party/git/trace2/tr2_sid.h deleted file mode 100644 index 9bef3217081a..000000000000 --- a/third_party/git/trace2/tr2_sid.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef TR2_SID_H -#define TR2_SID_H - -/* - * Get our session id. Compute if necessary. - */ -const char *tr2_sid_get(void); - -/* - * Get our process depth. A top-level git process invoked from the - * command line will have depth=0. A child git process will have - * depth=1 and so on. - */ -int tr2_sid_depth(void); - -void tr2_sid_release(void); - -#endif /* TR2_SID_H */ diff --git a/third_party/git/trace2/tr2_sysenv.c b/third_party/git/trace2/tr2_sysenv.c deleted file mode 100644 index a380dcf9105e..000000000000 --- a/third_party/git/trace2/tr2_sysenv.c +++ /dev/null @@ -1,132 +0,0 @@ -#include "cache.h" -#include "config.h" -#include "dir.h" -#include "tr2_sysenv.h" - -/* - * Each entry represents a trace2 setting. - * See Documentation/technical/api-trace2.txt - */ -struct tr2_sysenv_entry { - const char *env_var_name; - const char *git_config_name; - - char *value; - unsigned int getenv_called : 1; -}; - -/* - * This table must match "enum tr2_sysenv_variable" in tr2_sysenv.h. - * - * The strings in this table are constant and must match the published - * config and environment variable names as described in the documentation. - * - * We do not define entries for the GIT_TRACE2_PARENT_* environment - * variables because they are transient and used to pass information - * from parent to child git processes, rather than settings. - */ -/* clang-format off */ -static struct tr2_sysenv_entry tr2_sysenv_settings[] = { - [TR2_SYSENV_CFG_PARAM] = { "GIT_TRACE2_CONFIG_PARAMS", - "trace2.configparams" }, - [TR2_SYSENV_ENV_VARS] = { "GIT_TRACE2_ENV_VARS", - "trace2.envvars" }, - - [TR2_SYSENV_DST_DEBUG] = { "GIT_TRACE2_DST_DEBUG", - "trace2.destinationdebug" }, - - [TR2_SYSENV_NORMAL] = { "GIT_TRACE2", - "trace2.normaltarget" }, - [TR2_SYSENV_NORMAL_BRIEF] = { "GIT_TRACE2_BRIEF", - "trace2.normalbrief" }, - - [TR2_SYSENV_EVENT] = { "GIT_TRACE2_EVENT", - "trace2.eventtarget" }, - [TR2_SYSENV_EVENT_BRIEF] = { "GIT_TRACE2_EVENT_BRIEF", - "trace2.eventbrief" }, - [TR2_SYSENV_EVENT_NESTING] = { "GIT_TRACE2_EVENT_NESTING", - "trace2.eventnesting" }, - - [TR2_SYSENV_PERF] = { "GIT_TRACE2_PERF", - "trace2.perftarget" }, - [TR2_SYSENV_PERF_BRIEF] = { "GIT_TRACE2_PERF_BRIEF", - "trace2.perfbrief" }, - - [TR2_SYSENV_MAX_FILES] = { "GIT_TRACE2_MAX_FILES", - "trace2.maxfiles" }, -}; -/* clang-format on */ - -static int tr2_sysenv_cb(const char *key, const char *value, void *d) -{ - int k; - - if (!starts_with(key, "trace2.")) - return 0; - - for (k = 0; k < ARRAY_SIZE(tr2_sysenv_settings); k++) { - if (!strcmp(key, tr2_sysenv_settings[k].git_config_name)) { - free(tr2_sysenv_settings[k].value); - tr2_sysenv_settings[k].value = xstrdup(value); - return 0; - } - } - - return 0; -} - -/* - * Load Trace2 settings from the system config (usually "/etc/gitconfig" - * unless we were built with a runtime-prefix). These are intended to - * define the default values for Trace2 as requested by the administrator. - * - * Then override with the Trace2 settings from the global config. - */ -void tr2_sysenv_load(void) -{ - if (ARRAY_SIZE(tr2_sysenv_settings) != TR2_SYSENV_MUST_BE_LAST) - BUG("tr2_sysenv_settings size is wrong"); - - read_very_early_config(tr2_sysenv_cb, NULL); -} - -/* - * Return the value for the requested Trace2 setting from these sources: - * the system config, the global config, and the environment. - */ -const char *tr2_sysenv_get(enum tr2_sysenv_variable var) -{ - if (var >= TR2_SYSENV_MUST_BE_LAST) - BUG("tr2_sysenv_get invalid var '%d'", var); - - if (!tr2_sysenv_settings[var].getenv_called) { - const char *v = getenv(tr2_sysenv_settings[var].env_var_name); - if (v && *v) { - free(tr2_sysenv_settings[var].value); - tr2_sysenv_settings[var].value = xstrdup(v); - } - tr2_sysenv_settings[var].getenv_called = 1; - } - - return tr2_sysenv_settings[var].value; -} - -/* - * Return a friendly name for this setting that is suitable for printing - * in an error messages. - */ -const char *tr2_sysenv_display_name(enum tr2_sysenv_variable var) -{ - if (var >= TR2_SYSENV_MUST_BE_LAST) - BUG("tr2_sysenv_get invalid var '%d'", var); - - return tr2_sysenv_settings[var].env_var_name; -} - -void tr2_sysenv_release(void) -{ - int k; - - for (k = 0; k < ARRAY_SIZE(tr2_sysenv_settings); k++) - free(tr2_sysenv_settings[k].value); -} diff --git a/third_party/git/trace2/tr2_sysenv.h b/third_party/git/trace2/tr2_sysenv.h deleted file mode 100644 index 3292ee15bc96..000000000000 --- a/third_party/git/trace2/tr2_sysenv.h +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef TR2_SYSENV_H -#define TR2_SYSENV_H - -/* - * The Trace2 settings that can be loaded from /etc/gitconfig - * and/or user environment variables. - * - * Note that this set does not contain any of the transient - * environment variables used to pass information from parent - * to child git processes, such "GIT_TRACE2_PARENT_SID". - */ -enum tr2_sysenv_variable { - TR2_SYSENV_CFG_PARAM = 0, - TR2_SYSENV_ENV_VARS, - - TR2_SYSENV_DST_DEBUG, - - TR2_SYSENV_NORMAL, - TR2_SYSENV_NORMAL_BRIEF, - - TR2_SYSENV_EVENT, - TR2_SYSENV_EVENT_BRIEF, - TR2_SYSENV_EVENT_NESTING, - - TR2_SYSENV_PERF, - TR2_SYSENV_PERF_BRIEF, - - TR2_SYSENV_MAX_FILES, - - TR2_SYSENV_MUST_BE_LAST -}; - -void tr2_sysenv_load(void); - -const char *tr2_sysenv_get(enum tr2_sysenv_variable); -const char *tr2_sysenv_display_name(enum tr2_sysenv_variable var); -void tr2_sysenv_release(void); - -#endif /* TR2_SYSENV_H */ diff --git a/third_party/git/trace2/tr2_tbuf.c b/third_party/git/trace2/tr2_tbuf.c deleted file mode 100644 index 2498482d9ad8..000000000000 --- a/third_party/git/trace2/tr2_tbuf.c +++ /dev/null @@ -1,47 +0,0 @@ -#include "cache.h" -#include "tr2_tbuf.h" - -void tr2_tbuf_local_time(struct tr2_tbuf *tb) -{ - struct timeval tv; - struct tm tm; - time_t secs; - - gettimeofday(&tv, NULL); - secs = tv.tv_sec; - localtime_r(&secs, &tm); - - xsnprintf(tb->buf, sizeof(tb->buf), "%02d:%02d:%02d.%06ld", tm.tm_hour, - tm.tm_min, tm.tm_sec, (long)tv.tv_usec); -} - -void tr2_tbuf_utc_datetime_extended(struct tr2_tbuf *tb) -{ - struct timeval tv; - struct tm tm; - time_t secs; - - gettimeofday(&tv, NULL); - secs = tv.tv_sec; - gmtime_r(&secs, &tm); - - xsnprintf(tb->buf, sizeof(tb->buf), - "%4d-%02d-%02dT%02d:%02d:%02d.%06ldZ", tm.tm_year + 1900, - tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, - (long)tv.tv_usec); -} - -void tr2_tbuf_utc_datetime(struct tr2_tbuf *tb) -{ - struct timeval tv; - struct tm tm; - time_t secs; - - gettimeofday(&tv, NULL); - secs = tv.tv_sec; - gmtime_r(&secs, &tm); - - xsnprintf(tb->buf, sizeof(tb->buf), "%4d%02d%02dT%02d%02d%02d.%06ldZ", - tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, - tm.tm_min, tm.tm_sec, (long)tv.tv_usec); -} diff --git a/third_party/git/trace2/tr2_tbuf.h b/third_party/git/trace2/tr2_tbuf.h deleted file mode 100644 index fa853d8f4211..000000000000 --- a/third_party/git/trace2/tr2_tbuf.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef TR2_TBUF_H -#define TR2_TBUF_H - -/* - * A simple wrapper around a fixed buffer to avoid C syntax - * quirks and the need to pass around an additional size_t - * argument. - */ -struct tr2_tbuf { - char buf[32]; -}; - -/* - * Fill buffer with formatted local time string. - */ -void tr2_tbuf_local_time(struct tr2_tbuf *tb); - -/* - * Fill buffer with formatted UTC datatime string. - */ -void tr2_tbuf_utc_datetime_extended(struct tr2_tbuf *tb); -void tr2_tbuf_utc_datetime(struct tr2_tbuf *tb); - -#endif /* TR2_TBUF_H */ diff --git a/third_party/git/trace2/tr2_tgt.h b/third_party/git/trace2/tr2_tgt.h deleted file mode 100644 index 7b904692123e..000000000000 --- a/third_party/git/trace2/tr2_tgt.h +++ /dev/null @@ -1,134 +0,0 @@ -#ifndef TR2_TGT_H -#define TR2_TGT_H - -struct child_process; -struct repository; -struct json_writer; - -/* - * Function prototypes for a TRACE2 "target" vtable. - */ - -typedef int(tr2_tgt_init_t)(void); -typedef void(tr2_tgt_term_t)(void); - -typedef void(tr2_tgt_evt_version_fl_t)(const char *file, int line); - -typedef void(tr2_tgt_evt_start_fl_t)(const char *file, int line, - uint64_t us_elapsed_absolute, - const char **argv); -typedef void(tr2_tgt_evt_exit_fl_t)(const char *file, int line, - uint64_t us_elapsed_absolute, int code); -typedef void(tr2_tgt_evt_signal_t)(uint64_t us_elapsed_absolute, int signo); -typedef void(tr2_tgt_evt_atexit_t)(uint64_t us_elapsed_absolute, int code); - -typedef void(tr2_tgt_evt_error_va_fl_t)(const char *file, int line, - const char *fmt, va_list ap); - -typedef void(tr2_tgt_evt_command_path_fl_t)(const char *file, int line, - const char *command_path); -typedef void(tr2_tgt_evt_command_name_fl_t)(const char *file, int line, - const char *name, - const char *hierarchy); -typedef void(tr2_tgt_evt_command_mode_fl_t)(const char *file, int line, - const char *mode); - -typedef void(tr2_tgt_evt_alias_fl_t)(const char *file, int line, - const char *alias, const char **argv); - -typedef void(tr2_tgt_evt_child_start_fl_t)(const char *file, int line, - uint64_t us_elapsed_absolute, - const struct child_process *cmd); -typedef void(tr2_tgt_evt_child_exit_fl_t)(const char *file, int line, - uint64_t us_elapsed_absolute, int cid, - int pid, int code, - uint64_t us_elapsed_child); - -typedef void(tr2_tgt_evt_thread_start_fl_t)(const char *file, int line, - uint64_t us_elapsed_absolute); -typedef void(tr2_tgt_evt_thread_exit_fl_t)(const char *file, int line, - uint64_t us_elapsed_absolute, - uint64_t us_elapsed_thread); - -typedef void(tr2_tgt_evt_exec_fl_t)(const char *file, int line, - uint64_t us_elapsed_absolute, int exec_id, - const char *exe, const char **argv); -typedef void(tr2_tgt_evt_exec_result_fl_t)(const char *file, int line, - uint64_t us_elapsed_absolute, - int exec_id, int code); - -typedef void(tr2_tgt_evt_param_fl_t)(const char *file, int line, - const char *param, const char *value); - -typedef void(tr2_tgt_evt_repo_fl_t)(const char *file, int line, - const struct repository *repo); - -typedef void(tr2_tgt_evt_region_enter_printf_va_fl_t)( - const char *file, int line, uint64_t us_elapsed_absolute, - const char *category, const char *label, const struct repository *repo, - const char *fmt, va_list ap); -typedef void(tr2_tgt_evt_region_leave_printf_va_fl_t)( - const char *file, int line, uint64_t us_elapsed_absolute, - uint64_t us_elapsed_region, const char *category, const char *label, - const struct repository *repo, const char *fmt, va_list ap); - -typedef void(tr2_tgt_evt_data_fl_t)(const char *file, int line, - uint64_t us_elapsed_absolute, - uint64_t us_elapsed_region, - const char *category, - const struct repository *repo, - const char *key, const char *value); -typedef void(tr2_tgt_evt_data_json_fl_t)(const char *file, int line, - uint64_t us_elapsed_absolute, - uint64_t us_elapsed_region, - const char *category, - const struct repository *repo, - const char *key, - const struct json_writer *value); - -typedef void(tr2_tgt_evt_printf_va_fl_t)(const char *file, int line, - uint64_t us_elapsed_absolute, - const char *fmt, va_list ap); - -/* - * "vtable" for a TRACE2 target. Use NULL if a target does not want - * to emit that message. - */ -/* clang-format off */ -struct tr2_tgt { - struct tr2_dst *pdst; - - tr2_tgt_init_t *pfn_init; - tr2_tgt_term_t *pfn_term; - - tr2_tgt_evt_version_fl_t *pfn_version_fl; - tr2_tgt_evt_start_fl_t *pfn_start_fl; - tr2_tgt_evt_exit_fl_t *pfn_exit_fl; - tr2_tgt_evt_signal_t *pfn_signal; - tr2_tgt_evt_atexit_t *pfn_atexit; - tr2_tgt_evt_error_va_fl_t *pfn_error_va_fl; - tr2_tgt_evt_command_path_fl_t *pfn_command_path_fl; - tr2_tgt_evt_command_name_fl_t *pfn_command_name_fl; - tr2_tgt_evt_command_mode_fl_t *pfn_command_mode_fl; - tr2_tgt_evt_alias_fl_t *pfn_alias_fl; - tr2_tgt_evt_child_start_fl_t *pfn_child_start_fl; - tr2_tgt_evt_child_exit_fl_t *pfn_child_exit_fl; - tr2_tgt_evt_thread_start_fl_t *pfn_thread_start_fl; - tr2_tgt_evt_thread_exit_fl_t *pfn_thread_exit_fl; - tr2_tgt_evt_exec_fl_t *pfn_exec_fl; - tr2_tgt_evt_exec_result_fl_t *pfn_exec_result_fl; - tr2_tgt_evt_param_fl_t *pfn_param_fl; - tr2_tgt_evt_repo_fl_t *pfn_repo_fl; - tr2_tgt_evt_region_enter_printf_va_fl_t *pfn_region_enter_printf_va_fl; - tr2_tgt_evt_region_leave_printf_va_fl_t *pfn_region_leave_printf_va_fl; - tr2_tgt_evt_data_fl_t *pfn_data_fl; - tr2_tgt_evt_data_json_fl_t *pfn_data_json_fl; - tr2_tgt_evt_printf_va_fl_t *pfn_printf_va_fl; -}; -/* clang-format on */ - -extern struct tr2_tgt tr2_tgt_event; -extern struct tr2_tgt tr2_tgt_normal; -extern struct tr2_tgt tr2_tgt_perf; - -#endif /* TR2_TGT_H */ diff --git a/third_party/git/trace2/tr2_tgt_event.c b/third_party/git/trace2/tr2_tgt_event.c deleted file mode 100644 index 6353e8ad9156..000000000000 --- a/third_party/git/trace2/tr2_tgt_event.c +++ /dev/null @@ -1,603 +0,0 @@ -#include "cache.h" -#include "config.h" -#include "json-writer.h" -#include "run-command.h" -#include "version.h" -#include "trace2/tr2_dst.h" -#include "trace2/tr2_tbuf.h" -#include "trace2/tr2_sid.h" -#include "trace2/tr2_sysenv.h" -#include "trace2/tr2_tgt.h" -#include "trace2/tr2_tls.h" - -static struct tr2_dst tr2dst_event = { TR2_SYSENV_EVENT, 0, 0, 0, 0 }; - -/* - * The version number of the JSON data generated by the EVENT target in this - * source file. The version should be incremented if new event types are added, - * if existing fields are removed, or if there are significant changes in - * interpretation of existing events or fields. Smaller changes, such as adding - * a new field to an existing event, do not require an increment to the EVENT - * format version. - */ -#define TR2_EVENT_VERSION "2" - -/* - * Region nesting limit for messages written to the event target. - * - * The "region_enter" and "region_leave" messages (especially recursive - * messages such as those produced while diving the worktree or index) - * are primarily intended for the performance target during debugging. - * - * Some of the outer-most messages, however, may be of interest to the - * event target. Use the TR2_SYSENV_EVENT_NESTING setting to increase - * region details in the event target. - */ -static int tr2env_event_max_nesting_levels = 2; - -/* - * Use the TR2_SYSENV_EVENT_BRIEF to omit the <time>, <file>, and - * <line> fields from most events. - */ -static int tr2env_event_be_brief; - -static int fn_init(void) -{ - int want = tr2_dst_trace_want(&tr2dst_event); - int max_nesting; - int want_brief; - const char *nesting; - const char *brief; - - if (!want) - return want; - - nesting = tr2_sysenv_get(TR2_SYSENV_EVENT_NESTING); - if (nesting && *nesting && ((max_nesting = atoi(nesting)) > 0)) - tr2env_event_max_nesting_levels = max_nesting; - - brief = tr2_sysenv_get(TR2_SYSENV_EVENT_BRIEF); - if (brief && *brief && - ((want_brief = git_parse_maybe_bool(brief)) != -1)) - tr2env_event_be_brief = want_brief; - - return want; -} - -static void fn_term(void) -{ - tr2_dst_trace_disable(&tr2dst_event); -} - -/* - * Append common key-value pairs to the currently open JSON object. - * "event:"<event_name>" - * "sid":"<sid>" - * "thread":"<thread_name>" - * "time":"<time>" - * "file":"<filename>" - * "line":<line_number> - * "repo":<repo_id> - */ -static void event_fmt_prepare(const char *event_name, const char *file, - int line, const struct repository *repo, - struct json_writer *jw) -{ - struct tr2tls_thread_ctx *ctx = tr2tls_get_self(); - struct tr2_tbuf tb_now; - - jw_object_string(jw, "event", event_name); - jw_object_string(jw, "sid", tr2_sid_get()); - jw_object_string(jw, "thread", ctx->thread_name.buf); - - /* - * In brief mode, only emit <time> on these 2 event types. - */ - if (!tr2env_event_be_brief || !strcmp(event_name, "version") || - !strcmp(event_name, "atexit")) { - tr2_tbuf_utc_datetime_extended(&tb_now); - jw_object_string(jw, "time", tb_now.buf); - } - - if (!tr2env_event_be_brief && file && *file) { - jw_object_string(jw, "file", file); - jw_object_intmax(jw, "line", line); - } - - if (repo) - jw_object_intmax(jw, "repo", repo->trace2_repo_id); -} - -static void fn_too_many_files_fl(const char *file, int line) -{ - const char *event_name = "too_many_files"; - struct json_writer jw = JSON_WRITER_INIT; - - jw_object_begin(&jw, 0); - event_fmt_prepare(event_name, file, line, NULL, &jw); - jw_end(&jw); - - tr2_dst_write_line(&tr2dst_event, &jw.json); - jw_release(&jw); -} - -static void fn_version_fl(const char *file, int line) -{ - const char *event_name = "version"; - struct json_writer jw = JSON_WRITER_INIT; - - jw_object_begin(&jw, 0); - event_fmt_prepare(event_name, file, line, NULL, &jw); - jw_object_string(&jw, "evt", TR2_EVENT_VERSION); - jw_object_string(&jw, "exe", git_version_string); - jw_end(&jw); - - tr2_dst_write_line(&tr2dst_event, &jw.json); - jw_release(&jw); - - if (tr2dst_event.too_many_files) - fn_too_many_files_fl(file, line); -} - -static void fn_start_fl(const char *file, int line, - uint64_t us_elapsed_absolute, const char **argv) -{ - const char *event_name = "start"; - struct json_writer jw = JSON_WRITER_INIT; - double t_abs = (double)us_elapsed_absolute / 1000000.0; - - jw_object_begin(&jw, 0); - event_fmt_prepare(event_name, file, line, NULL, &jw); - jw_object_double(&jw, "t_abs", 6, t_abs); - jw_object_inline_begin_array(&jw, "argv"); - jw_array_argv(&jw, argv); - jw_end(&jw); - jw_end(&jw); - - tr2_dst_write_line(&tr2dst_event, &jw.json); - jw_release(&jw); -} - -static void fn_exit_fl(const char *file, int line, uint64_t us_elapsed_absolute, - int code) -{ - const char *event_name = "exit"; - struct json_writer jw = JSON_WRITER_INIT; - double t_abs = (double)us_elapsed_absolute / 1000000.0; - - jw_object_begin(&jw, 0); - event_fmt_prepare(event_name, file, line, NULL, &jw); - jw_object_double(&jw, "t_abs", 6, t_abs); - jw_object_intmax(&jw, "code", code); - jw_end(&jw); - - tr2_dst_write_line(&tr2dst_event, &jw.json); - jw_release(&jw); -} - -static void fn_signal(uint64_t us_elapsed_absolute, int signo) -{ - const char *event_name = "signal"; - struct json_writer jw = JSON_WRITER_INIT; - double t_abs = (double)us_elapsed_absolute / 1000000.0; - - jw_object_begin(&jw, 0); - event_fmt_prepare(event_name, __FILE__, __LINE__, NULL, &jw); - jw_object_double(&jw, "t_abs", 6, t_abs); - jw_object_intmax(&jw, "signo", signo); - jw_end(&jw); - - tr2_dst_write_line(&tr2dst_event, &jw.json); - jw_release(&jw); -} - -static void fn_atexit(uint64_t us_elapsed_absolute, int code) -{ - const char *event_name = "atexit"; - struct json_writer jw = JSON_WRITER_INIT; - double t_abs = (double)us_elapsed_absolute / 1000000.0; - - jw_object_begin(&jw, 0); - event_fmt_prepare(event_name, __FILE__, __LINE__, NULL, &jw); - jw_object_double(&jw, "t_abs", 6, t_abs); - jw_object_intmax(&jw, "code", code); - jw_end(&jw); - - tr2_dst_write_line(&tr2dst_event, &jw.json); - jw_release(&jw); -} - -static void maybe_add_string_va(struct json_writer *jw, const char *field_name, - const char *fmt, va_list ap) -{ - if (fmt && *fmt) { - va_list copy_ap; - struct strbuf buf = STRBUF_INIT; - - va_copy(copy_ap, ap); - strbuf_vaddf(&buf, fmt, copy_ap); - va_end(copy_ap); - - jw_object_string(jw, field_name, buf.buf); - strbuf_release(&buf); - return; - } -} - -static void fn_error_va_fl(const char *file, int line, const char *fmt, - va_list ap) -{ - const char *event_name = "error"; - struct json_writer jw = JSON_WRITER_INIT; - - jw_object_begin(&jw, 0); - event_fmt_prepare(event_name, file, line, NULL, &jw); - maybe_add_string_va(&jw, "msg", fmt, ap); - /* - * Also emit the format string as a field in case - * post-processors want to aggregate common error - * messages by type without argument fields (such - * as pathnames or branch names) cluttering it up. - */ - if (fmt && *fmt) - jw_object_string(&jw, "fmt", fmt); - jw_end(&jw); - - tr2_dst_write_line(&tr2dst_event, &jw.json); - jw_release(&jw); -} - -static void fn_command_path_fl(const char *file, int line, const char *pathname) -{ - const char *event_name = "cmd_path"; - struct json_writer jw = JSON_WRITER_INIT; - - jw_object_begin(&jw, 0); - event_fmt_prepare(event_name, file, line, NULL, &jw); - jw_object_string(&jw, "path", pathname); - jw_end(&jw); - - tr2_dst_write_line(&tr2dst_event, &jw.json); - jw_release(&jw); -} - -static void fn_command_name_fl(const char *file, int line, const char *name, - const char *hierarchy) -{ - const char *event_name = "cmd_name"; - struct json_writer jw = JSON_WRITER_INIT; - - jw_object_begin(&jw, 0); - event_fmt_prepare(event_name, file, line, NULL, &jw); - jw_object_string(&jw, "name", name); - if (hierarchy && *hierarchy) - jw_object_string(&jw, "hierarchy", hierarchy); - jw_end(&jw); - - tr2_dst_write_line(&tr2dst_event, &jw.json); - jw_release(&jw); -} - -static void fn_command_mode_fl(const char *file, int line, const char *mode) -{ - const char *event_name = "cmd_mode"; - struct json_writer jw = JSON_WRITER_INIT; - - jw_object_begin(&jw, 0); - event_fmt_prepare(event_name, file, line, NULL, &jw); - jw_object_string(&jw, "name", mode); - jw_end(&jw); - - tr2_dst_write_line(&tr2dst_event, &jw.json); - jw_release(&jw); -} - -static void fn_alias_fl(const char *file, int line, const char *alias, - const char **argv) -{ - const char *event_name = "alias"; - struct json_writer jw = JSON_WRITER_INIT; - - jw_object_begin(&jw, 0); - event_fmt_prepare(event_name, file, line, NULL, &jw); - jw_object_string(&jw, "alias", alias); - jw_object_inline_begin_array(&jw, "argv"); - jw_array_argv(&jw, argv); - jw_end(&jw); - jw_end(&jw); - - tr2_dst_write_line(&tr2dst_event, &jw.json); - jw_release(&jw); -} - -static void fn_child_start_fl(const char *file, int line, - uint64_t us_elapsed_absolute, - const struct child_process *cmd) -{ - const char *event_name = "child_start"; - struct json_writer jw = JSON_WRITER_INIT; - - jw_object_begin(&jw, 0); - event_fmt_prepare(event_name, file, line, NULL, &jw); - jw_object_intmax(&jw, "child_id", cmd->trace2_child_id); - if (cmd->trace2_hook_name) { - jw_object_string(&jw, "child_class", "hook"); - jw_object_string(&jw, "hook_name", cmd->trace2_hook_name); - } else { - const char *child_class = - cmd->trace2_child_class ? cmd->trace2_child_class : "?"; - jw_object_string(&jw, "child_class", child_class); - } - if (cmd->dir) - jw_object_string(&jw, "cd", cmd->dir); - jw_object_bool(&jw, "use_shell", cmd->use_shell); - jw_object_inline_begin_array(&jw, "argv"); - if (cmd->git_cmd) - jw_array_string(&jw, "git"); - jw_array_argv(&jw, cmd->argv); - jw_end(&jw); - jw_end(&jw); - - tr2_dst_write_line(&tr2dst_event, &jw.json); - jw_release(&jw); -} - -static void fn_child_exit_fl(const char *file, int line, - uint64_t us_elapsed_absolute, int cid, int pid, - int code, uint64_t us_elapsed_child) -{ - const char *event_name = "child_exit"; - struct json_writer jw = JSON_WRITER_INIT; - double t_rel = (double)us_elapsed_child / 1000000.0; - - jw_object_begin(&jw, 0); - event_fmt_prepare(event_name, file, line, NULL, &jw); - jw_object_intmax(&jw, "child_id", cid); - jw_object_intmax(&jw, "pid", pid); - jw_object_intmax(&jw, "code", code); - jw_object_double(&jw, "t_rel", 6, t_rel); - jw_end(&jw); - - tr2_dst_write_line(&tr2dst_event, &jw.json); - - jw_release(&jw); -} - -static void fn_thread_start_fl(const char *file, int line, - uint64_t us_elapsed_absolute) -{ - const char *event_name = "thread_start"; - struct json_writer jw = JSON_WRITER_INIT; - - jw_object_begin(&jw, 0); - event_fmt_prepare(event_name, file, line, NULL, &jw); - jw_end(&jw); - - tr2_dst_write_line(&tr2dst_event, &jw.json); - jw_release(&jw); -} - -static void fn_thread_exit_fl(const char *file, int line, - uint64_t us_elapsed_absolute, - uint64_t us_elapsed_thread) -{ - const char *event_name = "thread_exit"; - struct json_writer jw = JSON_WRITER_INIT; - double t_rel = (double)us_elapsed_thread / 1000000.0; - - jw_object_begin(&jw, 0); - event_fmt_prepare(event_name, file, line, NULL, &jw); - jw_object_double(&jw, "t_rel", 6, t_rel); - jw_end(&jw); - - tr2_dst_write_line(&tr2dst_event, &jw.json); - jw_release(&jw); -} - -static void fn_exec_fl(const char *file, int line, uint64_t us_elapsed_absolute, - int exec_id, const char *exe, const char **argv) -{ - const char *event_name = "exec"; - struct json_writer jw = JSON_WRITER_INIT; - - jw_object_begin(&jw, 0); - event_fmt_prepare(event_name, file, line, NULL, &jw); - jw_object_intmax(&jw, "exec_id", exec_id); - if (exe) - jw_object_string(&jw, "exe", exe); - jw_object_inline_begin_array(&jw, "argv"); - jw_array_argv(&jw, argv); - jw_end(&jw); - jw_end(&jw); - - tr2_dst_write_line(&tr2dst_event, &jw.json); - jw_release(&jw); -} - -static void fn_exec_result_fl(const char *file, int line, - uint64_t us_elapsed_absolute, int exec_id, - int code) -{ - const char *event_name = "exec_result"; - struct json_writer jw = JSON_WRITER_INIT; - - jw_object_begin(&jw, 0); - event_fmt_prepare(event_name, file, line, NULL, &jw); - jw_object_intmax(&jw, "exec_id", exec_id); - jw_object_intmax(&jw, "code", code); - jw_end(&jw); - - tr2_dst_write_line(&tr2dst_event, &jw.json); - jw_release(&jw); -} - -static void fn_param_fl(const char *file, int line, const char *param, - const char *value) -{ - const char *event_name = "def_param"; - struct json_writer jw = JSON_WRITER_INIT; - - jw_object_begin(&jw, 0); - event_fmt_prepare(event_name, file, line, NULL, &jw); - jw_object_string(&jw, "param", param); - jw_object_string(&jw, "value", value); - jw_end(&jw); - - tr2_dst_write_line(&tr2dst_event, &jw.json); - jw_release(&jw); -} - -static void fn_repo_fl(const char *file, int line, - const struct repository *repo) -{ - const char *event_name = "def_repo"; - struct json_writer jw = JSON_WRITER_INIT; - - jw_object_begin(&jw, 0); - event_fmt_prepare(event_name, file, line, repo, &jw); - jw_object_string(&jw, "worktree", repo->worktree); - jw_end(&jw); - - tr2_dst_write_line(&tr2dst_event, &jw.json); - jw_release(&jw); -} - -static void fn_region_enter_printf_va_fl(const char *file, int line, - uint64_t us_elapsed_absolute, - const char *category, - const char *label, - const struct repository *repo, - const char *fmt, va_list ap) -{ - const char *event_name = "region_enter"; - struct tr2tls_thread_ctx *ctx = tr2tls_get_self(); - if (ctx->nr_open_regions <= tr2env_event_max_nesting_levels) { - struct json_writer jw = JSON_WRITER_INIT; - - jw_object_begin(&jw, 0); - event_fmt_prepare(event_name, file, line, repo, &jw); - jw_object_intmax(&jw, "nesting", ctx->nr_open_regions); - if (category) - jw_object_string(&jw, "category", category); - if (label) - jw_object_string(&jw, "label", label); - maybe_add_string_va(&jw, "msg", fmt, ap); - jw_end(&jw); - - tr2_dst_write_line(&tr2dst_event, &jw.json); - jw_release(&jw); - } -} - -static void fn_region_leave_printf_va_fl( - const char *file, int line, uint64_t us_elapsed_absolute, - uint64_t us_elapsed_region, const char *category, const char *label, - const struct repository *repo, const char *fmt, va_list ap) -{ - const char *event_name = "region_leave"; - struct tr2tls_thread_ctx *ctx = tr2tls_get_self(); - if (ctx->nr_open_regions <= tr2env_event_max_nesting_levels) { - struct json_writer jw = JSON_WRITER_INIT; - double t_rel = (double)us_elapsed_region / 1000000.0; - - jw_object_begin(&jw, 0); - event_fmt_prepare(event_name, file, line, repo, &jw); - jw_object_double(&jw, "t_rel", 6, t_rel); - jw_object_intmax(&jw, "nesting", ctx->nr_open_regions); - if (category) - jw_object_string(&jw, "category", category); - if (label) - jw_object_string(&jw, "label", label); - maybe_add_string_va(&jw, "msg", fmt, ap); - jw_end(&jw); - - tr2_dst_write_line(&tr2dst_event, &jw.json); - jw_release(&jw); - } -} - -static void fn_data_fl(const char *file, int line, uint64_t us_elapsed_absolute, - uint64_t us_elapsed_region, const char *category, - const struct repository *repo, const char *key, - const char *value) -{ - const char *event_name = "data"; - struct tr2tls_thread_ctx *ctx = tr2tls_get_self(); - if (ctx->nr_open_regions <= tr2env_event_max_nesting_levels) { - struct json_writer jw = JSON_WRITER_INIT; - double t_abs = (double)us_elapsed_absolute / 1000000.0; - double t_rel = (double)us_elapsed_region / 1000000.0; - - jw_object_begin(&jw, 0); - event_fmt_prepare(event_name, file, line, repo, &jw); - jw_object_double(&jw, "t_abs", 6, t_abs); - jw_object_double(&jw, "t_rel", 6, t_rel); - jw_object_intmax(&jw, "nesting", ctx->nr_open_regions); - jw_object_string(&jw, "category", category); - jw_object_string(&jw, "key", key); - jw_object_string(&jw, "value", value); - jw_end(&jw); - - tr2_dst_write_line(&tr2dst_event, &jw.json); - jw_release(&jw); - } -} - -static void fn_data_json_fl(const char *file, int line, - uint64_t us_elapsed_absolute, - uint64_t us_elapsed_region, const char *category, - const struct repository *repo, const char *key, - const struct json_writer *value) -{ - const char *event_name = "data_json"; - struct tr2tls_thread_ctx *ctx = tr2tls_get_self(); - if (ctx->nr_open_regions <= tr2env_event_max_nesting_levels) { - struct json_writer jw = JSON_WRITER_INIT; - double t_abs = (double)us_elapsed_absolute / 1000000.0; - double t_rel = (double)us_elapsed_region / 1000000.0; - - jw_object_begin(&jw, 0); - event_fmt_prepare(event_name, file, line, repo, &jw); - jw_object_double(&jw, "t_abs", 6, t_abs); - jw_object_double(&jw, "t_rel", 6, t_rel); - jw_object_intmax(&jw, "nesting", ctx->nr_open_regions); - jw_object_string(&jw, "category", category); - jw_object_string(&jw, "key", key); - jw_object_sub_jw(&jw, "value", value); - jw_end(&jw); - - tr2_dst_write_line(&tr2dst_event, &jw.json); - jw_release(&jw); - } -} - -struct tr2_tgt tr2_tgt_event = { - &tr2dst_event, - - fn_init, - fn_term, - - fn_version_fl, - fn_start_fl, - fn_exit_fl, - fn_signal, - fn_atexit, - fn_error_va_fl, - fn_command_path_fl, - fn_command_name_fl, - fn_command_mode_fl, - fn_alias_fl, - fn_child_start_fl, - fn_child_exit_fl, - fn_thread_start_fl, - fn_thread_exit_fl, - fn_exec_fl, - fn_exec_result_fl, - fn_param_fl, - fn_repo_fl, - fn_region_enter_printf_va_fl, - fn_region_leave_printf_va_fl, - fn_data_fl, - fn_data_json_fl, - NULL, /* printf */ -}; diff --git a/third_party/git/trace2/tr2_tgt_normal.c b/third_party/git/trace2/tr2_tgt_normal.c deleted file mode 100644 index 31b602c171fc..000000000000 --- a/third_party/git/trace2/tr2_tgt_normal.c +++ /dev/null @@ -1,325 +0,0 @@ -#include "cache.h" -#include "config.h" -#include "run-command.h" -#include "quote.h" -#include "version.h" -#include "trace2/tr2_dst.h" -#include "trace2/tr2_sysenv.h" -#include "trace2/tr2_tbuf.h" -#include "trace2/tr2_tgt.h" -#include "trace2/tr2_tls.h" - -static struct tr2_dst tr2dst_normal = { TR2_SYSENV_NORMAL, 0, 0, 0, 0 }; - -/* - * Use the TR2_SYSENV_NORMAL_BRIEF setting to omit the "<time> <file>:<line>" - * fields from each line written to the builtin normal target. - * - * Unit tests may want to use this to help with testing. - */ -static int tr2env_normal_be_brief; - -#define TR2FMT_NORMAL_FL_WIDTH (50) - -static int fn_init(void) -{ - int want = tr2_dst_trace_want(&tr2dst_normal); - int want_brief; - const char *brief; - - if (!want) - return want; - - brief = tr2_sysenv_get(TR2_SYSENV_NORMAL_BRIEF); - if (brief && *brief && - ((want_brief = git_parse_maybe_bool(brief)) != -1)) - tr2env_normal_be_brief = want_brief; - - return want; -} - -static void fn_term(void) -{ - tr2_dst_trace_disable(&tr2dst_normal); -} - -static void normal_fmt_prepare(const char *file, int line, struct strbuf *buf) -{ - strbuf_setlen(buf, 0); - - if (!tr2env_normal_be_brief) { - struct tr2_tbuf tb_now; - - tr2_tbuf_local_time(&tb_now); - strbuf_addstr(buf, tb_now.buf); - strbuf_addch(buf, ' '); - - if (file && *file) - strbuf_addf(buf, "%s:%d ", file, line); - while (buf->len < TR2FMT_NORMAL_FL_WIDTH) - strbuf_addch(buf, ' '); - } -} - -static void normal_io_write_fl(const char *file, int line, - const struct strbuf *buf_payload) -{ - struct strbuf buf_line = STRBUF_INIT; - - normal_fmt_prepare(file, line, &buf_line); - strbuf_addbuf(&buf_line, buf_payload); - tr2_dst_write_line(&tr2dst_normal, &buf_line); - strbuf_release(&buf_line); -} - -static void fn_version_fl(const char *file, int line) -{ - struct strbuf buf_payload = STRBUF_INIT; - - strbuf_addf(&buf_payload, "version %s", git_version_string); - normal_io_write_fl(file, line, &buf_payload); - strbuf_release(&buf_payload); -} - -static void fn_start_fl(const char *file, int line, - uint64_t us_elapsed_absolute, const char **argv) -{ - struct strbuf buf_payload = STRBUF_INIT; - - strbuf_addstr(&buf_payload, "start "); - sq_append_quote_argv_pretty(&buf_payload, argv); - normal_io_write_fl(file, line, &buf_payload); - strbuf_release(&buf_payload); -} - -static void fn_exit_fl(const char *file, int line, uint64_t us_elapsed_absolute, - int code) -{ - struct strbuf buf_payload = STRBUF_INIT; - double elapsed = (double)us_elapsed_absolute / 1000000.0; - - strbuf_addf(&buf_payload, "exit elapsed:%.6f code:%d", elapsed, code); - normal_io_write_fl(file, line, &buf_payload); - strbuf_release(&buf_payload); -} - -static void fn_signal(uint64_t us_elapsed_absolute, int signo) -{ - struct strbuf buf_payload = STRBUF_INIT; - double elapsed = (double)us_elapsed_absolute / 1000000.0; - - strbuf_addf(&buf_payload, "signal elapsed:%.6f code:%d", elapsed, - signo); - normal_io_write_fl(__FILE__, __LINE__, &buf_payload); - strbuf_release(&buf_payload); -} - -static void fn_atexit(uint64_t us_elapsed_absolute, int code) -{ - struct strbuf buf_payload = STRBUF_INIT; - double elapsed = (double)us_elapsed_absolute / 1000000.0; - - strbuf_addf(&buf_payload, "atexit elapsed:%.6f code:%d", elapsed, code); - normal_io_write_fl(__FILE__, __LINE__, &buf_payload); - strbuf_release(&buf_payload); -} - -static void maybe_append_string_va(struct strbuf *buf, const char *fmt, - va_list ap) -{ - if (fmt && *fmt) { - va_list copy_ap; - - va_copy(copy_ap, ap); - strbuf_vaddf(buf, fmt, copy_ap); - va_end(copy_ap); - return; - } -} - -static void fn_error_va_fl(const char *file, int line, const char *fmt, - va_list ap) -{ - struct strbuf buf_payload = STRBUF_INIT; - - strbuf_addstr(&buf_payload, "error"); - if (fmt && *fmt) { - strbuf_addch(&buf_payload, ' '); - maybe_append_string_va(&buf_payload, fmt, ap); - } - normal_io_write_fl(file, line, &buf_payload); - strbuf_release(&buf_payload); -} - -static void fn_command_path_fl(const char *file, int line, const char *pathname) -{ - struct strbuf buf_payload = STRBUF_INIT; - - strbuf_addf(&buf_payload, "cmd_path %s", pathname); - normal_io_write_fl(file, line, &buf_payload); - strbuf_release(&buf_payload); -} - -static void fn_command_name_fl(const char *file, int line, const char *name, - const char *hierarchy) -{ - struct strbuf buf_payload = STRBUF_INIT; - - strbuf_addf(&buf_payload, "cmd_name %s", name); - if (hierarchy && *hierarchy) - strbuf_addf(&buf_payload, " (%s)", hierarchy); - normal_io_write_fl(file, line, &buf_payload); - strbuf_release(&buf_payload); -} - -static void fn_command_mode_fl(const char *file, int line, const char *mode) -{ - struct strbuf buf_payload = STRBUF_INIT; - - strbuf_addf(&buf_payload, "cmd_mode %s", mode); - normal_io_write_fl(file, line, &buf_payload); - strbuf_release(&buf_payload); -} - -static void fn_alias_fl(const char *file, int line, const char *alias, - const char **argv) -{ - struct strbuf buf_payload = STRBUF_INIT; - - strbuf_addf(&buf_payload, "alias %s -> ", alias); - sq_append_quote_argv_pretty(&buf_payload, argv); - normal_io_write_fl(file, line, &buf_payload); - strbuf_release(&buf_payload); -} - -static void fn_child_start_fl(const char *file, int line, - uint64_t us_elapsed_absolute, - const struct child_process *cmd) -{ - struct strbuf buf_payload = STRBUF_INIT; - - strbuf_addf(&buf_payload, "child_start[%d]", cmd->trace2_child_id); - - if (cmd->dir) { - strbuf_addstr(&buf_payload, " cd "); - sq_quote_buf_pretty(&buf_payload, cmd->dir); - strbuf_addstr(&buf_payload, ";"); - } - - /* - * TODO if (cmd->env) { Consider dumping changes to environment. } - * See trace_add_env() in run-command.c as used by original trace.c - */ - - strbuf_addch(&buf_payload, ' '); - if (cmd->git_cmd) - strbuf_addstr(&buf_payload, "git "); - sq_append_quote_argv_pretty(&buf_payload, cmd->argv); - - normal_io_write_fl(file, line, &buf_payload); - strbuf_release(&buf_payload); -} - -static void fn_child_exit_fl(const char *file, int line, - uint64_t us_elapsed_absolute, int cid, int pid, - int code, uint64_t us_elapsed_child) -{ - struct strbuf buf_payload = STRBUF_INIT; - double elapsed = (double)us_elapsed_child / 1000000.0; - - strbuf_addf(&buf_payload, "child_exit[%d] pid:%d code:%d elapsed:%.6f", - cid, pid, code, elapsed); - normal_io_write_fl(file, line, &buf_payload); - strbuf_release(&buf_payload); -} - -static void fn_exec_fl(const char *file, int line, uint64_t us_elapsed_absolute, - int exec_id, const char *exe, const char **argv) -{ - struct strbuf buf_payload = STRBUF_INIT; - - strbuf_addf(&buf_payload, "exec[%d] ", exec_id); - if (exe) { - strbuf_addstr(&buf_payload, exe); - strbuf_addch(&buf_payload, ' '); - } - sq_append_quote_argv_pretty(&buf_payload, argv); - normal_io_write_fl(file, line, &buf_payload); - strbuf_release(&buf_payload); -} - -static void fn_exec_result_fl(const char *file, int line, - uint64_t us_elapsed_absolute, int exec_id, - int code) -{ - struct strbuf buf_payload = STRBUF_INIT; - - strbuf_addf(&buf_payload, "exec_result[%d] code:%d", exec_id, code); - if (code > 0) - strbuf_addf(&buf_payload, " err:%s", strerror(code)); - normal_io_write_fl(file, line, &buf_payload); - strbuf_release(&buf_payload); -} - -static void fn_param_fl(const char *file, int line, const char *param, - const char *value) -{ - struct strbuf buf_payload = STRBUF_INIT; - - strbuf_addf(&buf_payload, "def_param %s=%s", param, value); - normal_io_write_fl(file, line, &buf_payload); - strbuf_release(&buf_payload); -} - -static void fn_repo_fl(const char *file, int line, - const struct repository *repo) -{ - struct strbuf buf_payload = STRBUF_INIT; - - strbuf_addstr(&buf_payload, "worktree "); - sq_quote_buf_pretty(&buf_payload, repo->worktree); - normal_io_write_fl(file, line, &buf_payload); - strbuf_release(&buf_payload); -} - -static void fn_printf_va_fl(const char *file, int line, - uint64_t us_elapsed_absolute, const char *fmt, - va_list ap) -{ - struct strbuf buf_payload = STRBUF_INIT; - - maybe_append_string_va(&buf_payload, fmt, ap); - normal_io_write_fl(file, line, &buf_payload); - strbuf_release(&buf_payload); -} - -struct tr2_tgt tr2_tgt_normal = { - &tr2dst_normal, - - fn_init, - fn_term, - - fn_version_fl, - fn_start_fl, - fn_exit_fl, - fn_signal, - fn_atexit, - fn_error_va_fl, - fn_command_path_fl, - fn_command_name_fl, - fn_command_mode_fl, - fn_alias_fl, - fn_child_start_fl, - fn_child_exit_fl, - NULL, /* thread_start */ - NULL, /* thread_exit */ - fn_exec_fl, - fn_exec_result_fl, - fn_param_fl, - fn_repo_fl, - NULL, /* region_enter */ - NULL, /* region_leave */ - NULL, /* data */ - NULL, /* data_json */ - fn_printf_va_fl, -}; diff --git a/third_party/git/trace2/tr2_tgt_perf.c b/third_party/git/trace2/tr2_tgt_perf.c deleted file mode 100644 index a8018f18cc87..000000000000 --- a/third_party/git/trace2/tr2_tgt_perf.c +++ /dev/null @@ -1,551 +0,0 @@ -#include "cache.h" -#include "config.h" -#include "run-command.h" -#include "quote.h" -#include "version.h" -#include "json-writer.h" -#include "trace2/tr2_dst.h" -#include "trace2/tr2_sid.h" -#include "trace2/tr2_sysenv.h" -#include "trace2/tr2_tbuf.h" -#include "trace2/tr2_tgt.h" -#include "trace2/tr2_tls.h" - -static struct tr2_dst tr2dst_perf = { TR2_SYSENV_PERF, 0, 0, 0, 0 }; - -/* - * Use TR2_SYSENV_PERF_BRIEF to omit the "<time> <file>:<line>" - * fields from each line written to the builtin performance target. - * - * Unit tests may want to use this to help with testing. - */ -static int tr2env_perf_be_brief; - -#define TR2FMT_PERF_FL_WIDTH (28) -#define TR2FMT_PERF_MAX_EVENT_NAME (12) -#define TR2FMT_PERF_REPO_WIDTH (3) -#define TR2FMT_PERF_CATEGORY_WIDTH (12) - -#define TR2_INDENT (2) -#define TR2_INDENT_LENGTH(ctx) (((ctx)->nr_open_regions - 1) * TR2_INDENT) - -static int fn_init(void) -{ - int want = tr2_dst_trace_want(&tr2dst_perf); - int want_brief; - const char *brief; - - if (!want) - return want; - - brief = tr2_sysenv_get(TR2_SYSENV_PERF_BRIEF); - if (brief && *brief && - ((want_brief = git_parse_maybe_bool(brief)) != -1)) - tr2env_perf_be_brief = want_brief; - - return want; -} - -static void fn_term(void) -{ - tr2_dst_trace_disable(&tr2dst_perf); -} - -/* - * Format trace line prefix in human-readable classic format for - * the performance target: - * "[<time> [<file>:<line>] <bar>] <nr_parents> <bar> - * <thread_name> <bar> <event_name> <bar> [<repo>] <bar> - * [<elapsed_absolute>] [<elapsed_relative>] <bar> - * [<category>] <bar> [<dots>] " - */ -static void perf_fmt_prepare(const char *event_name, - struct tr2tls_thread_ctx *ctx, const char *file, - int line, const struct repository *repo, - uint64_t *p_us_elapsed_absolute, - uint64_t *p_us_elapsed_relative, - const char *category, struct strbuf *buf) -{ - int len; - - strbuf_setlen(buf, 0); - - if (!tr2env_perf_be_brief) { - struct tr2_tbuf tb_now; - size_t fl_end_col; - - tr2_tbuf_local_time(&tb_now); - strbuf_addstr(buf, tb_now.buf); - strbuf_addch(buf, ' '); - - fl_end_col = buf->len + TR2FMT_PERF_FL_WIDTH; - - if (file && *file) { - struct strbuf buf_fl = STRBUF_INIT; - - strbuf_addf(&buf_fl, "%s:%d", file, line); - - if (buf_fl.len <= TR2FMT_PERF_FL_WIDTH) - strbuf_addbuf(buf, &buf_fl); - else { - size_t avail = TR2FMT_PERF_FL_WIDTH - 3; - strbuf_addstr(buf, "..."); - strbuf_add(buf, - &buf_fl.buf[buf_fl.len - avail], - avail); - } - - strbuf_release(&buf_fl); - } - - while (buf->len < fl_end_col) - strbuf_addch(buf, ' '); - - strbuf_addstr(buf, " | "); - } - - strbuf_addf(buf, "d%d | ", tr2_sid_depth()); - strbuf_addf(buf, "%-*s | %-*s | ", TR2_MAX_THREAD_NAME, - ctx->thread_name.buf, TR2FMT_PERF_MAX_EVENT_NAME, - event_name); - - len = buf->len + TR2FMT_PERF_REPO_WIDTH; - if (repo) - strbuf_addf(buf, "r%d ", repo->trace2_repo_id); - while (buf->len < len) - strbuf_addch(buf, ' '); - strbuf_addstr(buf, " | "); - - if (p_us_elapsed_absolute) - strbuf_addf(buf, "%9.6f | ", - ((double)(*p_us_elapsed_absolute)) / 1000000.0); - else - strbuf_addf(buf, "%9s | ", " "); - - if (p_us_elapsed_relative) - strbuf_addf(buf, "%9.6f | ", - ((double)(*p_us_elapsed_relative)) / 1000000.0); - else - strbuf_addf(buf, "%9s | ", " "); - - strbuf_addf(buf, "%-*.*s | ", TR2FMT_PERF_CATEGORY_WIDTH, - TR2FMT_PERF_CATEGORY_WIDTH, (category ? category : "")); - - if (ctx->nr_open_regions > 0) - strbuf_addchars(buf, '.', TR2_INDENT_LENGTH(ctx)); -} - -static void perf_io_write_fl(const char *file, int line, const char *event_name, - const struct repository *repo, - uint64_t *p_us_elapsed_absolute, - uint64_t *p_us_elapsed_relative, - const char *category, - const struct strbuf *buf_payload) -{ - struct tr2tls_thread_ctx *ctx = tr2tls_get_self(); - struct strbuf buf_line = STRBUF_INIT; - - perf_fmt_prepare(event_name, ctx, file, line, repo, - p_us_elapsed_absolute, p_us_elapsed_relative, category, - &buf_line); - strbuf_addbuf(&buf_line, buf_payload); - tr2_dst_write_line(&tr2dst_perf, &buf_line); - strbuf_release(&buf_line); -} - -static void fn_version_fl(const char *file, int line) -{ - const char *event_name = "version"; - struct strbuf buf_payload = STRBUF_INIT; - - strbuf_addstr(&buf_payload, git_version_string); - - perf_io_write_fl(file, line, event_name, NULL, NULL, NULL, NULL, - &buf_payload); - strbuf_release(&buf_payload); -} - -static void fn_start_fl(const char *file, int line, - uint64_t us_elapsed_absolute, const char **argv) -{ - const char *event_name = "start"; - struct strbuf buf_payload = STRBUF_INIT; - - sq_append_quote_argv_pretty(&buf_payload, argv); - - perf_io_write_fl(file, line, event_name, NULL, &us_elapsed_absolute, - NULL, NULL, &buf_payload); - strbuf_release(&buf_payload); -} - -static void fn_exit_fl(const char *file, int line, uint64_t us_elapsed_absolute, - int code) -{ - const char *event_name = "exit"; - struct strbuf buf_payload = STRBUF_INIT; - - strbuf_addf(&buf_payload, "code:%d", code); - - perf_io_write_fl(file, line, event_name, NULL, &us_elapsed_absolute, - NULL, NULL, &buf_payload); - strbuf_release(&buf_payload); -} - -static void fn_signal(uint64_t us_elapsed_absolute, int signo) -{ - const char *event_name = "signal"; - struct strbuf buf_payload = STRBUF_INIT; - - strbuf_addf(&buf_payload, "signo:%d", signo); - - perf_io_write_fl(__FILE__, __LINE__, event_name, NULL, - &us_elapsed_absolute, NULL, NULL, &buf_payload); - strbuf_release(&buf_payload); -} - -static void fn_atexit(uint64_t us_elapsed_absolute, int code) -{ - const char *event_name = "atexit"; - struct strbuf buf_payload = STRBUF_INIT; - - strbuf_addf(&buf_payload, "code:%d", code); - - perf_io_write_fl(__FILE__, __LINE__, event_name, NULL, - &us_elapsed_absolute, NULL, NULL, &buf_payload); - strbuf_release(&buf_payload); -} - -static void maybe_append_string_va(struct strbuf *buf, const char *fmt, - va_list ap) -{ - if (fmt && *fmt) { - va_list copy_ap; - - va_copy(copy_ap, ap); - strbuf_vaddf(buf, fmt, copy_ap); - va_end(copy_ap); - return; - } -} - -static void fn_error_va_fl(const char *file, int line, const char *fmt, - va_list ap) -{ - const char *event_name = "error"; - struct strbuf buf_payload = STRBUF_INIT; - - maybe_append_string_va(&buf_payload, fmt, ap); - - perf_io_write_fl(file, line, event_name, NULL, NULL, NULL, NULL, - &buf_payload); - strbuf_release(&buf_payload); -} - -static void fn_command_path_fl(const char *file, int line, const char *pathname) -{ - const char *event_name = "cmd_path"; - struct strbuf buf_payload = STRBUF_INIT; - - strbuf_addstr(&buf_payload, pathname); - - perf_io_write_fl(file, line, event_name, NULL, NULL, NULL, NULL, - &buf_payload); - strbuf_release(&buf_payload); -} - -static void fn_command_name_fl(const char *file, int line, const char *name, - const char *hierarchy) -{ - const char *event_name = "cmd_name"; - struct strbuf buf_payload = STRBUF_INIT; - - strbuf_addstr(&buf_payload, name); - if (hierarchy && *hierarchy) - strbuf_addf(&buf_payload, " (%s)", hierarchy); - - perf_io_write_fl(file, line, event_name, NULL, NULL, NULL, NULL, - &buf_payload); - strbuf_release(&buf_payload); -} - -static void fn_command_mode_fl(const char *file, int line, const char *mode) -{ - const char *event_name = "cmd_mode"; - struct strbuf buf_payload = STRBUF_INIT; - - strbuf_addstr(&buf_payload, mode); - - perf_io_write_fl(file, line, event_name, NULL, NULL, NULL, NULL, - &buf_payload); - strbuf_release(&buf_payload); -} - -static void fn_alias_fl(const char *file, int line, const char *alias, - const char **argv) -{ - const char *event_name = "alias"; - struct strbuf buf_payload = STRBUF_INIT; - - strbuf_addf(&buf_payload, "alias:%s argv:[", alias); - sq_append_quote_argv_pretty(&buf_payload, argv); - strbuf_addch(&buf_payload, ']'); - - perf_io_write_fl(file, line, event_name, NULL, NULL, NULL, NULL, - &buf_payload); - strbuf_release(&buf_payload); -} - -static void fn_child_start_fl(const char *file, int line, - uint64_t us_elapsed_absolute, - const struct child_process *cmd) -{ - const char *event_name = "child_start"; - struct strbuf buf_payload = STRBUF_INIT; - - if (cmd->trace2_hook_name) { - strbuf_addf(&buf_payload, "[ch%d] class:hook hook:%s", - cmd->trace2_child_id, cmd->trace2_hook_name); - } else { - const char *child_class = - cmd->trace2_child_class ? cmd->trace2_child_class : "?"; - strbuf_addf(&buf_payload, "[ch%d] class:%s", - cmd->trace2_child_id, child_class); - } - - if (cmd->dir) { - strbuf_addstr(&buf_payload, " cd:"); - sq_quote_buf_pretty(&buf_payload, cmd->dir); - } - - strbuf_addstr(&buf_payload, " argv:["); - if (cmd->git_cmd) { - strbuf_addstr(&buf_payload, "git"); - if (cmd->argv[0]) - strbuf_addch(&buf_payload, ' '); - } - sq_append_quote_argv_pretty(&buf_payload, cmd->argv); - strbuf_addch(&buf_payload, ']'); - - perf_io_write_fl(file, line, event_name, NULL, &us_elapsed_absolute, - NULL, NULL, &buf_payload); - strbuf_release(&buf_payload); -} - -static void fn_child_exit_fl(const char *file, int line, - uint64_t us_elapsed_absolute, int cid, int pid, - int code, uint64_t us_elapsed_child) -{ - const char *event_name = "child_exit"; - struct strbuf buf_payload = STRBUF_INIT; - - strbuf_addf(&buf_payload, "[ch%d] pid:%d code:%d", cid, pid, code); - - perf_io_write_fl(file, line, event_name, NULL, &us_elapsed_absolute, - &us_elapsed_child, NULL, &buf_payload); - strbuf_release(&buf_payload); -} - -static void fn_thread_start_fl(const char *file, int line, - uint64_t us_elapsed_absolute) -{ - const char *event_name = "thread_start"; - struct strbuf buf_payload = STRBUF_INIT; - - perf_io_write_fl(file, line, event_name, NULL, &us_elapsed_absolute, - NULL, NULL, &buf_payload); - strbuf_release(&buf_payload); -} - -static void fn_thread_exit_fl(const char *file, int line, - uint64_t us_elapsed_absolute, - uint64_t us_elapsed_thread) -{ - const char *event_name = "thread_exit"; - struct strbuf buf_payload = STRBUF_INIT; - - perf_io_write_fl(file, line, event_name, NULL, &us_elapsed_absolute, - &us_elapsed_thread, NULL, &buf_payload); - strbuf_release(&buf_payload); -} - -static void fn_exec_fl(const char *file, int line, uint64_t us_elapsed_absolute, - int exec_id, const char *exe, const char **argv) -{ - const char *event_name = "exec"; - struct strbuf buf_payload = STRBUF_INIT; - - strbuf_addf(&buf_payload, "id:%d ", exec_id); - strbuf_addstr(&buf_payload, "argv:["); - if (exe) { - strbuf_addstr(&buf_payload, exe); - if (argv[0]) - strbuf_addch(&buf_payload, ' '); - } - sq_append_quote_argv_pretty(&buf_payload, argv); - strbuf_addch(&buf_payload, ']'); - - perf_io_write_fl(file, line, event_name, NULL, &us_elapsed_absolute, - NULL, NULL, &buf_payload); - strbuf_release(&buf_payload); -} - -static void fn_exec_result_fl(const char *file, int line, - uint64_t us_elapsed_absolute, int exec_id, - int code) -{ - const char *event_name = "exec_result"; - struct strbuf buf_payload = STRBUF_INIT; - - strbuf_addf(&buf_payload, "id:%d code:%d", exec_id, code); - if (code > 0) - strbuf_addf(&buf_payload, " err:%s", strerror(code)); - - perf_io_write_fl(file, line, event_name, NULL, &us_elapsed_absolute, - NULL, NULL, &buf_payload); - strbuf_release(&buf_payload); -} - -static void fn_param_fl(const char *file, int line, const char *param, - const char *value) -{ - const char *event_name = "def_param"; - struct strbuf buf_payload = STRBUF_INIT; - - strbuf_addf(&buf_payload, "%s:%s", param, value); - - perf_io_write_fl(file, line, event_name, NULL, NULL, NULL, NULL, - &buf_payload); - strbuf_release(&buf_payload); -} - -static void fn_repo_fl(const char *file, int line, - const struct repository *repo) -{ - const char *event_name = "def_repo"; - struct strbuf buf_payload = STRBUF_INIT; - - strbuf_addstr(&buf_payload, "worktree:"); - sq_quote_buf_pretty(&buf_payload, repo->worktree); - - perf_io_write_fl(file, line, event_name, repo, NULL, NULL, NULL, - &buf_payload); - strbuf_release(&buf_payload); -} - -static void fn_region_enter_printf_va_fl(const char *file, int line, - uint64_t us_elapsed_absolute, - const char *category, - const char *label, - const struct repository *repo, - const char *fmt, va_list ap) -{ - const char *event_name = "region_enter"; - struct strbuf buf_payload = STRBUF_INIT; - - if (label) - strbuf_addf(&buf_payload, "label:%s", label); - if (fmt && *fmt) { - strbuf_addch(&buf_payload, ' '); - maybe_append_string_va(&buf_payload, fmt, ap); - } - - perf_io_write_fl(file, line, event_name, repo, &us_elapsed_absolute, - NULL, category, &buf_payload); - strbuf_release(&buf_payload); -} - -static void fn_region_leave_printf_va_fl( - const char *file, int line, uint64_t us_elapsed_absolute, - uint64_t us_elapsed_region, const char *category, const char *label, - const struct repository *repo, const char *fmt, va_list ap) -{ - const char *event_name = "region_leave"; - struct strbuf buf_payload = STRBUF_INIT; - - if (label) - strbuf_addf(&buf_payload, "label:%s", label); - if (fmt && *fmt) { - strbuf_addch(&buf_payload, ' ' ); - maybe_append_string_va(&buf_payload, fmt, ap); - } - - perf_io_write_fl(file, line, event_name, repo, &us_elapsed_absolute, - &us_elapsed_region, category, &buf_payload); - strbuf_release(&buf_payload); -} - -static void fn_data_fl(const char *file, int line, uint64_t us_elapsed_absolute, - uint64_t us_elapsed_region, const char *category, - const struct repository *repo, const char *key, - const char *value) -{ - const char *event_name = "data"; - struct strbuf buf_payload = STRBUF_INIT; - - strbuf_addf(&buf_payload, "%s:%s", key, value); - - perf_io_write_fl(file, line, event_name, repo, &us_elapsed_absolute, - &us_elapsed_region, category, &buf_payload); - strbuf_release(&buf_payload); -} - -static void fn_data_json_fl(const char *file, int line, - uint64_t us_elapsed_absolute, - uint64_t us_elapsed_region, const char *category, - const struct repository *repo, const char *key, - const struct json_writer *value) -{ - const char *event_name = "data_json"; - struct strbuf buf_payload = STRBUF_INIT; - - strbuf_addf(&buf_payload, "%s:%s", key, value->json.buf); - - perf_io_write_fl(file, line, event_name, repo, &us_elapsed_absolute, - &us_elapsed_region, category, &buf_payload); - strbuf_release(&buf_payload); -} - -static void fn_printf_va_fl(const char *file, int line, - uint64_t us_elapsed_absolute, const char *fmt, - va_list ap) -{ - const char *event_name = "printf"; - struct strbuf buf_payload = STRBUF_INIT; - - maybe_append_string_va(&buf_payload, fmt, ap); - - perf_io_write_fl(file, line, event_name, NULL, &us_elapsed_absolute, - NULL, NULL, &buf_payload); - strbuf_release(&buf_payload); -} - -struct tr2_tgt tr2_tgt_perf = { - &tr2dst_perf, - - fn_init, - fn_term, - - fn_version_fl, - fn_start_fl, - fn_exit_fl, - fn_signal, - fn_atexit, - fn_error_va_fl, - fn_command_path_fl, - fn_command_name_fl, - fn_command_mode_fl, - fn_alias_fl, - fn_child_start_fl, - fn_child_exit_fl, - fn_thread_start_fl, - fn_thread_exit_fl, - fn_exec_fl, - fn_exec_result_fl, - fn_param_fl, - fn_repo_fl, - fn_region_enter_printf_va_fl, - fn_region_leave_printf_va_fl, - fn_data_fl, - fn_data_json_fl, - fn_printf_va_fl, -}; diff --git a/third_party/git/trace2/tr2_tls.c b/third_party/git/trace2/tr2_tls.c deleted file mode 100644 index 067c23755fb5..000000000000 --- a/third_party/git/trace2/tr2_tls.c +++ /dev/null @@ -1,180 +0,0 @@ -#include "cache.h" -#include "thread-utils.h" -#include "trace2/tr2_tls.h" - -/* - * Initialize size of the thread stack for nested regions. - * This is used to store nested region start times. Note that - * this stack is per-thread and not per-trace-key. - */ -#define TR2_REGION_NESTING_INITIAL_SIZE (100) - -static struct tr2tls_thread_ctx *tr2tls_thread_main; -static uint64_t tr2tls_us_start_process; - -static pthread_mutex_t tr2tls_mutex; -static pthread_key_t tr2tls_key; - -static int tr2_next_thread_id; /* modify under lock */ - -void tr2tls_start_process_clock(void) -{ - if (tr2tls_us_start_process) - return; - - /* - * Keep the absolute start time of the process (i.e. the main - * process) in a fixed variable since other threads need to - * access it. This allows them to do that without a lock on - * main thread's array data (because of reallocs). - */ - tr2tls_us_start_process = getnanotime() / 1000; -} - -struct tr2tls_thread_ctx *tr2tls_create_self(const char *thread_name, - uint64_t us_thread_start) -{ - struct tr2tls_thread_ctx *ctx = xcalloc(1, sizeof(*ctx)); - - /* - * Implicitly "tr2tls_push_self()" to capture the thread's start - * time in array_us_start[0]. For the main thread this gives us the - * application run time. - */ - ctx->alloc = TR2_REGION_NESTING_INITIAL_SIZE; - ctx->array_us_start = (uint64_t *)xcalloc(ctx->alloc, sizeof(uint64_t)); - ctx->array_us_start[ctx->nr_open_regions++] = us_thread_start; - - ctx->thread_id = tr2tls_locked_increment(&tr2_next_thread_id); - - strbuf_init(&ctx->thread_name, 0); - if (ctx->thread_id) - strbuf_addf(&ctx->thread_name, "th%02d:", ctx->thread_id); - strbuf_addstr(&ctx->thread_name, thread_name); - if (ctx->thread_name.len > TR2_MAX_THREAD_NAME) - strbuf_setlen(&ctx->thread_name, TR2_MAX_THREAD_NAME); - - pthread_setspecific(tr2tls_key, ctx); - - return ctx; -} - -struct tr2tls_thread_ctx *tr2tls_get_self(void) -{ - struct tr2tls_thread_ctx *ctx; - - if (!HAVE_THREADS) - return tr2tls_thread_main; - - ctx = pthread_getspecific(tr2tls_key); - - /* - * If the thread-proc did not call trace2_thread_start(), we won't - * have any TLS data associated with the current thread. Fix it - * here and silently continue. - */ - if (!ctx) - ctx = tr2tls_create_self("unknown", getnanotime() / 1000); - - return ctx; -} - -int tr2tls_is_main_thread(void) -{ - if (!HAVE_THREADS) - return 1; - - return pthread_getspecific(tr2tls_key) == tr2tls_thread_main; -} - -void tr2tls_unset_self(void) -{ - struct tr2tls_thread_ctx *ctx; - - ctx = tr2tls_get_self(); - - pthread_setspecific(tr2tls_key, NULL); - - free(ctx->array_us_start); - free(ctx); -} - -void tr2tls_push_self(uint64_t us_now) -{ - struct tr2tls_thread_ctx *ctx = tr2tls_get_self(); - - ALLOC_GROW(ctx->array_us_start, ctx->nr_open_regions + 1, ctx->alloc); - ctx->array_us_start[ctx->nr_open_regions++] = us_now; -} - -void tr2tls_pop_self(void) -{ - struct tr2tls_thread_ctx *ctx = tr2tls_get_self(); - - if (!ctx->nr_open_regions) - BUG("no open regions in thread '%s'", ctx->thread_name.buf); - - ctx->nr_open_regions--; -} - -void tr2tls_pop_unwind_self(void) -{ - struct tr2tls_thread_ctx *ctx = tr2tls_get_self(); - - while (ctx->nr_open_regions > 1) - tr2tls_pop_self(); -} - -uint64_t tr2tls_region_elasped_self(uint64_t us) -{ - struct tr2tls_thread_ctx *ctx; - uint64_t us_start; - - ctx = tr2tls_get_self(); - if (!ctx->nr_open_regions) - return 0; - - us_start = ctx->array_us_start[ctx->nr_open_regions - 1]; - - return us - us_start; -} - -uint64_t tr2tls_absolute_elapsed(uint64_t us) -{ - if (!tr2tls_thread_main) - return 0; - - return us - tr2tls_us_start_process; -} - -void tr2tls_init(void) -{ - tr2tls_start_process_clock(); - - pthread_key_create(&tr2tls_key, NULL); - init_recursive_mutex(&tr2tls_mutex); - - tr2tls_thread_main = - tr2tls_create_self("main", tr2tls_us_start_process); -} - -void tr2tls_release(void) -{ - tr2tls_unset_self(); - tr2tls_thread_main = NULL; - - pthread_mutex_destroy(&tr2tls_mutex); - pthread_key_delete(tr2tls_key); -} - -int tr2tls_locked_increment(int *p) -{ - int current_value; - - pthread_mutex_lock(&tr2tls_mutex); - current_value = *p; - *p = current_value + 1; - pthread_mutex_unlock(&tr2tls_mutex); - - return current_value; -} diff --git a/third_party/git/trace2/tr2_tls.h b/third_party/git/trace2/tr2_tls.h deleted file mode 100644 index b1e327a928e2..000000000000 --- a/third_party/git/trace2/tr2_tls.h +++ /dev/null @@ -1,103 +0,0 @@ -#ifndef TR2_TLS_H -#define TR2_TLS_H - -#include "strbuf.h" - -/* - * Arbitry limit for thread names for column alignment. - */ -#define TR2_MAX_THREAD_NAME (24) - -struct tr2tls_thread_ctx { - struct strbuf thread_name; - uint64_t *array_us_start; - int alloc; - int nr_open_regions; /* plays role of "nr" in ALLOC_GROW */ - int thread_id; -}; - -/* - * Create TLS data for the current thread. This gives us a place to - * put per-thread data, such as thread start time, function nesting - * and a per-thread label for our messages. - * - * We assume the first thread is "main". Other threads are given - * non-zero thread-ids to help distinguish messages from concurrent - * threads. - * - * Truncate the thread name if necessary to help with column alignment - * in printf-style messages. - * - * In this and all following functions the term "self" refers to the - * current thread. - */ -struct tr2tls_thread_ctx *tr2tls_create_self(const char *thread_name, - uint64_t us_thread_start); - -/* - * Get our TLS data. - */ -struct tr2tls_thread_ctx *tr2tls_get_self(void); - -/* - * return true if the current thread is the main thread. - */ -int tr2tls_is_main_thread(void); - -/* - * Free our TLS data. - */ -void tr2tls_unset_self(void); - -/* - * Begin a new nested region and remember the start time. - */ -void tr2tls_push_self(uint64_t us_now); - -/* - * End the innermost nested region. - */ -void tr2tls_pop_self(void); - -/* - * Pop any extra (above the first) open regions on the current - * thread and discard. During a thread-exit, we should only - * have region[0] that was pushed in trace2_thread_start() if - * the thread exits normally. - */ -void tr2tls_pop_unwind_self(void); - -/* - * Compute the elapsed time since the innermost region in the - * current thread started and the given time (usually now). - */ -uint64_t tr2tls_region_elasped_self(uint64_t us); - -/* - * Compute the elapsed time since the main thread started - * and the given time (usually now). This is assumed to - * be the absolute run time of the process. - */ -uint64_t tr2tls_absolute_elapsed(uint64_t us); - -/* - * Initialize the tr2 TLS system. - */ -void tr2tls_init(void); - -/* - * Free all tr2 TLS resources. - */ -void tr2tls_release(void); - -/* - * Protected increment of an integer. - */ -int tr2tls_locked_increment(int *p); - -/* - * Capture the process start time and do nothing else. - */ -void tr2tls_start_process_clock(void); - -#endif /* TR2_TLS_H */ |