ipc: fix spelling in log and comment
[dpdk.git] / lib / librte_eal / common / eal_common_trace_ctf.c
index 5ad44cc..9dc91df 100644 (file)
@@ -83,6 +83,11 @@ meta_data_type_emit(char **meta, int *offset)
                "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"
@@ -215,12 +220,131 @@ meta_stream_emit(char **meta, int *offset)
        return meta_copy(meta, offset, str, rc);
 }
 
+static void
+string_fixed_replace(char *input, const char *search, const char *replace)
+{
+       char *found;
+       size_t len;
+
+       found = strstr(input, search);
+       if (found == NULL)
+               return;
+
+       if (strlen(found) != strlen(search))
+               return;
+
+       len = strlen(replace);
+       memcpy(found, replace, len);
+       found[len] = '\0';
+}
+
+static void
+ctf_fixup_align(char *str)
+{
+       string_fixed_replace(str, "align", "_align");
+}
+
+static void
+ctf_fixup_arrow_deref(char *str)
+{
+       const char *replace = "_";
+       const char *search = "->";
+       char *found;
+       size_t len;
+
+       found = strstr(str, search);
+       if (found == NULL)
+               return;
+
+       do {
+               memcpy(found, replace, strlen(replace));
+               len = strlen(found + 2);
+               memcpy(found + 1, found + 2, len);
+               found[len + 1] = '\0';
+               found = strstr(str, search);
+       } while (found != NULL);
+}
+
+static void
+ctf_fixup_dot_deref(char *str)
+{
+       const char *replace = "_";
+       const char *search = ".";
+       char *found;
+       size_t len;
+
+       found = strstr(str, search);
+       if (found == NULL)
+               return;
+
+       len = strlen(replace);
+       do {
+               memcpy(found, replace, len);
+               found = strstr(str, search);
+       } while (found != NULL);
+}
+
+static void
+ctf_fixup_event(char *str)
+{
+       string_fixed_replace(str, "event", "_event");
+}
+
+static int
+ctf_fixup_keyword(char *str)
+{
+       char dup_str[TRACE_CTF_FIELD_SIZE];
+       char input[TRACE_CTF_FIELD_SIZE];
+       const char *delim = ";";
+       char *from;
+       int len;
+
+       if (str == NULL)
+               return 0;
+
+       len = strlen(str);
+       if (len >= TRACE_CTF_FIELD_SIZE) {
+               trace_err("ctf_field reached its maximum limit");
+               return -EMSGSIZE;
+       }
+
+       /* Create duplicate string */
+       strcpy(dup_str, str);
+
+       len = 0;
+       from = strtok(dup_str, delim);
+       while (from != NULL) {
+               strcpy(input, from);
+               ctf_fixup_align(input);
+               ctf_fixup_dot_deref(input);
+               ctf_fixup_arrow_deref(input);
+               ctf_fixup_event(input);
+
+               strcpy(&input[strlen(input)], delim);
+               if ((len + strlen(input)) >= TRACE_CTF_FIELD_SIZE) {
+                       trace_err("ctf_field reached its maximum limit");
+                       return -EMSGSIZE;
+               }
+
+               strcpy(str + len, input);
+               len += strlen(input);
+               from = strtok(NULL, delim);
+       }
+
+       return 0;
+}
+
 static int
 meta_event_emit(char **meta, int *offset, struct trace_point *tp)
 {
        char *str = NULL;
        int rc;
 
+       /* Fixup ctf field string in case it using reserved ctf keywords */
+       rc = ctf_fixup_keyword(tp->ctf_field);
+       if (rc)
+               return rc;
+
        rc = metadata_printf(&str,
                "event {\n"
                "    id = %d;\n"
@@ -300,3 +424,70 @@ trace_metadata_destroy(void)
        }
 }
 
+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;
+}