Merge branch 'jk/refs-double-abort'
[git] / trace2 / tr2_sid.c
1 #include "cache.h"
2 #include "trace2/tr2_sid.h"
3
4 #define TR2_ENVVAR_PARENT_SID "GIT_TR2_PARENT_SID"
5
6 static struct strbuf tr2sid_buf = STRBUF_INIT;
7 static int tr2sid_nr_git_parents;
8
9 /*
10  * Compute a "unique" session id (SID) for the current process.  This allows
11  * all events from this process to have a single label (much like a PID).
12  *
13  * Export this into our environment so that all child processes inherit it.
14  *
15  * If we were started by another git instance, use our parent's SID as a
16  * prefix.  (This lets us track parent/child relationships even if there
17  * is an intermediate shell process.)
18  *
19  * Additionally, count the number of nested git processes.
20  */
21 static void tr2_sid_compute(void)
22 {
23         uint64_t us_now;
24         const char *parent_sid;
25
26         if (tr2sid_buf.len)
27                 return;
28
29         parent_sid = getenv(TR2_ENVVAR_PARENT_SID);
30         if (parent_sid && *parent_sid) {
31                 const char *p;
32                 for (p = parent_sid; *p; p++)
33                         if (*p == '/')
34                                 tr2sid_nr_git_parents++;
35
36                 strbuf_addstr(&tr2sid_buf, parent_sid);
37                 strbuf_addch(&tr2sid_buf, '/');
38                 tr2sid_nr_git_parents++;
39         }
40
41         us_now = getnanotime() / 1000;
42         strbuf_addf(&tr2sid_buf, "%" PRIuMAX "-%" PRIdMAX, (uintmax_t)us_now,
43                     (intmax_t)getpid());
44
45         setenv(TR2_ENVVAR_PARENT_SID, tr2sid_buf.buf, 1);
46 }
47
48 const char *tr2_sid_get(void)
49 {
50         if (!tr2sid_buf.len)
51                 tr2_sid_compute();
52
53         return tr2sid_buf.buf;
54 }
55
56 int tr2_sid_depth(void)
57 {
58         if (!tr2sid_buf.len)
59                 tr2_sid_compute();
60
61         return tr2sid_nr_git_parents;
62 }
63
64 void tr2_sid_release(void)
65 {
66         strbuf_release(&tr2sid_buf);
67 }