#include <limits.h>
#include <unistd.h>
#include <inttypes.h>
-#include <common/common.h>
-#include <common/time.h>
+#include <common/common.hpp>
+#include <common/time.hpp>
+#include <vector>
-#include "ust-registry.h"
-#include "ust-clock.h"
-#include "ust-app.h"
-
-#ifndef max_t
-#define max_t(type, a, b) ((type) ((a) > (b) ? (a) : (b)))
-#endif
+#include "ust-registry.hpp"
+#include "ust-clock.hpp"
+#include "ust-app.hpp"
#define NR_CLOCK_OFFSET_SAMPLES 10
+namespace {
struct offset_sample {
- int64_t offset; /* correlation offset */
- uint64_t measure_delta; /* lower is better */
+ /* correlation offset */
+ int64_t offset;
+ /* lower is better */
+ uint64_t measure_delta;
};
+} /* namespace */
static
int _lttng_field_statedump(struct ust_registry_session *session,
char *newptr;
new_alloc_len =
- max_t(size_t, 1U << get_count_order(new_alloc_len), old_alloc_len << 1);
+ std::max<size_t>(1U << get_count_order(new_alloc_len), old_alloc_len << 1);
newptr = (char *) realloc(session->metadata, new_alloc_len);
if (!newptr)
return -ENOMEM;
int ret;
char identifier[LTTNG_UST_ABI_SYM_NAME_LEN];
- if (variant->type.atype != lttng_ust_ctl_atype_variant) {
- ret = -EINVAL;
- goto end;
- }
(*iter_field)++;
sanitize_ctf_identifier(identifier, tag_name);
if (alignment) {
if (chan->chan_id == -1U)
return 0;
+ /*
+ * We don't want to output an event's metadata before its parent
+ * stream's metadata. If the stream's metadata hasn't been output yet,
+ * skip this event. Its metadata will be output when we output the
+ * stream's metadata.
+ */
+ if (!chan->metadata_dumped || event->metadata_dumped) {
+ return 0;
+ }
+
ret = lttng_metadata_printf(session,
"event {\n"
" name = \"%s\";\n"
/*
* Should be called with session registry mutex held.
+ *
+ * RCU read lock must be held by the caller.
*/
int ust_metadata_channel_statedump(struct ust_registry_session *session,
struct ust_registry_channel *chan)
{
- int ret = 0;
+ int ret;
+
+ ASSERT_RCU_READ_LOCKED();
/* Don't dump metadata events */
if (chan->chan_id == -1U)
"struct event_header_compact" :
"struct event_header_large");
if (ret) {
- goto end;
+ return ret;
}
if (chan->ctx_fields) {
ret = lttng_metadata_printf(session,
" event.context := struct {\n");
if (ret) {
- goto end;
+ return ret;
}
}
ret = _lttng_context_metadata_statedump(session,
chan->nr_ctx_fields,
chan->ctx_fields);
if (ret) {
- goto end;
+ return ret;
}
if (chan->ctx_fields) {
ret = lttng_metadata_printf(session,
" };\n");
if (ret) {
- goto end;
+ return ret;
}
}
ret = lttng_metadata_printf(session,
"};\n\n");
+ if (ret) {
+ return ret;
+ }
+
/* Flag success of metadata dump. */
chan->metadata_dumped = 1;
-end:
- return ret;
+ /*
+ * Output the metadata of any existing event.
+ *
+ * Sort the events by id. This is not necessary, but it's nice to have
+ * a more predictable order in the metadata file.
+ */
+ std::vector<ust_registry_event *> events;
+ {
+ cds_lfht_iter event_iter;
+ ust_registry_event *event;
+ cds_lfht_for_each_entry(chan->events->ht, &event_iter, event,
+ node.node) {
+ events.push_back(event);
+ }
+ }
+
+ std::sort(events.begin(), events.end(),
+ [] (ust_registry_event *a, ust_registry_event *b) {
+ return a->id < b->id;
+ });
+
+ for (ust_registry_event *event : events) {
+ ust_metadata_event_statedump(session, chan, event);
+ }
+
+ return 0;
}
static