Update stream packet and event headers
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Wed, 18 May 2011 17:57:42 +0000 (13:57 -0400)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Wed, 18 May 2011 17:57:42 +0000 (13:57 -0400)
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
lib/bitfield.h [new file with mode: 0644]
lib/ringbuffer/frontend.h
lib/ringbuffer/frontend_types.h
ltt-endian.h [new file with mode: 0644]
ltt-events.c
ltt-events.h
ltt-ring-buffer-client.h
ltt-ring-buffer-metadata-client.h
ltt-tracer.h
probes/lttng-types.h

diff --git a/lib/bitfield.h b/lib/bitfield.h
new file mode 100644 (file)
index 0000000..a509e35
--- /dev/null
@@ -0,0 +1,400 @@
+#ifndef _BABELTRACE_BITFIELD_H
+#define _BABELTRACE_BITFIELD_H
+
+/*
+ * BabelTrace
+ *
+ * Bitfields read/write functions.
+ *
+ * Copyright 2010 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ */
+
+#include "ltt-endian.h"
+
+#ifndef CHAR_BIT
+#define CHAR_BIT 8
+#endif
+
+/* We can't shift a int from 32 bit, >> 32 and << 32 on int is undefined */
+#define _bt_piecewise_rshift(_v, _shift)                               \
+({                                                                     \
+       typeof(_v) ___v = (_v);                                         \
+       typeof(_shift) ___shift = (_shift);                             \
+       unsigned long sb = (___shift) / (sizeof(___v) * CHAR_BIT - 1);  \
+       unsigned long final = (___shift) % (sizeof(___v) * CHAR_BIT - 1); \
+                                                                       \
+       for (; sb; sb--)                                                \
+               ___v >>= sizeof(___v) * CHAR_BIT - 1;                   \
+       ___v >>= final;                                                 \
+})
+
+#define _bt_piecewise_lshift(_v, _shift)                               \
+({                                                                     \
+       typeof(_v) ___v = (_v);                                         \
+       typeof(_shift) ___shift = (_shift);                             \
+       unsigned long sb = (___shift) / (sizeof(___v) * CHAR_BIT - 1);  \
+       unsigned long final = (___shift) % (sizeof(___v) * CHAR_BIT - 1); \
+                                                                       \
+       for (; sb; sb--)                                                \
+               ___v <<= sizeof(___v) * CHAR_BIT - 1;                   \
+       ___v <<= final;                                                 \
+})
+
+#define _bt_is_signed_type(type)       (((type)(-1)) < 0)
+
+#define _bt_unsigned_cast(type, v)                                     \
+({                                                                     \
+       (sizeof(v) < sizeof(type)) ?                                    \
+               ((type) (v)) & (~(~(type) 0 << (sizeof(v) * CHAR_BIT))) : \
+               (type) (v);                                             \
+})
+
+/*
+ * bt_bitfield_write - write integer to a bitfield in native endianness
+ *
+ * Save integer to the bitfield, which starts at the "start" bit, has "len"
+ * bits.
+ * The inside of a bitfield is from high bits to low bits.
+ * Uses native endianness.
+ * For unsigned "v", pad MSB with 0 if bitfield is larger than v.
+ * For signed "v", sign-extend v if bitfield is larger than v.
+ *
+ * On little endian, bytes are placed from the less significant to the most
+ * significant. Also, consecutive bitfields are placed from lower bits to higher
+ * bits.
+ *
+ * On big endian, bytes are places from most significant to less significant.
+ * Also, consecutive bitfields are placed from higher to lower bits.
+ */
+
+#define _bt_bitfield_write_le(_ptr, type, _start, _length, _v)         \
+do {                                                                   \
+       typeof(_v) __v = (_v);                                          \
+       type *__ptr = (void *) (_ptr);                                  \
+       unsigned long __start = (_start), __length = (_length);         \
+       type mask, cmask;                                               \
+       unsigned long ts = sizeof(type) * CHAR_BIT; /* type size */     \
+       unsigned long start_unit, end_unit, this_unit;                  \
+       unsigned long end, cshift; /* cshift is "complement shift" */   \
+                                                                       \
+       if (!__length)                                                  \
+               break;                                                  \
+                                                                       \
+       end = __start + __length;                                       \
+       start_unit = __start / ts;                                      \
+       end_unit = (end + (ts - 1)) / ts;                               \
+                                                                       \
+       /* Trim v high bits */                                          \
+       if (__length < sizeof(__v) * CHAR_BIT)                          \
+               __v &= ~((~(typeof(__v)) 0) << __length);               \
+                                                                       \
+       /* We can now append v with a simple "or", shift it piece-wise */ \
+       this_unit = start_unit;                                         \
+       if (start_unit == end_unit - 1) {                               \
+               mask = ~((~(type) 0) << (__start % ts));                \
+               if (end % ts)                                           \
+                       mask |= (~(type) 0) << (end % ts);              \
+               cmask = (type) __v << (__start % ts);                   \
+               cmask &= ~mask;                                         \
+               __ptr[this_unit] &= mask;                               \
+               __ptr[this_unit] |= cmask;                              \
+               break;                                                  \
+       }                                                               \
+       if (__start % ts) {                                             \
+               cshift = __start % ts;                                  \
+               mask = ~((~(type) 0) << cshift);                        \
+               cmask = (type) __v << cshift;                           \
+               cmask &= ~mask;                                         \
+               __ptr[this_unit] &= mask;                               \
+               __ptr[this_unit] |= cmask;                              \
+               __v = _bt_piecewise_rshift(__v, ts - cshift);           \
+               __start += ts - cshift;                                 \
+               this_unit++;                                            \
+       }                                                               \
+       for (; this_unit < end_unit - 1; this_unit++) {                 \
+               __ptr[this_unit] = (type) __v;                          \
+               __v = _bt_piecewise_rshift(__v, ts);                    \
+               __start += ts;                                          \
+       }                                                               \
+       if (end % ts) {                                                 \
+               mask = (~(type) 0) << (end % ts);                       \
+               cmask = (type) __v;                                     \
+               cmask &= ~mask;                                         \
+               __ptr[this_unit] &= mask;                               \
+               __ptr[this_unit] |= cmask;                              \
+       } else                                                          \
+               __ptr[this_unit] = (type) __v;                          \
+} while (0)
+
+#define _bt_bitfield_write_be(_ptr, type, _start, _length, _v)         \
+do {                                                                   \
+       typeof(_v) __v = (_v);                                          \
+       type *__ptr = (void *) (_ptr);                                  \
+       unsigned long __start = (_start), __length = (_length);         \
+       type mask, cmask;                                               \
+       unsigned long ts = sizeof(type) * CHAR_BIT; /* type size */     \
+       unsigned long start_unit, end_unit, this_unit;                  \
+       unsigned long end, cshift; /* cshift is "complement shift" */   \
+                                                                       \
+       if (!__length)                                                  \
+               break;                                                  \
+                                                                       \
+       end = __start + __length;                                       \
+       start_unit = __start / ts;                                      \
+       end_unit = (end + (ts - 1)) / ts;                               \
+                                                                       \
+       /* Trim v high bits */                                          \
+       if (__length < sizeof(__v) * CHAR_BIT)                          \
+               __v &= ~((~(typeof(__v)) 0) << __length);               \
+                                                                       \
+       /* We can now append v with a simple "or", shift it piece-wise */ \
+       this_unit = end_unit - 1;                                       \
+       if (start_unit == end_unit - 1) {                               \
+               mask = ~((~(type) 0) << ((ts - (end % ts)) % ts));      \
+               if (__start % ts)                                       \
+                       mask |= (~((type) 0)) << (ts - (__start % ts)); \
+               cmask = (type) __v << ((ts - (end % ts)) % ts);         \
+               cmask &= ~mask;                                         \
+               __ptr[this_unit] &= mask;                               \
+               __ptr[this_unit] |= cmask;                              \
+               break;                                                  \
+       }                                                               \
+       if (end % ts) {                                                 \
+               cshift = end % ts;                                      \
+               mask = ~((~(type) 0) << (ts - cshift));                 \
+               cmask = (type) __v << (ts - cshift);                    \
+               cmask &= ~mask;                                         \
+               __ptr[this_unit] &= mask;                               \
+               __ptr[this_unit] |= cmask;                              \
+               __v = _bt_piecewise_rshift(__v, cshift);                \
+               end -= cshift;                                          \
+               this_unit--;                                            \
+       }                                                               \
+       for (; (long) this_unit >= (long) start_unit + 1; this_unit--) { \
+               __ptr[this_unit] = (type) __v;                          \
+               __v = _bt_piecewise_rshift(__v, ts);                    \
+               end -= ts;                                              \
+       }                                                               \
+       if (__start % ts) {                                             \
+               mask = (~(type) 0) << (ts - (__start % ts));            \
+               cmask = (type) __v;                                     \
+               cmask &= ~mask;                                         \
+               __ptr[this_unit] &= mask;                               \
+               __ptr[this_unit] |= cmask;                              \
+       } else                                                          \
+               __ptr[this_unit] = (type) __v;                          \
+} while (0)
+
+/*
+ * bt_bitfield_write - write integer to a bitfield in native endianness
+ * bt_bitfield_write_le - write integer to a bitfield in little endian
+ * bt_bitfield_write_be - write integer to a bitfield in big endian
+ */
+
+#if (__BYTE_ORDER == __LITTLE_ENDIAN)
+
+#define bt_bitfield_write(ptr, type, _start, _length, _v)              \
+       _bt_bitfield_write_le(ptr, type, _start, _length, _v)
+
+#define bt_bitfield_write_le(ptr, type, _start, _length, _v)           \
+       _bt_bitfield_write_le(ptr, type, _start, _length, _v)
+       
+#define bt_bitfield_write_be(ptr, type, _start, _length, _v)           \
+       _bt_bitfield_write_be(ptr, unsigned char, _start, _length, _v)
+
+#elif (__BYTE_ORDER == __BIG_ENDIAN)
+
+#define bt_bitfield_write(ptr, type, _start, _length, _v)              \
+       _bt_bitfield_write_be(ptr, type, _start, _length, _v)
+
+#define bt_bitfield_write_le(ptr, type, _start, _length, _v)           \
+       _bt_bitfield_write_le(ptr, unsigned char, _start, _length, _v)
+       
+#define bt_bitfield_write_be(ptr, type, _start, _length, _v)           \
+       _bt_bitfield_write_be(ptr, type, _start, _length, _v)
+
+#else /* (BYTE_ORDER == PDP_ENDIAN) */
+
+#error "Byte order not supported"
+
+#endif
+
+#define _bt_bitfield_read_le(_ptr, type, _start, _length, _vptr)       \
+do {                                                                   \
+       typeof(*(_vptr)) *__vptr = (_vptr);                             \
+       typeof(*__vptr) __v;                                            \
+       type *__ptr = (void *) (_ptr);                                  \
+       unsigned long __start = (_start), __length = (_length);         \
+       type mask, cmask;                                               \
+       unsigned long ts = sizeof(type) * CHAR_BIT; /* type size */     \
+       unsigned long start_unit, end_unit, this_unit;                  \
+       unsigned long end, cshift; /* cshift is "complement shift" */   \
+                                                                       \
+       if (!__length) {                                                \
+               *__vptr = 0;                                            \
+               break;                                                  \
+       }                                                               \
+                                                                       \
+       end = __start + __length;                                       \
+       start_unit = __start / ts;                                      \
+       end_unit = (end + (ts - 1)) / ts;                               \
+                                                                       \
+       this_unit = end_unit - 1;                                       \
+       if (_bt_is_signed_type(typeof(__v))                             \
+           && (__ptr[this_unit] & ((type) 1 << ((end % ts ? : ts) - 1)))) \
+               __v = ~(typeof(__v)) 0;                                 \
+       else                                                            \
+               __v = 0;                                                \
+       if (start_unit == end_unit - 1) {                               \
+               cmask = __ptr[this_unit];                               \
+               cmask >>= (__start % ts);                               \
+               if ((end - __start) % ts) {                             \
+                       mask = ~((~(type) 0) << (end - __start));       \
+                       cmask &= mask;                                  \
+               }                                                       \
+               __v = _bt_piecewise_lshift(__v, end - __start);         \
+               __v |= _bt_unsigned_cast(typeof(__v), cmask);           \
+               *__vptr = __v;                                          \
+               break;                                                  \
+       }                                                               \
+       if (end % ts) {                                                 \
+               cshift = end % ts;                                      \
+               mask = ~((~(type) 0) << cshift);                        \
+               cmask = __ptr[this_unit];                               \
+               cmask &= mask;                                          \
+               __v = _bt_piecewise_lshift(__v, cshift);                \
+               __v |= _bt_unsigned_cast(typeof(__v), cmask);           \
+               end -= cshift;                                          \
+               this_unit--;                                            \
+       }                                                               \
+       for (; (long) this_unit >= (long) start_unit + 1; this_unit--) { \
+               __v = _bt_piecewise_lshift(__v, ts);                    \
+               __v |= _bt_unsigned_cast(typeof(__v), __ptr[this_unit]);\
+               end -= ts;                                              \
+       }                                                               \
+       if (__start % ts) {                                             \
+               mask = ~((~(type) 0) << (ts - (__start % ts)));         \
+               cmask = __ptr[this_unit];                               \
+               cmask >>= (__start % ts);                               \
+               cmask &= mask;                                          \
+               __v = _bt_piecewise_lshift(__v, ts - (__start % ts));   \
+               __v |= _bt_unsigned_cast(typeof(__v), cmask);           \
+       } else {                                                        \
+               __v = _bt_piecewise_lshift(__v, ts);                    \
+               __v |= _bt_unsigned_cast(typeof(__v), __ptr[this_unit]);\
+       }                                                               \
+       *__vptr = __v;                                                  \
+} while (0)
+
+#define _bt_bitfield_read_be(_ptr, type, _start, _length, _vptr)       \
+do {                                                                   \
+       typeof(*(_vptr)) *__vptr = (_vptr);                             \
+       typeof(*__vptr) __v;                                            \
+       type *__ptr = (void *) (_ptr);                                  \
+       unsigned long __start = (_start), __length = (_length);         \
+       type mask, cmask;                                               \
+       unsigned long ts = sizeof(type) * CHAR_BIT; /* type size */     \
+       unsigned long start_unit, end_unit, this_unit;                  \
+       unsigned long end, cshift; /* cshift is "complement shift" */   \
+                                                                       \
+       if (!__length) {                                                \
+               *__vptr = 0;                                            \
+               break;                                                  \
+       }                                                               \
+                                                                       \
+       end = __start + __length;                                       \
+       start_unit = __start / ts;                                      \
+       end_unit = (end + (ts - 1)) / ts;                               \
+                                                                       \
+       this_unit = start_unit;                                         \
+       if (_bt_is_signed_type(typeof(__v))                             \
+           && (__ptr[this_unit] & ((type) 1 << (ts - (__start % ts) - 1)))) \
+               __v = ~(typeof(__v)) 0;                                 \
+       else                                                            \
+               __v = 0;                                                \
+       if (start_unit == end_unit - 1) {                               \
+               cmask = __ptr[this_unit];                               \
+               cmask >>= (ts - (end % ts)) % ts;                       \
+               if ((end - __start) % ts) {                             \
+                       mask = ~((~(type) 0) << (end - __start));       \
+                       cmask &= mask;                                  \
+               }                                                       \
+               __v = _bt_piecewise_lshift(__v, end - __start);         \
+               __v |= _bt_unsigned_cast(typeof(__v), cmask);           \
+               *__vptr = __v;                                          \
+               break;                                                  \
+       }                                                               \
+       if (__start % ts) {                                             \
+               cshift = __start % ts;                                  \
+               mask = ~((~(type) 0) << (ts - cshift));                 \
+               cmask = __ptr[this_unit];                               \
+               cmask &= mask;                                          \
+               __v = _bt_piecewise_lshift(__v, ts - cshift);           \
+               __v |= _bt_unsigned_cast(typeof(__v), cmask);           \
+               __start += ts - cshift;                                 \
+               this_unit++;                                            \
+       }                                                               \
+       for (; this_unit < end_unit - 1; this_unit++) {                 \
+               __v = _bt_piecewise_lshift(__v, ts);                    \
+               __v |= _bt_unsigned_cast(typeof(__v), __ptr[this_unit]);\
+               __start += ts;                                          \
+       }                                                               \
+       if (end % ts) {                                                 \
+               mask = ~((~(type) 0) << (end % ts));                    \
+               cmask = __ptr[this_unit];                               \
+               cmask >>= ts - (end % ts);                              \
+               cmask &= mask;                                          \
+               __v = _bt_piecewise_lshift(__v, end % ts);              \
+               __v |= _bt_unsigned_cast(typeof(__v), cmask);           \
+       } else {                                                        \
+               __v = _bt_piecewise_lshift(__v, ts);                    \
+               __v |= _bt_unsigned_cast(typeof(__v), __ptr[this_unit]);\
+       }                                                               \
+       *__vptr = __v;                                                  \
+} while (0)
+
+/*
+ * bt_bitfield_read - read integer from a bitfield in native endianness
+ * bt_bitfield_read_le - read integer from a bitfield in little endian
+ * bt_bitfield_read_be - read integer from a bitfield in big endian
+ */
+
+#if (__BYTE_ORDER == __LITTLE_ENDIAN)
+
+#define bt_bitfield_read(_ptr, type, _start, _length, _vptr)           \
+       _bt_bitfield_read_le(_ptr, type, _start, _length, _vptr)
+
+#define bt_bitfield_read_le(_ptr, type, _start, _length, _vptr)                \
+       _bt_bitfield_read_le(_ptr, type, _start, _length, _vptr)
+       
+#define bt_bitfield_read_be(_ptr, type, _start, _length, _vptr)                \
+       _bt_bitfield_read_be(_ptr, unsigned char, _start, _length, _vptr)
+
+#elif (__BYTE_ORDER == __BIG_ENDIAN)
+
+#define bt_bitfield_read(_ptr, type, _start, _length, _vptr)           \
+       _bt_bitfield_read_be(_ptr, type, _start, _length, _vptr)
+
+#define bt_bitfield_read_le(_ptr, type, _start, _length, _vptr)                \
+       _bt_bitfield_read_le(_ptr, unsigned char, _start, _length, _vptr)
+       
+#define bt_bitfield_read_be(_ptr, type, _start, _length, _vptr)                \
+       _bt_bitfield_read_be(_ptr, type, _start, _length, _vptr)
+
+#else /* (__BYTE_ORDER == __PDP_ENDIAN) */
+
+#error "Byte order not supported"
+
+#endif
+
+#endif /* _BABELTRACE_BITFIELD_H */
index 7bb51a4721037acd530efd16fb061361796b3e76..003c2e1915f70cb7e53601efe9e8de0fb0d9b0e1 100644 (file)
@@ -213,10 +213,4 @@ unsigned long lib_ring_buffer_get_records_read(
        return v_read(config, &buf->backend.records_read);
 }
 
-static inline
-void *channel_get_private(struct channel *chan)
-{
-       return chan->backend.priv;
-}
-
 #endif /* _LINUX_RING_BUFFER_FRONTEND_H */
index 0fa2dddfce5efb9339fac01fe77a869786d303f9..e8c4c5ce8a4f5dd89da66cce76d5c8af7e66e356 100644 (file)
@@ -139,6 +139,12 @@ struct lib_ring_buffer {
        int read_timer_enabled:1;       /* Protected by ring_buffer_nohz_lock */
 };
 
+static inline
+void *channel_get_private(struct channel *chan)
+{
+       return chan->backend.priv;
+}
+
 /*
  * Issue warnings and disable channels upon internal error.
  * Can receive struct lib_ring_buffer or struct lib_ring_buffer_backend
diff --git a/ltt-endian.h b/ltt-endian.h
new file mode 100644 (file)
index 0000000..29d75df
--- /dev/null
@@ -0,0 +1,23 @@
+#ifndef _LTT_ENDIAN_H
+#define _LTT_ENDIAN_H
+
+#ifdef __KERNEL__
+# include <asm/byteorder.h>
+# ifdef __BIG_ENDIAN
+#  define __BYTE_ORDER __BIG_ENDIAN
+# elif defined(__LITTLE_ENDIAN)
+#  define __BYTE_ORDER __LITTLE_ENDIAN
+# else
+#  error "unknown endianness"
+# endif
+#ifndef __BIG_ENDIAN
+# define __BIG_ENDIAN 4321
+#endif
+#ifndef __LITTLE_ENDIAN
+# define __LITTLE_ENDIAN 1234
+#endif
+#else
+# include <endian.h>
+#endif
+
+#endif /* _LTT_ENDIAN_H */
index 73ea08ea843eff4252277bc4a4d70dc8908e51f1..703fd3d7fa5ddac330460e802de0e74fb79567de 100644 (file)
@@ -168,7 +168,7 @@ struct ltt_channel *ltt_channel_create(struct ltt_session *session,
                goto nomem;
        chan->session = session;
        init_waitqueue_head(&chan->notify_wait);
-       chan->chan = transport->ops.channel_create("[lttng]", session, buf_addr,
+       chan->chan = transport->ops.channel_create("[lttng]", chan, buf_addr,
                        subbuf_size, num_subbuf, switch_timer_interval,
                        read_timer_interval);
        if (!chan->chan)
@@ -491,8 +491,8 @@ int _ltt_event_metadata_statedump(struct ltt_session *session,
         * byte size.
         */
        ret = lttng_metadata_printf(session,
-               "       } aligned(%u);\n"
-               "};\n\n", ltt_get_header_alignment());
+               "       };\n"
+               "};\n\n");
        if (ret)
                goto end;
 
@@ -520,7 +520,8 @@ int _ltt_channel_metadata_statedump(struct ltt_session *session,
        ret = lttng_metadata_printf(session,
                "stream {\n"
                "       id = %u;\n"
-               "       event.header := %s;\n",
+               "       event.header := %s;\n"
+               "       packet.context := struct packet_context;\n"
                "};\n\n",
                chan->id,
                chan->header_type == 1 ? "struct event_header_compact" :
@@ -533,6 +534,64 @@ end:
        return ret;
 }
 
+static
+int _ltt_stream_packet_context_declare(struct ltt_session *session)
+{
+       return lttng_metadata_printf(session,
+               "struct packet_context {\n"
+               "       uint64_t timestamp_begin;\n"
+               "       uint64_t timestamp_end;\n"
+               "       uint32_t events_discarded;\n"
+               "       uint32_t content_size;\n"
+               "       uint32_t packet_size;\n"
+               "       uint32_t cpu_id;\n"
+               "};\n"
+               );
+}
+
+/*
+ * Compact header:
+ * id: range: 0 - 30.
+ * id 31 is reserved to indicate an extended header.
+ *
+ * Large header:
+ * id: range: 0 - 65534.
+ * id 65535 is reserved to indicate an extended header.
+ */
+static
+int _ltt_event_header_declare(struct ltt_session *session)
+{
+       return lttng_metadata_printf(session,
+       "struct event_header_compact {\n"
+       "       enum : uint5_t { compact = 0 ... 30, extended = 31 } id;\n"
+       "       variant <id> {\n"
+       "               struct {\n"
+       "                       uint27_t timestamp;\n"
+       "               } compact;\n"
+       "               struct {\n"
+       "                       uint32_t id;\n"
+       "                       uint64_t timestamp;\n"
+       "               } extended;\n"
+       "       } v;\n"
+       "} align(%u);\n"
+       "\n"
+       "struct event_header_large {\n"
+       "       enum : uint16_t { compact = 0 ... 65534, extended = 65535 } id;\n"
+       "       variant <id> {\n"
+       "               struct {\n"
+       "                       uint32_t timestamp;\n"
+       "               } compact;\n"
+       "               struct {\n"
+       "                       uint32_t id;\n"
+       "                       uint64_t timestamp;\n"
+       "               } extended;\n"
+       "       } v;\n"
+       "} align(%u);\n\n",
+       ltt_alignof(uint32_t) * CHAR_BIT,
+       ltt_alignof(uint16_t) * CHAR_BIT
+       );
+}
+
 /*
  * Output metadata into this session's metadata buffers.
  */
@@ -561,9 +620,12 @@ int _ltt_session_metadata_statedump(struct ltt_session *session)
                uuid_s[12], uuid_s[13], uuid_s[14], uuid_s[15]);
 
        ret = lttng_metadata_printf(session,
-               "typealias integer {size = 8; align = %u; signed = false; } := uint8_t;\n"
-               "typealias integer {size = 32; align = %u; signed = false; } := uint32_t;\n"
-               "typealias integer {size = 64; align = %u; signed = false; } := uint64_t;\n"
+               "typealias integer { size = 8; align = %u; signed = false; } := uint8_t;\n"
+               "typealias integer { size = 16; align = %u; signed = false; } := uint16_t;\n"
+               "typealias integer { size = 32; align = %u; signed = false; } := uint32_t;\n"
+               "typealias integer { size = 64; align = %u; signed = false; } := uint64_t;\n"
+               "typealias integer { size = 5; align = 1; signed = false; } := uint5_t;\n"
+               "typealias integer { size = 27; align = 1; signed = false; } := uint27_t;\n"
                "\n"
                "trace {\n"
                "       major = %u;\n"
@@ -574,11 +636,6 @@ int _ltt_session_metadata_statedump(struct ltt_session *session)
                "               uint32_t magic;\n"
                "               uint8_t  uuid[16];\n"
                "               uint32_t stream_id;\n"
-               "               uint64_t timestamp_begin;\n"
-               "               uint64_t timestamp_end;\n"
-               "               uint32_t content_size;\n"
-               "               uint32_t packet_size;\n"
-               "               uint32_t events_lost;\n"
                "       };\n",
                "};\n\n",
                ltt_alignof(uint8_t) * CHAR_BIT,
@@ -596,6 +653,14 @@ int _ltt_session_metadata_statedump(struct ltt_session *session)
        if (ret)
                goto end;
 
+       ret = _ltt_stream_packet_context_declare(session);
+       if (ret)
+               goto end;
+
+       ret = _ltt_event_header_declare(session);
+       if (ret)
+               goto end;
+
 skip_session:
        list_for_each_entry(chan, &session->chan, list) {
                ret = _ltt_channel_metadata_statedump(session, chan);
index 0911a5ef300a1311d0ef6c2ec1a83ac6255b385d..bf0ac599df7ad53e2b8d3774179a1bb31037cec5 100644 (file)
@@ -135,7 +135,7 @@ struct ltt_event {
 
 struct ltt_channel_ops {
        struct channel *(*channel_create)(const char *name,
-                               struct ltt_session *session,
+                               struct ltt_channel *ltt_chan,
                                void *buf_addr,
                                size_t subbuf_size, size_t num_subbuf,
                                unsigned int switch_timer_interval,
@@ -166,8 +166,8 @@ struct ltt_channel {
        struct list_head list;          /* Channel list */
        wait_queue_head_t notify_wait;  /* Channel addition notif. waitqueue */
        struct ltt_channel_ops *ops;
+       int header_type;                /* 0: unset, 1: compact, 2: large */
        int metadata_dumped:1;
-       int header_type:2;              /* 0: unset, 1: compact, 2: large */
 };
 
 struct ltt_session {
index 8bb66af8ad09865ef2ebd851a17d114eb4059bdb..caf949cdc414659a4f164ca5987621a3ebb9d1fd 100644 (file)
 
 #include <linux/module.h>
 #include <linux/types.h>
+#include "lib/bitfield.h"
 #include "wrapper/vmalloc.h"   /* for wrapper_vmalloc_sync_all() */
 #include "wrapper/trace-clock.h"
 #include "ltt-events.h"
 #include "ltt-tracer.h"
+#include "wrapper/ringbuffer/frontend_types.h"
 
 /*
  * Keep the natural field alignment for _each field_ within this structure if
  * because gcc generates poor code on at least powerpc and mips. Don't ever
  * let gcc add padding between the structure elements.
  */
+
 struct packet_header {
+       /* Trace packet header */
        uint32_t magic;                 /*
                                         * Trace magic number.
                                         * contains endianness information.
                                         */
        uint8_t uuid[16];
        uint32_t stream_id;
-       uint64_t timestamp_begin;       /* Cycle count at subbuffer start */
-       uint64_t timestamp_end; /* Cycle count at subbuffer end */
-       uint32_t content_size;          /* Size of data in subbuffer */
-       uint32_t packet_size;           /* Subbuffer size (include padding) */
-       uint32_t events_lost;           /*
-                                        * Events lost in this subbuffer since
-                                        * the beginning of the trace.
-                                        * (may overflow)
-                                        */
-#if 0
-       uint64_t start_time_sec;        /* NTP-corrected start time */
-       uint64_t start_time_usec;
-       uint64_t start_freq;            /*
-                                        * Frequency at trace start,
-                                * used all along the trace.
-                                        */
-       uint32_t freq_scale;            /* Frequency scaling (divisor) */
-#endif //0
-       uint8_t header_end[0];          /* End of header */
+
+       struct {
+               /* Stream packet context */
+               uint64_t timestamp_begin;       /* Cycle count at subbuffer start */
+               uint64_t timestamp_end;         /* Cycle count at subbuffer end */
+               uint32_t events_discarded;      /*
+                                                * Events lost in this subbuffer since
+                                                * the beginning of the trace.
+                                                * (may overflow)
+                                                */
+               uint32_t content_size;          /* Size of data in subbuffer */
+               uint32_t packet_size;           /* Subbuffer size (include padding) */
+               uint32_t cpu_id;                /* CPU id associated with stream */
+               uint8_t header_end;             /* End of header */
+       } ctx;
 };
 
 
@@ -67,17 +67,6 @@ static inline notrace u64 lib_ring_buffer_clock_read(struct channel *chan)
  *
  * 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.
  */
@@ -88,34 +77,44 @@ unsigned char record_header_size(const struct lib_ring_buffer_config *config,
                                 unsigned int rflags,
                                 struct lib_ring_buffer_ctx *ctx)
 {
+       struct ltt_channel *ltt_chan = channel_get_private(chan);
        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;
+       switch (ltt_chan->header_type) {
+       case 1: /* compact */
+               padding = lib_ring_buffer_align(offset, ltt_alignof(uint32_t));
+               offset += padding;
+               if (!(rflags & RING_BUFFER_RFLAG_FULL_TSC)) {
+                       offset += sizeof(uint32_t);     /* id and timestamp */
+               } else {
+                       /* Minimum space taken by 5-bit id */
+                       offset += sizeof(uint8_t);
+                       /* Align extended struct on largest member */
+                       offset += lib_ring_buffer_align(offset, ltt_alignof(uint64_t));
+                       offset += sizeof(uint32_t);     /* id */
+                       offset += lib_ring_buffer_align(offset, ltt_alignof(uint64_t));
+                       offset += sizeof(uint64_t);     /* timestamp */
+               }
+               break;
+       case 2: /* large */
+               padding = lib_ring_buffer_align(offset, ltt_alignof(uint16_t));
+               offset += padding;
+               offset += sizeof(uint16_t);
+               if (!(rflags & RING_BUFFER_RFLAG_FULL_TSC)) {
+                       offset += lib_ring_buffer_align(offset, ltt_alignof(uint32_t));
+                       offset += sizeof(uint32_t);     /* timestamp */
+               } else {
+                       /* Align extended struct on largest member */
+                       offset += lib_ring_buffer_align(offset, ltt_alignof(uint64_t));
+                       offset += sizeof(uint32_t);     /* id */
+                       offset += lib_ring_buffer_align(offset, ltt_alignof(uint64_t));
+                       offset += sizeof(uint64_t);     /* timestamp */
+                       
                }
+               break;
+       default:
+               WARN_ON(1);
        }
 
        *pre_header_padding = padding;
@@ -144,66 +143,96 @@ 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;
+       struct ltt_channel *ltt_chan = channel_get_private(ctx->chan);
 
        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));
+       switch (ltt_chan->header_type) {
+       case 1: /* compact */
+       {
+               uint32_t id_time = 0;
+
+               bt_bitfield_write(&id_time, uint32_t, 0, 5, eID);
+               bt_bitfield_write(&id_time, uint32_t, 5, 27, ctx->tsc);
+               lib_ring_buffer_write(config, ctx, &id_time, sizeof(id_time));
+               break;
+       }
+       case 2: /* large */
+       {
+               uint16_t event_id = eID;
+               uint32_t timestamp = (uint32_t) ctx->tsc;
+
+               lib_ring_buffer_write(config, ctx, &event_id, sizeof(event_id));
+               lib_ring_buffer_align_ctx(ctx, ltt_alignof(uint32_t));
+               lib_ring_buffer_write(config, ctx, &timestamp, sizeof(timestamp));
+               break;
+       }
+       default:
+               WARN_ON(1);
+       }
+       return;
 
 slow_path:
        ltt_write_event_header_slow(config, ctx, eID, event_size);
 }
 
+/*
+ * TODO: For now, we only support 65536 event ids per channel.
+ */
 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;
+       struct ltt_channel *ltt_chan = channel_get_private(ctx->chan);
+
+       switch (ltt_chan->header_type) {
+       case 1: /* compact */
+               if (!(ctx->rflags & RING_BUFFER_RFLAG_FULL_TSC)) {
+                       uint32_t id_time = 0;
+
+                       bt_bitfield_write(&id_time, uint32_t, 0, 5, eID);
+                       bt_bitfield_write(&id_time, uint32_t, 5, 27, ctx->tsc);
+                       lib_ring_buffer_write(config, ctx, &id_time, sizeof(id_time));
+               } else {
+                       uint8_t id = 0;
+                       uint32_t event_id = (uint32_t) eID;
+                       uint64_t timestamp = ctx->tsc;
+
+                       bt_bitfield_write(&id, uint8_t, 0, 5, 31);
+                       lib_ring_buffer_write(config, ctx, &id, sizeof(id));
+                       /* Align extended struct on largest member */
+                       lib_ring_buffer_align_ctx(ctx, ltt_alignof(uint64_t));
+                       lib_ring_buffer_write(config, ctx, &event_id, sizeof(event_id));
+                       lib_ring_buffer_align_ctx(ctx, ltt_alignof(uint64_t));
+                       lib_ring_buffer_write(config, ctx, &timestamp, sizeof(timestamp));
+               }
                break;
-       case LTT_RFLAG_ID:
-               header.id_time = 31 << LTT_TSC_BITS;
+       case 2: /* large */
+       {
+               if (!(ctx->rflags & RING_BUFFER_RFLAG_FULL_TSC)) {
+                       uint16_t event_id = eID;
+                       uint32_t timestamp = (uint32_t) ctx->tsc;
+
+                       lib_ring_buffer_write(config, ctx, &event_id, sizeof(event_id));
+                       lib_ring_buffer_align_ctx(ctx, ltt_alignof(uint32_t));
+                       lib_ring_buffer_write(config, ctx, &timestamp, sizeof(timestamp));
+               } else {
+                       uint16_t event_id = 65535;
+                       uint32_t event_id_ext = (uint32_t) eID;
+                       uint64_t timestamp = ctx->tsc;
+
+                       lib_ring_buffer_write(config, ctx, &event_id, sizeof(event_id));
+                       /* Align extended struct on largest member */
+                       lib_ring_buffer_align_ctx(ctx, ltt_alignof(uint64_t));
+                       lib_ring_buffer_write(config, ctx, &event_id_ext, sizeof(event_id_ext));
+                       lib_ring_buffer_align_ctx(ctx, ltt_alignof(uint64_t));
+                       lib_ring_buffer_write(config, ctx, &timestamp, sizeof(timestamp));
+               }
                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;
+       default:
+               WARN_ON(1);
        }
 }
 
@@ -235,7 +264,7 @@ size_t client_record_header_size(const struct lib_ring_buffer_config *config,
  */
 static size_t client_packet_header_size(void)
 {
-       return offsetof(struct packet_header, header_end);
+       return offsetof(struct packet_header, ctx.header_end);
 }
 
 static void client_buffer_begin(struct lib_ring_buffer *buf, u64 tsc,
@@ -246,21 +275,18 @@ static void client_buffer_begin(struct lib_ring_buffer *buf, u64 tsc,
                (struct packet_header *)
                        lib_ring_buffer_offset_address(&buf->backend,
                                subbuf_idx * chan->backend.subbuf_size);
-       struct ltt_session *session = channel_get_private(chan);
+       struct ltt_channel *ltt_chan = channel_get_private(chan);
+       struct ltt_session *session = ltt_chan->session;
 
        header->magic = CTF_MAGIC_NUMBER;
        memcpy(header->uuid, session->uuid.b, sizeof(session->uuid));
-       header->timestamp_begin = tsc;
-       header->timestamp_end = 0;
-       header->content_size = 0xFFFFFFFF; /* for debugging */
-       header->packet_size = 0xFFFFFFFF;
-       header->events_lost = 0;
-#if 0
-       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
+       header->stream_id = ltt_chan->id;
+       header->ctx.timestamp_begin = tsc;
+       header->ctx.timestamp_end = 0;
+       header->ctx.events_discarded = 0;
+       header->ctx.content_size = 0xFFFFFFFF; /* for debugging */
+       header->ctx.packet_size = 0xFFFFFFFF;
+       header->ctx.cpu_id = buf->backend.cpu;
 }
 
 /*
@@ -277,13 +303,13 @@ static void client_buffer_end(struct lib_ring_buffer *buf, u64 tsc,
                                subbuf_idx * chan->backend.subbuf_size);
        unsigned long records_lost = 0;
 
-       header->timestamp_end = tsc;
-       header->content_size = data_size;
-       header->packet_size = PAGE_ALIGN(data_size);
+       header->ctx.timestamp_end = tsc;
+       header->ctx.content_size = data_size;
+       header->ctx.packet_size = PAGE_ALIGN(data_size);
        records_lost += lib_ring_buffer_get_records_lost_full(&client_config, buf);
        records_lost += lib_ring_buffer_get_records_lost_wrap(&client_config, buf);
        records_lost += lib_ring_buffer_get_records_lost_big(&client_config, buf);
-       header->events_lost = records_lost;
+       header->ctx.events_discarded = records_lost;
 }
 
 static int client_buffer_create(struct lib_ring_buffer *buf, void *priv,
@@ -318,12 +344,12 @@ static const struct lib_ring_buffer_config client_config = {
 
 static
 struct channel *_channel_create(const char *name,
-                               struct ltt_session *session, void *buf_addr,
+                               struct ltt_channel *ltt_chan, void *buf_addr,
                                size_t subbuf_size, size_t num_subbuf,
                                unsigned int switch_timer_interval,
                                unsigned int read_timer_interval)
 {
-       return channel_create(&client_config, name, session, buf_addr,
+       return channel_create(&client_config, name, ltt_chan, buf_addr,
                              subbuf_size, num_subbuf, switch_timer_interval,
                              read_timer_interval);
 }
index bde712e6e6adbf6e513c843622977ea55de63f43..9456d54e54223d3d0dc5364a98f2911f4272a15a 100644 (file)
@@ -86,7 +86,8 @@ static void client_buffer_begin(struct lib_ring_buffer *buf, u64 tsc,
                (struct metadata_packet_header *)
                        lib_ring_buffer_offset_address(&buf->backend,
                                subbuf_idx * chan->backend.subbuf_size);
-       struct ltt_session *session = channel_get_private(chan);
+       struct ltt_channel *ltt_chan = channel_get_private(chan);
+       struct ltt_session *session = ltt_chan->session;
 
        header->magic = TSDL_MAGIC_NUMBER;
        memcpy(header->uuid, session->uuid.b, sizeof(session->uuid));
index f1cd2d90f75e4d258f335c400a6c0aa759c9533c..aa9db46a88a665fe1a91df032bf7c7fb1774c8f8 100644 (file)
@@ -96,38 +96,11 @@ enum ltt_channels {
  * concerns.
  */
 
-#define LTT_RESERVED_EVENTS    3
-#define LTT_EVENT_BITS         5
-#define LTT_FREE_EVENTS                ((1 << LTT_EVENT_BITS) - LTT_RESERVED_EVENTS)
-#define LTT_TSC_BITS           27
-#define LTT_TSC_MASK           ((1 << LTT_TSC_BITS) - 1)
-
-struct event_header {
-       u32 id_time;            /* 5 bits event id (MSB); 27 bits time (LSB) */
-};
-
-/* Reservation flags */
-#define        LTT_RFLAG_ID                    (1 << 0)
-#define        LTT_RFLAG_ID_SIZE               (1 << 1)
-#define        LTT_RFLAG_ID_SIZE_TSC           (1 << 2)
-
 #define LTT_MAX_SMALL_SIZE             0xFFFFU
 
 #ifdef RING_BUFFER_ALIGN
-static inline
-size_t ltt_get_header_alignment(void)
-{
-       return sizeof(struct event_header) * CHAR_BIT;
-}
-
 #define ltt_alignof(type)      __alignof__(type)
 #else
-static inline
-size_t ltt_get_header_alignment(void)
-{
-       return CHAR_BIT;
-}
-
 #define ltt_alignof(type)      1
 #endif
 
index 5a7a655445bdf1561b24586399c9d44f02fd78fc..c435b4d3ea127346e3b21c31bb115ab2bc3896a6 100644 (file)
@@ -9,29 +9,10 @@
 #include "lttng.h"
 #include "../ltt-events.h"
 #include "../ltt-tracer.h"
-
-#ifdef __KERNEL__
-# include <asm/byteorder.h>
-# ifdef __BIG_ENDIAN
-#  define __BYTE_ORDER __BIG_ENDIAN
-# elif defined(__LITTLE_ENDIAN)
-#  define __BYTE_ORDER __LITTLE_ENDIAN
-# else
-#  error "unknown endianness"
-# endif
-#ifndef __BIG_ENDIAN
-# define __BIG_ENDIAN 4321
-#endif
-#ifndef __LITTLE_ENDIAN
-# define __LITTLE_ENDIAN 1234
-#endif
-#else
-# include <endian.h>
-#endif
+#include "../ltt-endian.h"
 
 #endif /* _LTTNG_PROBES_LTTNG_TYPES_H */
 
-
 /* Export enumerations */
 
 #ifdef STAGE_EXPORT_ENUMS
This page took 0.040365 seconds and 4 git commands to generate.