8
#include "version.h"
9
#include "trace2/tr2_cfg.h"
10
#include "trace2/tr2_cmd_name.h"
11
+#include "trace2/tr2_ctr.h"
12
#include "trace2/tr2_dst.h"
13
#include "trace2/tr2_sid.h"
14
#include "trace2/tr2_sysenv.h"
102
tgt_j->pfn_timer(meta, timer, is_final_data);
103
}
104
105
+/*
106
+ * The signature of this function must match the pfn_counter
107
+ * method in the targets.
108
+ */
109
+static void tr2_tgt_emit_a_counter(const struct tr2_counter_metadata *meta,
110
+ const struct tr2_counter *counter,
111
+ int is_final_data)
112
+{
113
+ struct tr2_tgt *tgt_j;
114
+ int j;
115
+
116
+ for_each_wanted_builtin (j, tgt_j)
117
+ if (tgt_j->pfn_counter)
118
+ tgt_j->pfn_counter(meta, counter, is_final_data);
119
+}
120
+
121
static int tr2main_exit_code;
122
123
/*
149
* Some timers want per-thread details. If the main thread
150
* used one of those timers, emit the details now (before
151
* we emit the aggregate timer values).
152
+ *
153
+ * Likewise for counters.
154
*/
155
tr2_emit_per_thread_timers(tr2_tgt_emit_a_timer);
156
+ tr2_emit_per_thread_counters(tr2_tgt_emit_a_counter);
157
158
/*
139
- * Add stopwatch timer data for the main thread to the final
140
- * totals. And then emit the final timer values.
159
+ * Add stopwatch timer and counter data for the main thread to
160
+ * the final totals. And then emit the final values.
161
*
162
* Technically, we shouldn't need to hold the lock to update
143
- * and output the final_timer_block (since all other threads
144
- * should be dead by now), but it doesn't hurt anything.
163
+ * and output the final_timer_block and final_counter_block
164
+ * (since all other threads should be dead by now), but it
165
+ * doesn't hurt anything.
166
*/
167
tr2tls_lock();
168
tr2_update_final_timers();
169
+ tr2_update_final_counters();
170
tr2_emit_final_timers(tr2_tgt_emit_a_timer);
171
+ tr2_emit_final_counters(tr2_tgt_emit_a_counter);
172
tr2tls_unlock();
173
174
for_each_wanted_builtin (j, tgt_j)
605
/*
606
* Some timers want per-thread details. If this thread used
607
* one of those timers, emit the details now.
608
+ *
609
+ * Likewise for counters.
610
*/
611
tr2_emit_per_thread_timers(tr2_tgt_emit_a_timer);
612
+ tr2_emit_per_thread_counters(tr2_tgt_emit_a_counter);
613
614
/*
589
- * Add stopwatch timer data from the current (non-main) thread
590
- * to the final totals. (We'll accumulate data for the main
591
- * thread later during "atexit".)
615
+ * Add stopwatch timer and counter data from the current
616
+ * (non-main) thread to the final totals. (We'll accumulate
617
+ * data for the main thread later during "atexit".)
618
*/
619
tr2tls_lock();
620
tr2_update_final_timers();
621
+ tr2_update_final_counters();
622
tr2tls_unlock();
623
624
for_each_wanted_builtin (j, tgt_j)
897
tr2_stop_timer(tid);
898
}
899
900
+void trace2_counter_add(enum trace2_counter_id cid, uint64_t value)
901
+{
902
+ if (!trace2_enabled)
903
+ return;
904
+
905
+ if (cid < 0 || cid >= TRACE2_NUMBER_OF_COUNTERS)
906
+ BUG("trace2_counter_add: invalid counter id: %d", cid);
907
+
908
+ tr2_counter_increment(cid, value);
909
+}
910
+
911
const char *trace2_session_id(void)
912
{
913
return tr2_sid_get();