]>
Commit | Line | Data |
---|---|---|
15db4e7f | 1 | #include "git-compat-util.h" |
81071626 JH |
2 | #include "thread-utils.h" |
3 | #include "trace2/tr2_tgt.h" | |
4 | #include "trace2/tr2_tls.h" | |
5 | #include "trace2/tr2_ctr.h" | |
6 | ||
7 | /* | |
8 | * A global counter block to aggregrate values from the partial sums | |
9 | * from each thread. | |
10 | */ | |
11 | static struct tr2_counter_block final_counter_block; /* access under tr2tls_mutex */ | |
12 | ||
13 | /* | |
14 | * Define metadata for each global counter. | |
15 | * | |
16 | * This array must match the "enum trace2_counter_id" and the values | |
17 | * in "struct tr2_counter_block.counter[*]". | |
18 | */ | |
19 | static struct tr2_counter_metadata tr2_counter_metadata[TRACE2_NUMBER_OF_COUNTERS] = { | |
20 | [TRACE2_COUNTER_ID_TEST1] = { | |
21 | .category = "test", | |
22 | .name = "test1", | |
23 | .want_per_thread_events = 0, | |
24 | }, | |
25 | [TRACE2_COUNTER_ID_TEST2] = { | |
26 | .category = "test", | |
27 | .name = "test2", | |
28 | .want_per_thread_events = 1, | |
29 | }, | |
c489f47a TB |
30 | [TRACE2_COUNTER_ID_PACKED_REFS_JUMPS] = { |
31 | .category = "packed-refs", | |
32 | .name = "jumps_made", | |
33 | .want_per_thread_events = 0, | |
34 | }, | |
a27eecea BB |
35 | [TRACE2_COUNTER_ID_FSYNC_WRITEOUT_ONLY] = { |
36 | .category = "fsync", | |
37 | .name = "writeout-only", | |
38 | .want_per_thread_events = 0, | |
39 | }, | |
40 | [TRACE2_COUNTER_ID_FSYNC_HARDWARE_FLUSH] = { | |
41 | .category = "fsync", | |
42 | .name = "hardware-flush", | |
43 | .want_per_thread_events = 0, | |
44 | }, | |
81071626 JH |
45 | |
46 | /* Add additional metadata before here. */ | |
47 | }; | |
48 | ||
49 | void tr2_counter_increment(enum trace2_counter_id cid, uint64_t value) | |
50 | { | |
51 | struct tr2tls_thread_ctx *ctx = tr2tls_get_self(); | |
52 | struct tr2_counter *c = &ctx->counter_block.counter[cid]; | |
53 | ||
54 | c->value += value; | |
55 | ||
56 | ctx->used_any_counter = 1; | |
57 | if (tr2_counter_metadata[cid].want_per_thread_events) | |
58 | ctx->used_any_per_thread_counter = 1; | |
59 | } | |
60 | ||
61 | void tr2_update_final_counters(void) | |
62 | { | |
63 | struct tr2tls_thread_ctx *ctx = tr2tls_get_self(); | |
64 | enum trace2_counter_id cid; | |
65 | ||
66 | if (!ctx->used_any_counter) | |
67 | return; | |
68 | ||
69 | /* | |
70 | * Access `final_counter_block` requires holding `tr2tls_mutex`. | |
71 | * We assume that our caller is holding the lock. | |
72 | */ | |
73 | ||
74 | for (cid = 0; cid < TRACE2_NUMBER_OF_COUNTERS; cid++) { | |
75 | struct tr2_counter *c_final = &final_counter_block.counter[cid]; | |
76 | const struct tr2_counter *c = &ctx->counter_block.counter[cid]; | |
77 | ||
78 | c_final->value += c->value; | |
79 | } | |
80 | } | |
81 | ||
82 | void tr2_emit_per_thread_counters(tr2_tgt_evt_counter_t *fn_apply) | |
83 | { | |
84 | struct tr2tls_thread_ctx *ctx = tr2tls_get_self(); | |
85 | enum trace2_counter_id cid; | |
86 | ||
87 | if (!ctx->used_any_per_thread_counter) | |
88 | return; | |
89 | ||
90 | /* | |
91 | * For each counter, if the counter wants per-thread events | |
92 | * and this thread used it (the value is non-zero), emit it. | |
93 | */ | |
94 | for (cid = 0; cid < TRACE2_NUMBER_OF_COUNTERS; cid++) | |
95 | if (tr2_counter_metadata[cid].want_per_thread_events && | |
96 | ctx->counter_block.counter[cid].value) | |
97 | fn_apply(&tr2_counter_metadata[cid], | |
98 | &ctx->counter_block.counter[cid], | |
99 | 0); | |
100 | } | |
101 | ||
102 | void tr2_emit_final_counters(tr2_tgt_evt_counter_t *fn_apply) | |
103 | { | |
104 | enum trace2_counter_id cid; | |
105 | ||
106 | /* | |
107 | * Access `final_counter_block` requires holding `tr2tls_mutex`. | |
108 | * We assume that our caller is holding the lock. | |
109 | */ | |
110 | ||
111 | for (cid = 0; cid < TRACE2_NUMBER_OF_COUNTERS; cid++) | |
112 | if (final_counter_block.counter[cid].value) | |
113 | fn_apply(&tr2_counter_metadata[cid], | |
114 | &final_counter_block.counter[cid], | |
115 | 1); | |
116 | } |