Add metadata transport
[lttng-modules.git] / ltt-ring-buffer-client.h
index 219f69be239e67a41a025a90f80d1b055c7694b5..55d972ac18dbbd22d17806ae87162f596aa0b7d1 100644 (file)
 #include "ltt-events.h"
 #include "ltt-tracer.h"
 
+static inline notrace u64 lib_ring_buffer_clock_read(struct channel *chan)
+{
+       return trace_clock_read64();
+}
+
+/*
+ * record_header_size - Calculate the header size and padding necessary.
+ * @config: ring buffer instance configuration
+ * @chan: channel
+ * @offset: offset in the write buffer
+ * @data_size: size of the payload
+ * @pre_header_padding: padding to add before the header (output)
+ * @rflags: reservation flags
+ * @ctx: reservation context
+ *
+ * Returns the event header size (including padding).
+ *
+ * Important note :
+ * The event header must be 32-bits. The total offset calculated here :
+ *
+ * Alignment of header struct on 32 bits (min arch size, header size)
+ * + sizeof(header struct)  (32-bits)
+ * + (opt) u16 (ext. event id)
+ * + (opt) u16 (event_size)
+ *             (if event_size == LTT_MAX_SMALL_SIZE, has ext. event size)
+ * + (opt) u32 (ext. event size)
+ * + (opt) u64 full TSC (aligned on min(64-bits, arch size))
+ *
+ * The payload must itself determine its own alignment from the biggest type it
+ * contains.
+ */
+static __inline__
+unsigned char record_header_size(const struct lib_ring_buffer_config *config,
+                                struct channel *chan, size_t offset,
+                                size_t data_size, size_t *pre_header_padding,
+                                unsigned int rflags,
+                                struct lib_ring_buffer_ctx *ctx)
+{
+       size_t orig_offset = offset;
+       size_t padding;
+
+       BUILD_BUG_ON(sizeof(struct event_header) != sizeof(u32));
+
+       padding = lib_ring_buffer_align(offset,
+                                       sizeof(struct event_header));
+       offset += padding;
+       offset += sizeof(struct event_header);
+
+       if (unlikely(rflags)) {
+               switch (rflags) {
+               case LTT_RFLAG_ID_SIZE_TSC:
+                       offset += sizeof(u16) + sizeof(u16);
+                       if (data_size >= LTT_MAX_SMALL_SIZE)
+                               offset += sizeof(u32);
+                       offset += lib_ring_buffer_align(offset, sizeof(u64));
+                       offset += sizeof(u64);
+                       break;
+               case LTT_RFLAG_ID_SIZE:
+                       offset += sizeof(u16) + sizeof(u16);
+                       if (data_size >= LTT_MAX_SMALL_SIZE)
+                               offset += sizeof(u32);
+                       break;
+               case LTT_RFLAG_ID:
+                       offset += sizeof(u16);
+                       break;
+               }
+       }
+
+       *pre_header_padding = padding;
+       return offset - orig_offset;
+}
+
+#include "wrapper/ringbuffer/api.h"
+
+extern
+void ltt_write_event_header_slow(const struct lib_ring_buffer_config *config,
+                                struct lib_ring_buffer_ctx *ctx,
+                                u16 eID, u32 event_size);
+
+/*
+ * ltt_write_event_header
+ *
+ * Writes the event header to the offset (already aligned on 32-bits).
+ *
+ * @config: ring buffer instance configuration
+ * @ctx: reservation context
+ * @eID : event ID
+ * @event_size : size of the event, excluding the event header.
+ */
+static __inline__
+void ltt_write_event_header(const struct lib_ring_buffer_config *config,
+                           struct lib_ring_buffer_ctx *ctx,
+                           u16 eID, u32 event_size)
+{
+       struct event_header header;
+
+       if (unlikely(ctx->rflags))
+               goto slow_path;
+
+       header.id_time = eID << LTT_TSC_BITS;
+       header.id_time |= (u32)ctx->tsc & LTT_TSC_MASK;
+       lib_ring_buffer_write(config, ctx, &header, sizeof(header));
+
+slow_path:
+       ltt_write_event_header_slow(config, ctx, eID, event_size);
+}
+
+/**
+ * ltt_write_trace_header - Write trace header
+ * @priv: Private data (struct trace)
+ * @header: Memory address where the information must be written to
+ */
+static __inline__
+void write_trace_header(const struct lib_ring_buffer_config *config,
+                       struct packet_header *header)
+{
+       header->magic = CTF_MAGIC_NUMBER;
+#if 0
+       /* TODO: move start time to metadata */
+       header->major_version = LTT_TRACER_VERSION_MAJOR;
+       header->minor_version = LTT_TRACER_VERSION_MINOR;
+       header->arch_size = sizeof(void *);
+       header->alignment = lib_ring_buffer_get_alignment(config);
+       header->start_time_sec = ltt_chan->session->start_time.tv_sec;
+       header->start_time_usec = ltt_chan->session->start_time.tv_usec;
+       header->start_freq = ltt_chan->session->start_freq;
+       header->freq_scale = ltt_chan->session->freq_scale;
+#endif //0
+}
+
+void ltt_write_event_header_slow(const struct lib_ring_buffer_config *config,
+                                  struct lib_ring_buffer_ctx *ctx,
+                                  u16 eID, u32 event_size)
+{
+       struct event_header header;
+       u16 small_size;
+
+       switch (ctx->rflags) {
+       case LTT_RFLAG_ID_SIZE_TSC:
+               header.id_time = 29 << LTT_TSC_BITS;
+               break;
+       case LTT_RFLAG_ID_SIZE:
+               header.id_time = 30 << LTT_TSC_BITS;
+               break;
+       case LTT_RFLAG_ID:
+               header.id_time = 31 << LTT_TSC_BITS;
+               break;
+       default:
+               WARN_ON_ONCE(1);
+               header.id_time = 0;
+       }
+
+       header.id_time |= (u32)ctx->tsc & LTT_TSC_MASK;
+       lib_ring_buffer_write(config, ctx, &header, sizeof(header));
+
+       switch (ctx->rflags) {
+       case LTT_RFLAG_ID_SIZE_TSC:
+               small_size = (u16)min_t(u32, event_size, LTT_MAX_SMALL_SIZE);
+               lib_ring_buffer_write(config, ctx, &eID, sizeof(u16));
+               lib_ring_buffer_write(config, ctx, &small_size, sizeof(u16));
+               if (small_size == LTT_MAX_SMALL_SIZE)
+                       lib_ring_buffer_write(config, ctx, &event_size,
+                                             sizeof(u32));
+               lib_ring_buffer_align_ctx(ctx, sizeof(u64));
+               lib_ring_buffer_write(config, ctx, &ctx->tsc, sizeof(u64));
+               break;
+       case LTT_RFLAG_ID_SIZE:
+               small_size = (u16)min_t(u32, event_size, LTT_MAX_SMALL_SIZE);
+               lib_ring_buffer_write(config, ctx, &eID, sizeof(u16));
+               lib_ring_buffer_write(config, ctx, &small_size, sizeof(u16));
+               if (small_size == LTT_MAX_SMALL_SIZE)
+                       lib_ring_buffer_write(config, ctx, &event_size,
+                                             sizeof(u32));
+               break;
+       case LTT_RFLAG_ID:
+               lib_ring_buffer_write(config, ctx, &eID, sizeof(u16));
+               break;
+       }
+}
+
 static const struct lib_ring_buffer_config client_config;
 
 static u64 client_ring_buffer_clock_read(struct channel *chan)
This page took 0.025136 seconds and 4 git commands to generate.