trace2: Documentation/technical/api-trace2.txt

Created design document for Trace2 feature. Signed-off-by: Jeff Hostetler <jeffhost@microsoft.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Jeff Hostetler committed Feb 22, 2019 at 14:25 UTC e544221d97a57a9be7ba18a0df52a15b4cc76f97
1 file changed +1349
Documentation/technical/api-trace2.txt new
+1349
@@ -0,0 +1,1349 @@
1 += Trace2 API
2 +
3 +The Trace2 API can be used to print debug, performance, and telemetry
4 +information to stderr or a file. The Trace2 feature is inactive unless
5 +explicitly enabled by enabling one or more Trace2 Targets.
6 +
7 +The Trace2 API is intended to replace the existing (Trace1)
8 +printf-style tracing provided by the existing `GIT_TRACE` and
9 +`GIT_TRACE_PERFORMANCE` facilities. During initial implementation,
10 +Trace2 and Trace1 may operate in parallel.
11 +
12 +The Trace2 API defines a set of high-level messages with known fields,
13 +such as (`start`: `argv`) and (`exit`: {`exit-code`, `elapsed-time`}).
14 +
15 +Trace2 instrumentation throughout the Git code base sends Trace2
16 +messages to the enabled Trace2 Targets. Targets transform these
17 +messages content into purpose-specific formats and write events to
18 +their data streams. In this manner, the Trace2 API can drive
19 +many different types of analysis.
20 +
21 +Targets are defined using a VTable allowing easy extension to other
22 +formats in the future. This might be used to define a binary format,
23 +for example.
24 +
25 +== Trace2 Targets
26 +
27 +Trace2 defines the following set of Trace2 Targets.
28 +Format details are given in a later section.
29 +
30 +`GIT_TR2` (NORMAL)::
31 +
32 + a simple printf format like GIT_TRACE.
33 ++
34 +------------
35 +$ export GIT_TR2=~/log.normal
36 +$ git version
37 +git version 2.20.1.155.g426c96fcdb
38 +------------
39 ++
40 +------------
41 +$ cat ~/log.normal
42 +12:28:42.620009 common-main.c:38 version 2.20.1.155.g426c96fcdb
43 +12:28:42.620989 common-main.c:39 start git version
44 +12:28:42.621101 git.c:432 cmd_name version (version)
45 +12:28:42.621215 git.c:662 exit elapsed:0.001227 code:0
46 +12:28:42.621250 trace2/tr2_tgt_normal.c:124 atexit elapsed:0.001265 code:0
47 +------------
48 +
49 +`GIT_TR2_PERF` (PERF)::
50 +
51 + a column-based format to replace GIT_TRACE_PERFORMANCE suitable for
52 + development and testing, possibly to complement tools like gprof.
53 ++
54 +------------
55 +$ export GIT_TR2_PERF=~/log.perf
56 +$ git version
57 +git version 2.20.1.155.g426c96fcdb
58 +------------
59 ++
60 +------------
61 +$ cat ~/log.perf
62 +12:28:42.620675 common-main.c:38 | d0 | main | version | | | | | 2.20.1.155.g426c96fcdb
63 +12:28:42.621001 common-main.c:39 | d0 | main | start | | | | | git version
64 +12:28:42.621111 git.c:432 | d0 | main | cmd_name | | | | | version (version)
65 +12:28:42.621225 git.c:662 | d0 | main | exit | | 0.001227 | | | code:0
66 +12:28:42.621259 trace2/tr2_tgt_perf.c:211 | d0 | main | atexit | | 0.001265 | | | code:0
67 +------------
68 +
69 +`GIT_TR2_EVENT` (EVENT)::
70 +
71 + a JSON-based format of event data suitable for telemetry analysis.
72 ++
73 +------------
74 +$ export GIT_TR2_EVENT=~/log.event
75 +$ git version
76 +git version 2.20.1.155.g426c96fcdb
77 +------------
78 ++
79 +------------
80 +$ cat ~/log.event
81 +{"event":"version","sid":"1547659722619736-11614","thread":"main","time":"2019-01-16 17:28:42.620713","file":"common-main.c","line":38,"evt":"1","exe":"2.20.1.155.g426c96fcdb"}
82 +{"event":"start","sid":"1547659722619736-11614","thread":"main","time":"2019-01-16 17:28:42.621027","file":"common-main.c","line":39,"argv":["git","version"]}
83 +{"event":"cmd_name","sid":"1547659722619736-11614","thread":"main","time":"2019-01-16 17:28:42.621122","file":"git.c","line":432,"name":"version","hierarchy":"version"}
84 +{"event":"exit","sid":"1547659722619736-11614","thread":"main","time":"2019-01-16 17:28:42.621236","file":"git.c","line":662,"t_abs":0.001227,"code":0}
85 +{"event":"atexit","sid":"1547659722619736-11614","thread":"main","time":"2019-01-16 17:28:42.621268","file":"trace2/tr2_tgt_event.c","line":163,"t_abs":0.001265,"code":0}
86 +------------
87 +
88 +== Enabling a Target
89 +
90 +A Trace2 Target is enabled when the corresponding environment variable
91 +(`GIT_TR2`, `GIT_TR2_PERF`, or `GIT_TR2_EVENT`) is set. The following
92 +values are recognized.
93 +
94 +`0`::
95 +`false`::
96 +
97 + Disables the target.
98 +
99 +`1`::
100 +`true`::
101 +
102 + Enables the target and writes stream to `STDERR`.
103 +
104 +`[2-9]`::
105 +
106 + Enables the target and writes to the already opened file descriptor.
107 +
108 +`<absolute-pathname>`::
109 +
110 + Enables the target, opens and writes to the file in append mode.
111 +
112 +`af_unix:[<socket_type>:]<absolute-pathname>`::
113 +
114 + Enables the target, opens and writes to a Unix Domain Socket
115 + (on platforms that support them).
116 ++
117 +Socket type can be either `stream` or `dgram`. If the socket type is
118 +omitted, Git will try both.
119 +
120 +== Trace2 API
121 +
122 +All public Trace2 functions and macros are defined in `trace2.h` and
123 +`trace2.c`. All public symbols are prefixed with `trace2_`.
124 +
125 +There are no public Trace2 data structures.
126 +
127 +The Trace2 code also defines a set of private functions and data types
128 +in the `trace2/` directory. These symbols are prefixed with `tr2_`
129 +and should only be used by functions in `trace2.c`.
130 +
131 +== Conventions for Public Functions and Macros
132 +
133 +The functions defined by the Trace2 API are declared and documented
134 +in `trace2.h`. It defines the API functions and wrapper macros for
135 +Trace2.
136 +
137 +Some functions have a `_fl()` suffix to indicate that they take `file`
138 +and `line-number` arguments.
139 +
140 +Some functions have a `_va_fl()` suffix to indicate that they also
141 +take a `va_list` argument.
142 +
143 +Some functions have a `_printf_fl()` suffix to indicate that they also
144 +take a varargs argument.
145 +
146 +There are CPP wrapper macros and ifdefs to hide most of these details.
147 +See `trace2.h` for more details. The following discussion will only
148 +describe the simplified forms.
149 +
150 +== Public API
151 +
152 +All Trace2 API functions send a messsage to all of the active
153 +Trace2 Targets. This section describes the set of available
154 +messages.
155 +
156 +It helps to divide these functions into groups for discussion
157 +purposes.
158 +
159 +=== Basic Command Messages
160 +
161 +These are concerned with the lifetime of the overall git process.
162 +
163 +`void trace2_initialize()`::
164 +
165 + Determines if any Trace2 Targets should be enabled and
166 + initializes the Trace2 facility. This includes starting the
167 + elapsed time clocks and thread local storage (TLS).
168 ++
169 +This function emits a "version" message containing the version of git
170 +and the Trace2 protocol.
171 ++
172 +This function should be called from `main()` as early as possible in
173 +the life of the process.
174 +
175 +`int trace2_is_enabled()`::
176 +
177 + Returns 1 if Trace2 is enabled (at least one target is
178 + active).
179 +
180 +`void trace2_cmd_start(int argc, const char **argv)`::
181 +
182 + Emits a "start" message containing the process command line
183 + arguments.
184 +
185 +`int trace2_cmd_exit(int exit_code)`::
186 +
187 + Emits an "exit" message containing the process exit-code and
188 + elapsed time.
189 ++
190 +Returns the exit-code.
191 +
192 +`void trace2_cmd_error(const char *fmt, va_list ap)`::
193 +
194 + Emits an "error" message containing a formatted error message.
195 +
196 +`void trace2_cmd_path(const char *pathname)`::
197 +
198 + Emits a "cmd_path" message with the full pathname of the
199 + current process.
200 +
201 +=== Command Detail Messages
202 +
203 +These are concerned with describing the specific Git command
204 +after the command line, config, and environment are inspected.
205 +
206 +`void trace2_cmd_name(const char *name)`::
207 +
208 + Emits a "cmd_name" message with the canonical name of the
209 + command, for example "status" or "checkout".
210 +
211 +`void trace2_cmd_mode(const char *mode)`::
212 +
213 + Emits a "cmd_mode" message with a qualifier name to further
214 + describe the current git command.
215 ++
216 +This message is intended to be used with git commands having multiple
217 +major modes. For example, a "checkout" command can checkout a new
218 +branch or it can checkout a single file, so the checkout code could
219 +emit a cmd_mode message of "branch" or "file".
220 +
221 +`void trace2_cmd_alias(const char *alias, const char **argv_expansion)`::
222 +
223 + Emits an "alias" message containing the alias used and the
224 + argument expansion.
225 +
226 +`void trace2_def_param(const char *parameter, const char *value)`::
227 +
228 + Emits a "def_param" message containing a key/value pair.
229 ++
230 +This message is intended to report some global aspect of the current
231 +command, such as a configuration setting or command line switch that
232 +significantly affects program performance or behavior, such as
233 +`core.abbrev`, `status.showUntrackedFiles`, or `--no-ahead-behind`.
234 +
235 +`void trace2_cmd_list_config()`::
236 +
237 + Emits a "def_param" messages for "important" configuration
238 + settings.
239 ++
240 +The environment variable `GIT_TR2_CONFIG_PARAMS` can be set to a
241 +list of patterns of important configuration settings, for example:
242 +`core.*,remote.*.url`. This function will iterate over all config
243 +settings and emit a "def_param" message for each match.
244 +
245 +`void trace2_cmd_set_config(const char *key, const char *value)`::
246 +
247 + Emits a "def_param" message for a specific configuration
248 + setting IFF it matches the `GIT_TR2_CONFIG_PARAMS` pattern.
249 ++
250 +This is used to hook into `git_config_set()` and catch any
251 +configuration changes and update a value previously reported by
252 +`trace2_cmd_list_config()`.
253 +
254 +`void trace2_def_repo(struct repository *repo)`::
255 +
256 + Registers a repository with the Trace2 layer. Assigns a
257 + unique "repo-id" to `repo->trace2_repo_id`.
258 ++
259 +Emits a "worktree" messages containing the repo-id and the worktree
260 +pathname.
261 ++
262 +Region and data messages (described later) may refer to this repo-id.
263 ++
264 +The main/top-level repository will have repo-id value 1 (aka "r1").
265 ++
266 +The repo-id field is in anticipation of future in-proc submodule
267 +repositories.
268 +
269 +=== Child Process Messages
270 +
271 +These are concerned with the various spawned child processes,
272 +including shell scripts, git commands, editors, pagers, and hooks.
273 +
274 +`void trace2_child_start(struct child_process *cmd)`::
275 +
276 + Emits a "child_start" message containing the "child-id",
277 + "child-argv", and "child-classification".
278 ++
279 +Before calling this, set `cmd->trace2_child_class` to a name
280 +describing the type of child process, for example "editor".
281 ++
282 +This function assigns a unique "child-id" to `cmd->trace2_child_id`.
283 +This field is used later during the "child_exit" message to associate
284 +it with the "child_start" message.
285 ++
286 +This function should be called before spawning the child process.
287 +
288 +`void trace2_child_exit(struct child_proess *cmd, int child_exit_code)`::
289 +
290 + Emits a "child_exit" message containing the "child-id",
291 + the child's elapsed time and exit-code.
292 ++
293 +The reported elapsed time includes the process creation overhead and
294 +time spend waiting for it to exit, so it may be slightly longer than
295 +the time reported by the child itself.
296 ++
297 +This function should be called after reaping the child process.
298 +
299 +`int trace2_exec(const char *exe, const char **argv)`::
300 +
301 + Emits a "exec" message containing the "exec-id" and the
302 + argv of the new process.
303 ++
304 +This function should be called before calling one of the `exec()`
305 +variants, such as `execvp()`.
306 ++
307 +This function returns a unique "exec-id". This value is used later
308 +if the exec() fails and a "exec-result" message is necessary.
309 +
310 +`void trace2_exec_result(int exec_id, int error_code)`::
311 +
312 + Emits a "exec_result" message containing the "exec-id"
313 + and the error code.
314 ++
315 +On Unix-based systems, `exec()` does not return if successful.
316 +This message is used to indicate that the `exec()` failed and
317 +that the current program is continuing.
318 +
319 +=== Git Thread Messages
320 +
321 +These messages are concerned with Git thread usage.
322 +
323 +`void trace2_thread_start(const char *thread_name)`::
324 +
325 + Emits a "thread_start" message.
326 ++
327 +The `thread_name` field should be a descriptive name, such as the
328 +unique name of the thread-proc. A unique "thread-id" will be added
329 +to the name to uniquely identify thread instances.
330 ++
331 +Region and data messages (described later) may refer to this thread
332 +name.
333 ++
334 +This function must be called by the thread-proc of the new thread
335 +(so that TLS data is properly initialized) and not by the caller
336 +of `pthread_create()`.
337 +
338 +`void trace2_thread_exit()`::
339 +
340 + Emits a "thread_exit" message containing the thread name
341 + and the thread elapsed time.
342 ++
343 +This function must be called by the thread-proc before it returns
344 +(so that the coorect TLS data is used and cleaned up. It should
345 +not be called by the caller of `pthread_join()`.
346 +
347 +=== Region and Data Messages
348 +
349 +These are concerned with recording performance data
350 +over regions or spans of code.
351 +
352 +`void trace2_region_enter(const char *category, const char *label, const struct repository *repo)`::
353 +
354 +`void trace2_region_enter_printf(const char *category, const char *label, const struct repository *repo, const char *fmt, ...)`::
355 +
356 +`void trace2_region_enter_printf_va(const char *category, const char *label, const struct repository *repo, const char *fmt, va_list ap)`::
357 +
358 + Emits a thread-relative "region_enter" message with optional
359 + printf string.
360 ++
361 +This function pushes a new region nesting stack level on the current
362 +thread and starts a clock for the new stack frame.
363 ++
364 +The `category` field is an arbitrary category name used to classify
365 +regions by feature area, such as "status" or "index". At this time
366 +it is only just printed along with the rest of the message. It may
367 +be used in the future to filter messages.
368 ++
369 +The `label` field is an arbitrary label used to describe the activity
370 +being started, such as "read_recursive" or "do_read_index".
371 ++
372 +The `repo` field, if set, will be used to get the "repo-id", so that
373 +recursive oerations can be attributed to the correct repository.
374 +
375 +`void trace2_region_leave(const char *category, const char *label, const struct repository *repo)`::
376 +
377 +`void trace2_region_leave_printf(const char *category, const char *label, const struct repository *repo, const char *fmt, ...)`::
378 +
379 +`void trace2_region_leave_printf_va(const char *category, const char *label, const struct repository *repo, const char *fmt, va_list ap)`::
380 +
381 + Emits a thread-relative "region_leave" message with optional
382 + printf string.
383 ++
384 +This function pops the region nesting stack on the current thread
385 +and reports the elapsed time of the stack frame.
386 ++
387 +The `category`, `label`, and `repo` fields are the same as above.
388 +The `category` and `label` do not need to match the correpsonding
389 +"region_enter" message, but it makes the data stream easier to
390 +understand.
391 +
392 +`void trace2_data_string(const char *category, const struct repository *repo, const char *key, const char * value)`::
393 +
394 +`void trace2_data_intmax(const char *category, const struct repository *repo, const char *key, intmax value)`::
395 +
396 +`void trace2_data_json(const char *category, const struct repository *repo, const char *key, const struct json_writer *jw)`::
397 +
398 + Emits a region- and thread-relative "data" or "data_json" message.
399 ++
400 +This is a key/value pair message containing information about the
401 +current thread, region stack, and repository. This could be used
402 +to print the number of files in a directory during a multi-threaded
403 +recursive tree walk.
404 +
405 +`void trace2_printf(const char *fmt, ...)`::
406 +
407 +`void trace2_printf_va(const char *fmt, va_list ap)`::
408 +
409 + Emits a region- and thread-relative "printf" message.
410 +
411 +== Trace2 Target Formats
412 +
413 +=== NORMAL Format
414 +
415 +NORMAL format is enabled when the `GIT_TR2` environment variable is
416 +set.
417 +
418 +Events are written as lines of the form:
419 +
420 +------------
421 +[<time> SP <filename>:<line> SP+] <event-name> [[SP] <event-message>] LF
422 +------------
423 +
424 +`<event-name>`::
425 +
426 + is the event name.
427 +
428 +`<event-message>`::
429 + is a free-form printf message intended for human consumption.
430 ++
431 +Note that this may contain embedded LF or CRLF characters that are
432 +not escaped, so the event may spill across multiple lines.
433 +
434 +If `GIT_TR2_BRIEF` is true, the `time`, `filename`, and `line` fields
435 +are omitted.
436 +
437 +This target is intended to be more of a summary (like GIT_TRACE) and
438 +less detailed than the other targets. It ignores thread, region, and
439 +data messages, for example.
440 +
441 +=== PERF Format
442 +
443 +PERF format is enabled when the `GIT_TR2_PERF` environment variable
444 +is set.
445 +
446 +Events are written as lines of the form:
447 +
448 +------------
449 +[<time> SP <filename>:<line> SP+
450 + BAR SP] d<depth> SP
451 + BAR SP <thread-name> SP+
452 + BAR SP <event-name> SP+
453 + BAR SP [r<repo-id>] SP+
454 + BAR SP [<t_abs>] SP+
455 + BAR SP [<t_rel>] SP+
456 + BAR SP [<category>] SP+
457 + BAR SP DOTS* <perf-event-message>
458 + LF
459 +------------
460 +
461 +`<depth>`::
462 + is the git process depth. This is the number of parent
463 + git processes. A top-level git command has depth value "d0".
464 + A child of it has depth value "d1". A second level child
465 + has depth value "d2" and so on.
466 +
467 +`<thread-name>`::
468 + is a unique name for the thread. The primary thread
469 + is called "main". Other thread names are of the form "th%d:%s"
470 + and include a unique number and the name of the thread-proc.
471 +
472 +`<event-name>`::
473 + is the event name.
474 +
475 +`<repo-id>`::
476 + when present, is a number indicating the repository
477 + in use. A `def_repo` event is emitted when a repository is
478 + opened. This defines the repo-id and associated worktree.
479 + Subsequent repo-specific events will reference this repo-id.
480 ++
481 +Currently, this is always "r1" for the main repository.
482 +This field is in anticipation of in-proc submodules in the future.
483 +
484 +`<t_abs>`::
485 + when present, is the absolute time in seconds since the
486 + program started.
487 +
488 +`<t_rel>`::
489 + when present, is time in seconds relative to the start of
490 + the current region. For a thread-exit event, it is the elapsed
491 + time of the thread.
492 +
493 +`<category>`::
494 + is present on region and data events and is used to
495 + indicate a broad category, such as "index" or "status".
496 +
497 +`<perf-event-message>`::
498 + is a free-form printf message intended for human consumption.
499 +
500 +------------
501 +15:33:33.532712 wt-status.c:2310 | d0 | main | region_enter | r1 | 0.126064 | | status | label:print
502 +15:33:33.532712 wt-status.c:2331 | d0 | main | region_leave | r1 | 0.127568 | 0.001504 | status | label:print
503 +------------
504 +
505 +If `GIT_TR2_PERF_BRIEF` is true, the `time`, `file`, and `line`
506 +fields are omitted.
507 +
508 +------------
509 +d0 | main | region_leave | r1 | 0.011717 | 0.009122 | index | label:preload
510 +------------
511 +
512 +The PERF target is intended for interactive performance analysis
513 +during development and is quite noisy.
514 +
515 +=== EVENT Format
516 +
517 +EVENT format is enabled when the `GIT_TR2_EVENT` environment
518 +variable is set.
519 +
520 +Each event is a JSON-object containing multiple key/value pairs
521 +written as a single line and followed by a LF.
522 +
523 +------------
524 +'{' <key> ':' <value> [',' <key> ':' <value>]* '}' LF
525 +------------
526 +
527 +Some key/value pairs are common to all events and some are
528 +event-specific.
529 +
530 +==== Common Key/Value Pairs
531 +
532 +The following key/value pairs are common to all events:
533 +
534 +------------
535 +{
536 + "event":"version",
537 + "sid":"1547659722619736-11614",
538 + "thread":"main",
539 + "time":"2019-01-16 17:28:42.620713",
540 + "file":"common-main.c",
541 + "line":38,
542 + ...
543 +}
544 +------------
545 +
546 +`"event":<event>`::
547 + is the event name.
548 +
549 +`"sid":<sid>`::
550 + is the session-id. This is a unique string to identify the
551 + process instance to allow all events emitted by a process to
552 + be identified. A session-id is used instead of a PID because
553 + PIDs are recycled by the OS. For child git processes, the
554 + session-id is prepended with the session-id of the parent git
555 + process to allow parent-child relationships to be identified
556 + during post-processing.
557 +
558 +`"thread":<thread>`::
559 + is the thread name.
560 +
561 +`"time":<time>`::
562 + is the UTC time of the event.
563 +
564 +`"file":<filename>`::
565 + is source file generating the event.
566 +
567 +`"line":<line-number>`::
568 + is the integer source line number generating the event.
569 +
570 +`"repo":<repo-id>`::
571 + when present, is the integer repo-id as described previously.
572 +
573 +If `GIT_TR2_EVENT_BRIEF` is true, the `file` and `line` fields are omitted
574 +from all events and the `time` field is only present on the "start" and
575 +"atexit" events.
576 +
577 +==== Event-Specific Key/Value Pairs
578 +
579 +`"version"`::
580 + This event gives the version of the executable and the EVENT format.
581 ++
582 +------------
583 +{
584 + "event":"version",
585 + ...
586 + "evt":"1", # EVENT format version
587 + "exe":"2.20.1.155.g426c96fcdb" # git version
588 +}
589 +------------
590 +
591 +`"start"`::
592 + This event contains the complete argv received by main().
593 ++
594 +------------
595 +{
596 + "event":"start",
597 + ...
598 + "argv":["git","version"]
599 +}
600 +------------
601 +
602 +`"exit"`::
603 + This event is emitted when git calls `exit()`.
604 ++
605 +------------
606 +{
607 + "event":"exit",
608 + ...
609 + "t_abs":0.001227, # elapsed time in seconds
610 + "code":0 # exit code
611 +}
612 +------------
613 +
614 +`"atexit"`::
615 + This event is emitted by the Trace2 `atexit` routine during
616 + final shutdown. It should be the last event emitted by the
617 + process.
618 ++
619 +(The elapsed time reported here is greater than the time reported in
620 +the "exit" event because it runs after all other atexit tasks have
621 +completed.)
622 ++
623 +------------
624 +{
625 + "event":"atexit",
626 + ...
627 + "t_abs":0.001227, # elapsed time in seconds
628 + "code":0 # exit code
629 +}
630 +------------
631 +
632 +`"signal"`::
633 + This event is emitted when the program is terminated by a user
634 + signal. Depending on the platform, the signal event may
635 + prevent the "atexit" event from being generated.
636 ++
637 +------------
638 +{
639 + "event":"signal",
640 + ...
641 + "t_abs":0.001227, # elapsed time in seconds
642 + "signal":13 # SIGTERM, SIGINT, etc.
643 +}
644 +------------
645 +
646 +`"error"`::
647 + This event is emitted when one of the `error()`, `die()`,
648 + or `usage()` functions are called.
649 ++
650 +------------
651 +{
652 + "event":"error",
653 + ...
654 + "msg":"invalid option: --cahced", # formatted error message
655 + "fmt":"invalid option: %s" # error format string
656 +}
657 +------------
658 ++
659 +The error event may be emitted more than once. The format string
660 +allows post-processors to group errors by type without worrying
661 +about specific error arguments.
662 +
663 +`"cmd_path"`::
664 + This event contains the discovered full path of the git
665 + executable (on platforms that are configured to resolve it).
666 ++
667 +------------
668 +{
669 + "event":"cmd_path",
670 + ...
671 + "path":"C:/work/gfw/git.exe"
672 +}
673 +------------
674 +
675 +`"cmd_name"`::
676 + This event contains the command name for this git process
677 + and the hierarchy of commands from parent git processes.
678 ++
679 +------------
680 +{
681 + "event":"cmd_name",
682 + ...
683 + "name":"pack-objects",
684 + "hierarchy":"push/pack-objects"
685 +}
686 +------------
687 ++
688 +Normally, the "name" field contains the canonical name of the
689 +command. When a canonical name is not available, one of
690 +these special values are used:
691 ++
692 +------------
693 +"_query_" # "git --html-path"
694 +"_run_dashed_" # when "git foo" tries to run "git-foo"
695 +"_run_shell_alias_" # alias expansion to a shell command
696 +"_run_git_alias_" # alias expansion to a git command
697 +"_usage_" # usage error
698 +------------
699 +
700 +`"cmd_mode"`::
701 + This event, when present, describes the command variant This
702 + event may be emitted more than once.
703 ++
704 +------------
705 +{
706 + "event":"cmd_mode",
707 + ...
708 + "name":"branch"
709 +}
710 +------------
711 ++
712 +The "name" field is an arbitrary string to describe the command mode.
713 +For example, checkout can checkout a branch or an individual file.
714 +And these variations typically have different performance
715 +characteristics that are not comparable.
716 +
717 +`"alias"`::
718 + This event is present when an alias is expanded.
719 ++
720 +------------
721 +{
722 + "event":"alias",
723 + ...
724 + "alias":"l", # registered alias
725 + "argv":["log","--graph"] # alias expansion
726 +}
727 +------------
728 +
729 +`"child_start"`::
730 + This event describes a child process that is about to be
731 + spawned.
732 ++
733 +------------
734 +{
735 + "event":"child_start",
736 + ...
737 + "child_id":2,
738 + "child_class":"?",
739 + "use_shell":false,
740 + "argv":["git","rev-list","--objects","--stdin","--not","--all","--quiet"]
741 +
742 + "hook_name":"<hook_name>" # present when child_class is "hook"
743 + "cd":"<path>" # present when cd is required
744 +}
745 +------------
746 ++
747 +The "child_id" field can be used to match this child_start with the
748 +corresponding child_exit event.
749 ++
750 +The "child_class" field is a rough classification, such as "editor",
751 +"pager", "transport/*", and "hook". Unclassified children are classified
752 +with "?".
753 +
754 +`"child_exit"`::
755 + This event is generated after the current process has returned
756 + from the waitpid() and collected the exit information from the
757 + child.
758 ++
759 +------------
760 +{
761 + "event":"child_exit",
762 + ...
763 + "child_id":2,
764 + "pid":14708, # child PID
765 + "code":0, # child exit-code
766 + "t_rel":0.110605 # observed run-time of child process
767 +}
768 +------------
769 ++
770 +Note that the session-id of the child process is not available to
771 +the current/spawning process, so the child's PID is reported here as
772 +a hint for post-processing. (But it is only a hint because the child
773 +proces may be a shell script which doesn't have a session-id.)
774 ++
775 +Note that the `t_rel` field contains the observed run time in seconds
776 +for the child process (starting before the fork/exec/spawn and
777 +stopping after the waitpid() and includes OS process creation overhead).
778 +So this time will be slightly larger than the atexit time reported by
779 +the child process itself.
780 +
781 +`"exec"`::
782 + This event is generated before git attempts to `exec()`
783 + another command rather than starting a child process.
784 ++
785 +------------
786 +{
787 + "event":"exec",
788 + ...
789 + "exec_id":0,
790 + "exe":"git",
791 + "argv":["foo", "bar"]
792 +}
793 +------------
794 ++
795 +The "exec_id" field is a command-unique id and is only useful if the
796 +`exec()` fails and a corresponding exec_result event is generated.
797 +
798 +`"exec_result"`::
799 + This event is generated if the `exec()` fails and control
800 + returns to the current git command.
801 ++
802 +------------
803 +{
804 + "event":"exec_result",
805 + ...
806 + "exec_id":0,
807 + "code":1 # error code (errno) from exec()
808 +}
809 +------------
810 +
811 +`"thread_start"`::
812 + This event is generated when a thread is started. It is
813 + generated from *within* the new thread's thread-proc (for TLS
814 + reasons).
815 ++
816 +------------
817 +{
818 + "event":"thread_start",
819 + ...
820 + "thread":"th02:preload_thread" # thread name
821 +}
822 +------------
823 +
824 +`"thread_exit"`::
825 + This event is generated when a thread exits. It is generated
826 + from *within* the thread's thread-proc (for TLS reasons).
827 ++
828 +------------
829 +{
830 + "event":"thread_exit",
831 + ...
832 + "thread":"th02:preload_thread", # thread name
833 + "t_rel":0.007328 # thread elapsed time
834 +}
835 +------------
836 +
837 +`"def_param"`::
838 + This event is generated to log a global parameter.
839 ++
840 +------------
841 +{
842 + "event":"def_param",
843 + ...
844 + "param":"core.abbrev",
845 + "value":"7"
846 +}
847 +------------
848 +
849 +`"def_repo"`::
850 + This event defines a repo-id and associates it with the root
851 + of the worktree.
852 ++
853 +------------
854 +{
855 + "event":"def_repo",
856 + ...
857 + "repo":1,
858 + "worktree":"/Users/jeffhost/work/gfw"
859 +}
860 +------------
861 ++
862 +As stated earlier, the repo-id is currently always 1, so there will
863 +only be one def_repo event. Later, if in-proc submodules are
864 +supported, a def_repo event should be emitted for each submodule
865 +visited.
866 +
867 +`"region_enter"`::
868 + This event is generated when entering a region.
869 ++
870 +------------
871 +{
872 + "event":"region_enter",
873 + ...
874 + "repo":1, # optional
875 + "nesting":1, # current region stack depth
876 + "category":"index", # optional
877 + "label":"do_read_index", # optional
878 + "msg":".git/index" # optional
879 +}
880 +------------
881 ++
882 +The `category` field may be used in a future enhancement to
883 +do category-based filtering.
884 ++
885 +The `GIT_TR2_EVENT_NESTING` environment variable can be used to
886 +filter deeply nested regions and data events. It defaults to "2".
887 +
888 +`"region_leave"`::
889 + This event is generated when leaving a region.
890 ++
891 +------------
892 +{
893 + "event":"region_leave",
894 + ...
895 + "repo":1, # optional
896 + "t_rel":0.002876, # time spent in region in seconds
897 + "nesting":1, # region stack depth
898 + "category":"index", # optional
899 + "label":"do_read_index", # optional
900 + "msg":".git/index" # optional
901 +}
902 +------------
903 +
904 +`"data"`::
905 + This event is generated to log a thread- and region-local
906 + key/value pair.
907 ++
908 +------------
909 +{
910 + "event":"data",
911 + ...
912 + "repo":1, # optional
913 + "t_abs":0.024107, # absolute elapsed time
914 + "t_rel":0.001031, # elapsed time in region/thread
915 + "nesting":2, # region stack depth
916 + "category":"index",
917 + "key":"read/cache_nr",
918 + "value":"3552"
919 +}
920 +------------
921 ++
922 +The "value" field may be an integer or a string.
923 +
924 +`"data-json"`::
925 + This event is generated to log a pre-formatted JSON string
926 + containing structured data.
927 ++
928 +------------
929 +{
930 + "event":"data_json",
931 + ...
932 + "repo":1, # optional
933 + "t_abs":0.015905,
934 + "t_rel":0.015905,
935 + "nesting":1,
936 + "category":"process",
937 + "key":"windows/ancestry",
938 + "value":["bash.exe","bash.exe"]
939 +}
940 +------------
941 +
942 +== Example Trace2 API Usage
943 +
944 +Here is a hypothetical usage of the Trace2 API showing the intended
945 +usage (without worrying about the actual Git details).
946 +
947 +Initialization::
948 +
949 + Initialization happens in `main()`. Behind the scenes, an
950 + `atexit` and `signal` handler are registered.
951 ++
952 +----------------
953 +int main(int argc, const char **argv)
954 +{
955 + int exit_code;
956 +
957 + trace2_initialize();
958 + trace2_cmd_start(argv);
959 +
960 + exit_code = cmd_main(argc, argv);
961 +
962 + trace2_cmd_exit(exit_code);
963 +
964 + return exit_code;
965 +}
966 +----------------
967 +
968 +Command Details::
969 +
970 + After the basics are established, additional command
971 + information can be sent to Trace2 as it is discovered.
972 ++
973 +----------------
974 +int cmd_checkout(int argc, const char **argv)
975 +{
976 + trace2_cmd_name("checkout");
977 + trace2_cmd_mode("branch");
978 + trace2_def_repo(the_repository);
979 +
980 + // emit "def_param" messages for "interesting" config settings.
981 + trace2_cmd_list_config();
982 +
983 + if (do_something())
984 + trace2_cmd_error("Path '%s': cannot do something", path);
985 +
986 + return 0;
987 +}
988 +----------------
989 +
990 +Child Processes::
991 +
992 + Wrap code spawning child processes.
993 ++
994 +----------------
995 +void run_child(...)
996 +{
997 + int child_exit_code;
998 + struct child_process cmd = CHILD_PROCESS_INIT;
999 + ...
1000 + cmd.trace2_child_class = "editor";
1001 +
1002 + trace2_child_start(&cmd);
1003 + child_exit_code = spawn_child_and_wait_for_it();
1004 + trace2_child_exit(&cmd, child_exit_code);
1005 +}
1006 +----------------
1007 ++
1008 +For example, the following fetch command spawned ssh, index-pack,
1009 +rev-list, and gc. This example also shows that fetch took
1010 +5.199 seconds and of that 4.932 was in ssh.
1011 ++
1012 +----------------
1013 +$ export GIT_TR2_BRIEF=1
1014 +$ export GIT_TR2=~/log.normal
1015 +$ git fetch origin
1016 +...
1017 +----------------
1018 ++
1019 +----------------
1020 +$ cat ~/log.normal
1021 +version 2.20.1.vfs.1.1.47.g534dbe1ad1
1022 +start git fetch origin
1023 +worktree /Users/jeffhost/work/gfw
1024 +cmd_name fetch (fetch)
1025 +child_start[0] ssh git@github.com ...
1026 +child_start[1] git index-pack ...
1027 +... (Trace2 events from child processes omitted)
1028 +child_exit[1] pid:14707 code:0 elapsed:0.076353
1029 +child_exit[0] pid:14706 code:0 elapsed:4.931869
1030 +child_start[2] git rev-list ...
1031 +... (Trace2 events from child process omitted)
1032 +child_exit[2] pid:14708 code:0 elapsed:0.110605
1033 +child_start[3] git gc --auto
1034 +... (Trace2 events from child process omitted)
1035 +child_exit[3] pid:14709 code:0 elapsed:0.006240
1036 +exit elapsed:5.198503 code:0
1037 +atexit elapsed:5.198541 code:0
1038 +----------------
1039 ++
1040 +When a git process is a (direct or indirect) child of another
1041 +git process, it inherits Trace2 context information. This
1042 +allows the child to print the command hierarchy. This example
1043 +shows gc as child[3] of fetch. When the gc process reports
1044 +its name as "gc", it also reports the hierarchy as "fetch/gc".
1045 +(In this example, trace2 messages from the child process is
1046 +indented for clarity.)
1047 ++
1048 +----------------
1049 +$ export GIT_TR2_BRIEF=1
1050 +$ export GIT_TR2=~/log.normal
1051 +$ git fetch origin
1052 +...
1053 +----------------
1054 ++
1055 +----------------
1056 +$ cat ~/log.normal
1057 +version 2.20.1.160.g5676107ecd.dirty
1058 +start git fetch official
1059 +worktree /Users/jeffhost/work/gfw
1060 +cmd_name fetch (fetch)
1061 +...
1062 +child_start[3] git gc --auto
1063 + version 2.20.1.160.g5676107ecd.dirty
1064 + start /Users/jeffhost/work/gfw/git gc --auto
1065 + worktree /Users/jeffhost/work/gfw
1066 + cmd_name gc (fetch/gc)
1067 + exit elapsed:0.001959 code:0
1068 + atexit elapsed:0.001997 code:0
1069 +child_exit[3] pid:20303 code:0 elapsed:0.007564
1070 +exit elapsed:3.868938 code:0
1071 +atexit elapsed:3.868970 code:0
1072 +----------------
1073 +
1074 +Regions::
1075 +
1076 + Regions can be use to time an interesting section of code.
1077 ++
1078 +----------------
1079 +void wt_status_collect(struct wt_status *s)
1080 +{
1081 + trace2_region_enter("status", "worktrees", s->repo);
1082 + wt_status_collect_changes_worktree(s);
1083 + trace2_region_leave("status", "worktrees", s->repo);
1084 +
1085 + trace2_region_enter("status", "index", s->repo);
1086 + wt_status_collect_changes_index(s);
1087 + trace2_region_leave("status", "index", s->repo);
1088 +
1089 + trace2_region_enter("status", "untracked", s->repo);
1090 + wt_status_collect_untracked(s);
1091 + trace2_region_leave("status", "untracked", s->repo);
1092 +}
1093 +
1094 +void wt_status_print(struct wt_status *s)
1095 +{
1096 + trace2_region_enter("status", "print", s->repo);
1097 + switch (s->status_format) {
1098 + ...
1099 + }
1100 + trace2_region_leave("status", "print", s->repo);
1101 +}
1102 +----------------
1103 ++
1104 +In this example, scanning for untracked files ran from +0.012568 to
1105 ++0.027149 (since the process started) and took 0.014581 seconds.
1106 ++
1107 +----------------
1108 +$ export GIT_TR2_PERF_BRIEF=1
1109 +$ export GIT_TR2_PERF=~/log.perf
1110 +$ git status
1111 +...
1112 +
1113 +$ cat ~/log.perf
1114 +d0 | main | version | | | | | 2.20.1.160.g5676107ecd.dirty
1115 +d0 | main | start | | | | | git status
1116 +d0 | main | def_repo | r1 | | | | worktree:/Users/jeffhost/work/gfw
1117 +d0 | main | cmd_name | | | | | status (status)
1118 +...
1119 +d0 | main | region_enter | r1 | 0.010988 | | status | label:worktrees
1120 +d0 | main | region_leave | r1 | 0.011236 | 0.000248 | status | label:worktrees
1121 +d0 | main | region_enter | r1 | 0.011260 | | status | label:index
1122 +d0 | main | region_leave | r1 | 0.012542 | 0.001282 | status | label:index
1123 +d0 | main | region_enter | r1 | 0.012568 | | status | label:untracked
1124 +d0 | main | region_leave | r1 | 0.027149 | 0.014581 | status | label:untracked
1125 +d0 | main | region_enter | r1 | 0.027411 | | status | label:print
1126 +d0 | main | region_leave | r1 | 0.028741 | 0.001330 | status | label:print
1127 +d0 | main | exit | | 0.028778 | | | code:0
1128 +d0 | main | atexit | | 0.028809 | | | code:0
1129 +----------------
1130 ++
1131 +Regions may be nested. This causes messages to be indented in the
1132 +PERF target, for example.
1133 +Elapsed times are relative to the start of the correpsonding nesting
1134 +level as expected. For example, if we add region message to:
1135 ++
1136 +----------------
1137 +static enum path_treatment read_directory_recursive(struct dir_struct *dir,
1138 + struct index_state *istate, const char *base, int baselen,
1139 + struct untracked_cache_dir *untracked, int check_only,
1140 + int stop_at_first_file, const struct pathspec *pathspec)
1141 +{
1142 + enum path_treatment state, subdir_state, dir_state = path_none;
1143 +
1144 + trace2_region_enter_printf("dir", "read_recursive", NULL, "%.*s", baselen, base);
1145 + ...
1146 + trace2_region_leave_printf("dir", "read_recursive", NULL, "%.*s", baselen, base);
1147 + return dir_state;
1148 +}
1149 +----------------
1150 ++
1151 +We can further investigate the time spent scanning for untracked files.
1152 ++
1153 +----------------
1154 +$ export GIT_TR2_PERF_BRIEF=1
1155 +$ export GIT_TR2_PERF=~/log.perf
1156 +$ git status
1157 +...
1158 +$ cat ~/log.perf
1159 +d0 | main | version | | | | | 2.20.1.162.gb4ccea44db.dirty
1160 +d0 | main | start | | | | | git status
1161 +d0 | main | def_repo | r1 | | | | worktree:/Users/jeffhost/work/gfw
1162 +d0 | main | cmd_name | | | | | status (status)
1163 +...
1164 +d0 | main | region_enter | r1 | 0.015047 | | status | label:untracked
1165 +d0 | main | region_enter | | 0.015132 | | dir | ..label:read_recursive
1166 +d0 | main | region_enter | | 0.016341 | | dir | ....label:read_recursive vcs-svn/
1167 +d0 | main | region_leave | | 0.016422 | 0.000081 | dir | ....label:read_recursive vcs-svn/
1168 +d0 | main | region_enter | | 0.016446 | | dir | ....label:read_recursive xdiff/
1169 +d0 | main | region_leave | | 0.016522 | 0.000076 | dir | ....label:read_recursive xdiff/
1170 +d0 | main | region_enter | | 0.016612 | | dir | ....label:read_recursive git-gui/
1171 +d0 | main | region_enter | | 0.016698 | | dir | ......label:read_recursive git-gui/po/
1172 +d0 | main | region_enter | | 0.016810 | | dir | ........label:read_recursive git-gui/po/glossary/
1173 +d0 | main | region_leave | | 0.016863 | 0.000053 | dir | ........label:read_recursive git-gui/po/glossary/
1174 +...
1175 +d0 | main | region_enter | | 0.031876 | | dir | ....label:read_recursive builtin/
1176 +d0 | main | region_leave | | 0.032270 | 0.000394 | dir | ....label:read_recursive builtin/
1177 +d0 | main | region_leave | | 0.032414 | 0.017282 | dir | ..label:read_recursive
1178 +d0 | main | region_leave | r1 | 0.032454 | 0.017407 | status | label:untracked
1179 +...
1180 +d0 | main | exit | | 0.034279 | | | code:0
1181 +d0 | main | atexit | | 0.034322 | | | code:0
1182 +----------------
1183 ++
1184 +Trace2 regions are similar to the existing trace_performance_enter()
1185 +and trace_performance_leave() routines, but are thread safe and
1186 +maintain per-thread stacks of timers.
1187 +
1188 +Data Messages::
1189 +
1190 + Data messages added to a region.
1191 ++
1192 +----------------
1193 +int read_index_from(struct index_state *istate, const char *path,
1194 + const char *gitdir)
1195 +{
1196 + trace2_region_enter_printf("index", "do_read_index", the_repository, "%s", path);
1197 +
1198 + ...
1199 +
1200 + trace2_data_intmax("index", the_repository, "read/version", istate->version);
1201 + trace2_data_intmax("index", the_repository, "read/cache_nr", istate->cache_nr);
1202 +
1203 + trace2_region_leave_printf("index", "do_read_index", the_repository, "%s", path);
1204 +}
1205 +----------------
1206 ++
1207 +This example shows that the index contained 3552 entries.
1208 ++
1209 +----------------
1210 +$ export GIT_TR2_PERF_BRIEF=1
1211 +$ export GIT_TR2_PERF=~/log.perf
1212 +$ git status
1213 +...
1214 +$ cat ~/log.perf
1215 +d0 | main | version | | | | | 2.20.1.156.gf9916ae094.dirty
1216 +d0 | main | start | | | | | git status
1217 +d0 | main | def_repo | r1 | | | | worktree:/Users/jeffhost/work/gfw
1218 +d0 | main | cmd_name | | | | | status (status)
1219 +d0 | main | region_enter | r1 | 0.001791 | | index | label:do_read_index .git/index
1220 +d0 | main | data | r1 | 0.002494 | 0.000703 | index | ..read/version:2
1221 +d0 | main | data | r1 | 0.002520 | 0.000729 | index | ..read/cache_nr:3552
1222 +d0 | main | region_leave | r1 | 0.002539 | 0.000748 | index | label:do_read_index .git/index
1223 +...
1224 +----------------
1225 +
1226 +Thread Events::
1227 +
1228 + Thread messages added to a thread-proc.
1229 ++
1230 +For example, the multithreaded preload-index code can be
1231 +instrumented with a region around the thread pool and then
1232 +per-thread start and exit events within the threadproc.
1233 ++
1234 +----------------
1235 +static void *preload_thread(void *_data)
1236 +{
1237 + // start the per-thread clock and emit a message.
1238 + trace2_thread_start("preload_thread");
1239 +
1240 + // report which chunk of the array this thread was assigned.
1241 + trace2_data_intmax("index", the_repository, "offset", p->offset);
1242 + trace2_data_intmax("index", the_repository, "count", nr);
1243 +
1244 + do {
1245 + ...
1246 + } while (--nr > 0);
1247 + ...
1248 +
1249 + // report elapsed time taken by this thread.
1250 + trace2_thread_exit();
1251 + return NULL;
1252 +}
1253 +
1254 +void preload_index(struct index_state *index,
1255 + const struct pathspec *pathspec,
1256 + unsigned int refresh_flags)
1257 +{
1258 + trace2_region_enter("index", "preload", the_repository);
1259 +
1260 + for (i = 0; i < threads; i++) {
1261 + ... /* create thread */
1262 + }
1263 +
1264 + for (i = 0; i < threads; i++) {
1265 + ... /* join thread */
1266 + }
1267 +
1268 + trace2_region_leave("index", "preload", the_repository);
1269 +}
1270 +----------------
1271 ++
1272 +In this example preload_index() was executed by the `main` thread
1273 +and started the `preload` region. Seven threads, named
1274 +`th01:preload_thread` through `th07:preload_thread`, were started.
1275 +Events from each thread are atomically appended to the shared target
1276 +stream as they occur so they may appear in random order with respect
1277 +other threads. Finally, the main thread waits for the threads to
1278 +finish and leaves the region.
1279 ++
1280 +Data events are tagged with the active thread name. They are used
1281 +to report the per-thread parameters.
1282 ++
1283 +----------------
1284 +$ export GIT_TR2_PERF_BRIEF=1
1285 +$ export GIT_TR2_PERF=~/log.perf
1286 +$ git status
1287 +...
1288 +$ cat ~/log.perf
1289 +...
1290 +d0 | main | region_enter | r1 | 0.002595 | | index | label:preload
1291 +d0 | th01:preload_thread | thread_start | | 0.002699 | | |
1292 +d0 | th02:preload_thread | thread_start | | 0.002721 | | |
1293 +d0 | th01:preload_thread | data | r1 | 0.002736 | 0.000037 | index | offset:0
1294 +d0 | th02:preload_thread | data | r1 | 0.002751 | 0.000030 | index | offset:2032
1295 +d0 | th03:preload_thread | thread_start | | 0.002711 | | |
1296 +d0 | th06:preload_thread | thread_start | | 0.002739 | | |
1297 +d0 | th01:preload_thread | data | r1 | 0.002766 | 0.000067 | index | count:508
1298 +d0 | th06:preload_thread | data | r1 | 0.002856 | 0.000117 | index | offset:2540
1299 +d0 | th03:preload_thread | data | r1 | 0.002824 | 0.000113 | index | offset:1016
1300 +d0 | th04:preload_thread | thread_start | | 0.002710 | | |
1301 +d0 | th02:preload_thread | data | r1 | 0.002779 | 0.000058 | index | count:508
1302 +d0 | th06:preload_thread | data | r1 | 0.002966 | 0.000227 | index | count:508
1303 +d0 | th07:preload_thread | thread_start | | 0.002741 | | |
1304 +d0 | th07:preload_thread | data | r1 | 0.003017 | 0.000276 | index | offset:3048
1305 +d0 | th05:preload_thread | thread_start | | 0.002712 | | |
1306 +d0 | th05:preload_thread | data | r1 | 0.003067 | 0.000355 | index | offset:1524
1307 +d0 | th05:preload_thread | data | r1 | 0.003090 | 0.000378 | index | count:508
1308 +d0 | th07:preload_thread | data | r1 | 0.003037 | 0.000296 | index | count:504
1309 +d0 | th03:preload_thread | data | r1 | 0.002971 | 0.000260 | index | count:508
1310 +d0 | th04:preload_thread | data | r1 | 0.002983 | 0.000273 | index | offset:508
1311 +d0 | th04:preload_thread | data | r1 | 0.007311 | 0.004601 | index | count:508
1312 +d0 | th05:preload_thread | thread_exit | | 0.008781 | 0.006069 | |
1313 +d0 | th01:preload_thread | thread_exit | | 0.009561 | 0.006862 | |
1314 +d0 | th03:preload_thread | thread_exit | | 0.009742 | 0.007031 | |
1315 +d0 | th06:preload_thread | thread_exit | | 0.009820 | 0.007081 | |
1316 +d0 | th02:preload_thread | thread_exit | | 0.010274 | 0.007553 | |
1317 +d0 | th07:preload_thread | thread_exit | | 0.010477 | 0.007736 | |
1318 +d0 | th04:preload_thread | thread_exit | | 0.011657 | 0.008947 | |
1319 +d0 | main | region_leave | r1 | 0.011717 | 0.009122 | index | label:preload
1320 +...
1321 +d0 | main | exit | | 0.029996 | | | code:0
1322 +d0 | main | atexit | | 0.030027 | | | code:0
1323 +----------------
1324 ++
1325 +In this example, the preload region took 0.009122 seconds. The 7 threads
1326 +took between 0.006069 and 0.008947 seconds to work on their portion of
1327 +the index. Thread "th01" worked on 508 items at offset 0. Thread "th02"
1328 +worked on 508 items at offset 2032. Thread "th04" worked on 508 itemts
1329 +at offset 508.
1330 ++
1331 +This example also shows that thread names are assigned in a racy manner
1332 +as each thread starts and allocates TLS storage.
1333 +
1334 +== Future Work
1335 +
1336 +=== Relationship to the Existing Trace Api (api-trace.txt)
1337 +
1338 +There are a few issues to resolve before we can completely
1339 +switch to Trace2.
1340 +
1341 +* Updating existing tests that assume GIT_TRACE format messages.
1342 +
1343 +* How to best handle custom GIT_TRACE_<key> messages?
1344 +
1345 +** The GIT_TRACE_<key> mechanism allows each <key> to write to a
1346 +different file (in addition to just stderr).
1347 +
1348 +** Do we want to maintain that ability or simply write to the existing
1349 +Trace2 targets (and convert <key> to a "category").