if (rc < 0)
return rc;
- ptr = realloc(ptr, count + rc);
+ ptr = realloc(ptr, count + rc + 1);
if (ptr == NULL)
goto free_str;
memcpy(RTE_PTR_ADD(ptr, count), str, rc);
+ ptr[count + rc] = '\0';
count += rc;
free(str);
"typealias integer {size = 32; base = x;} := long;\n"
#endif
"typealias integer {size = 8; signed = false; encoding = ASCII; } := string_bounded_t;\n\n"
+#ifdef RTE_ARCH_64
+ "typealias integer {size = 64; base = x;} := size_t;\n"
+#else
+ "typealias integer {size = 32; base = x;} := size_t;\n"
+#endif
"typealias floating_point {\n"
" exp_dig = 8;\n"
" mant_dig = 24;\n"
" id = %d;\n"
" name = \"%s\";\n"
" fields := struct {\n"
- " %s\n"
+ "%s"
" };\n"
- "};\n\n", trace_id_get(tp->handle), tp->name, tp->ctf_field);
+ "};\n\n", trace_id_get(tp->handle), tp->name,
+ tp->ctf_field != NULL ? tp->ctf_field : "");
return meta_copy(meta, offset, str, rc);
}
}
}
+static void
+meta_fix_freq(struct trace *trace, char *meta)
+{
+ char *str;
+ int rc;
+
+ str = RTE_PTR_ADD(meta, trace->ctf_meta_offset_freq);
+ rc = sprintf(str, "%20"PRIu64"", rte_get_timer_hz());
+ str[rc] = ';';
+}
+
+static void
+meta_fix_freq_offset(struct trace *trace, char *meta)
+{
+ uint64_t uptime_tickes_floor, uptime_ticks, freq, uptime_sec;
+ uint64_t offset, offset_s;
+ char *str;
+ int rc;
+
+ uptime_ticks = trace->uptime_ticks &
+ ((1ULL << __RTE_TRACE_EVENT_HEADER_ID_SHIFT) - 1);
+ freq = rte_get_tsc_hz();
+ uptime_tickes_floor = RTE_ALIGN_MUL_FLOOR(uptime_ticks, freq);
+
+ uptime_sec = uptime_tickes_floor / freq;
+ offset_s = trace->epoch_sec - uptime_sec;
+
+ offset = uptime_ticks - uptime_tickes_floor;
+ offset += trace->epoch_nsec * (freq / NSEC_PER_SEC);
+
+ str = RTE_PTR_ADD(meta, trace->ctf_meta_offset_freq_off_s);
+ rc = sprintf(str, "%20"PRIu64"", offset_s);
+ str[rc] = ';';
+ str = RTE_PTR_ADD(meta, trace->ctf_meta_offset_freq_off);
+ rc = sprintf(str, "%20"PRIu64"", offset);
+ str[rc] = ';';
+}
+
+static void
+meta_fixup(struct trace *trace, char *meta)
+{
+ meta_fix_freq(trace, meta);
+ meta_fix_freq_offset(trace, meta);
+}
+
+int
+rte_trace_metadata_dump(FILE *f)
+{
+ struct trace *trace = trace_obj_get();
+ char *ctf_meta = trace->ctf_meta;
+ int rc;
+
+ if (!rte_trace_is_enabled())
+ return 0;
+
+ if (ctf_meta == NULL)
+ return -EINVAL;
+
+ if (!__atomic_load_n(&trace->ctf_fixup_done, __ATOMIC_SEQ_CST) &&
+ rte_get_timer_hz()) {
+ meta_fixup(trace, ctf_meta);
+ __atomic_store_n(&trace->ctf_fixup_done, 1, __ATOMIC_SEQ_CST);
+ }
+
+ rc = fprintf(f, "%s", ctf_meta);
+ return rc < 0 ? rc : 0;
+}
+
+char *trace_metadata_fixup_field(const char *field)
+{
+ const char *ctf_reserved_words[] = {
+ "align",
+ "event",
+ };
+ unsigned int i;
+ char *out;
+ char *p;
+
+ /* reserved keywords */
+ for (i = 0; i < RTE_DIM(ctf_reserved_words); i++) {
+ if (strcmp(field, ctf_reserved_words[i]) != 0)
+ continue;
+ if (asprintf(&out, "_%s", ctf_reserved_words[i]) == -1)
+ out = NULL;
+ return out;
+ }
+
+ /* nothing to replace, return early */
+ if (strstr(field, ".") == NULL && strstr(field, "->") == NULL)
+ return NULL;
+
+ out = strdup(field);
+ if (out == NULL)
+ return NULL;
+ p = out;
+ while ((p = strstr(p, ".")) != NULL) {
+ p[0] = '_';
+ p++;
+ }
+ p = out;
+ while ((p = strstr(p, "->")) != NULL) {
+ p[0] = '_';
+ p++;
+ memmove(p, p + 1, strlen(p));
+ }
+ return out;
+}