@@ -838,6 +838,25 @@ may exceed the "atexit" elapsed time of the program.
Timer events may represent an individual thread or a summation across
the entire program. Summation events will have a unique thread name.
+`"counter"`::
+ This event is generated at the end of the program and contains
+ the value of a global counter.
++
+------------
+{
+ "event":"counter",
+ ...
+ "name":"test", # counter name
+ "value":42, # value of the counter
+}
+------------
++
+A global counter can be incremented throughout the execution of the
+program. It will be reported in a "counter" event just prior to exit.
++
+Counter events may represent an individual thread or a summation across
+the entire program. Summation events will have a unique thread name.
+
== Example Trace2 API Usage
Here is a hypothetical usage of the Trace2 API showing the intended
@@ -120,6 +120,19 @@ typedef void(tr2_tgt_evt_timer_t)(uint64_t us_elapsed_absolute,
uint64_t ns_min_time,
uint64_t ns_max_time);
+/*
+ * Item counter event.
+ *
+ * This also does not take a (file,line) pair.
+ *
+ * The thread name is optional.
+ */
+typedef void(tr2_tgt_evt_counter_t)(uint64_t us_elapsed_absolute,
+ const char *thread_name,
+ const char *category,
+ const char *counter_name,
+ uint64_t value);
+
/*
* "vtable" for a TRACE2 target. Use NULL if a target does not want
* to emit that message.
@@ -157,6 +170,7 @@ struct tr2_tgt {
tr2_tgt_evt_data_json_fl_t *pfn_data_json_fl;
tr2_tgt_evt_printf_va_fl_t *pfn_printf_va_fl;
tr2_tgt_evt_timer_t *pfn_timer;
+ tr2_tgt_evt_counter_t *pfn_counter;
};
/* clang-format on */
@@ -643,6 +643,28 @@ static void fn_timer(uint64_t us_elapsed_absolute,
jw_release(&jw);
}
+static void fn_counter(uint64_t us_elapsed_absolute,
+ const char *thread_name,
+ const char *category,
+ const char *counter_name,
+ uint64_t value)
+{
+ const char *event_name = "counter";
+ 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, thread_name);
+ jw_object_double(&jw, "t_abs", 6, t_abs);
+ jw_object_string(&jw, "name", counter_name);
+ jw_object_intmax(&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,
@@ -675,4 +697,5 @@ struct tr2_tgt tr2_tgt_event = {
fn_data_json_fl,
NULL, /* printf */
fn_timer,
+ fn_counter,
};
@@ -356,4 +356,5 @@ struct tr2_tgt tr2_tgt_normal = {
NULL, /* data_json */
fn_printf_va_fl,
NULL, /* timer */
+ NULL, /* counter */
};
@@ -581,6 +581,23 @@ static void fn_timer(uint64_t us_elapsed_absolute,
strbuf_release(&buf_payload);
}
+static void fn_counter(uint64_t us_elapsed_absolute,
+ const char *thread_name,
+ const char *category,
+ const char *counter_name,
+ uint64_t value)
+{
+ const char *event_name = "counter";
+ struct strbuf buf_payload = STRBUF_INIT;
+
+ strbuf_addf(&buf_payload, "name:%s value:%"PRIu64, counter_name, value);
+
+ perf_io_write_fl(__FILE__, __LINE__, event_name, NULL,
+ &us_elapsed_absolute, NULL,
+ category, &buf_payload, thread_name);
+ strbuf_release(&buf_payload);
+}
+
struct tr2_tgt tr2_tgt_perf = {
&tr2dst_perf,
@@ -613,4 +630,5 @@ struct tr2_tgt tr2_tgt_perf = {
fn_data_json_fl,
fn_printf_va_fl,
fn_timer,
+ fn_counter,
};