[lttng-dev] CTF2-PROP-1.0: Proposal for a major revision of the Common Trace Format, version 1.8
Mathieu Desnoyers
mathieu.desnoyers at efficios.com
Wed Oct 26 16:27:44 UTC 2016
----- On Oct 26, 2016, at 11:32 AM, Mathieu Desnoyers mathieu.desnoyers at efficios.com wrote:
> ----- On Oct 25, 2016, at 2:26 PM, Philippe Proulx pproulx at efficios.com wrote:
>
>> Hello fellow trace format enthusiasts.
>>
>> This is a proposal for a major revision of CTF v1.8 (to CTF v2).
>
> How about we present it over a diamon.org conference call ? We could
> setup a call for the week of November 1st. Philippe could prepare
> a few slides to present it, and it would be mostly oriented
> towards gathering feedback.
Actually, the week of Nov. 8th would give a bit more time to prepare
and ensure attendees can have room in their schedule.
Thanks,
Mathieu
>
> Thanks,
>
> Mathieu
>
>
>>
>> I strongly suggest that you read the HTML version at:
>>
>> http://diamon.org/ctf/files/CTF2-PROP-1.0.html
>>
>> since the text below is an AsciiDoc source. You should, however,
>> inline-comment if you have something to say about a specific section of
>> the document, but _please_ keep only a few lines of context (what's
>> necessary) above and below your comment, because the text is about 4500
>> lines long.
>>
>> Other emails will follow with other CTF 2 documents. We decided to
>> decouple some features and optional parts of CTF 2 in different
>> documents so that each one is really focused on its own subject. Then
>> producers and consumers may comply with this or that document. For
>> example, as long as a consumer can decode a CTF 2 trace (following the
>> specification itself), it's not the end of the world if it doesn't know
>> that a given integer field type prefers to be displayed in base 16.
>>
>> The other documents are:
>>
>> * http://diamon.org/ctf/files/CTF2-DOCID-1.0.html
>> * http://diamon.org/ctf/files/CTF2-BASICATTRS-1.0.html
>> * http://diamon.org/ctf/files/CTF2-PMETA-1.0.html
>> * http://diamon.org/ctf/files/CTF2-FS-1.0.html
>>
>> Feel free to question this proposal!
>>
>> A few things that still annoy me:
>>
>> * Should a boolean field type inherit the properties of an integer field
>> type instead of a simple bit array field type? In other words, should
>> a boolean field type have a signedness property?
>>
>> Since the interesting values of a boolean field are really _true_ and
>> _false_, in my opinion we should not care about any signedness here.
>> If you need this, you can use the new union field type and match a
>> boolean field type of size X with a (signed, for example) integer
>> field type of size X.
>>
>> * Do we really need to support other bases than base 10 in the constant
>> integer JSON object? AFAIK, other bases are not required to encode and
>> decode any integer value. They're only there to ease human reading of
>> the metadata stream... however it's pretty much the only place where
>> such a human-friendly entity is defined, so is it really needed?
>>
>> Keep in mind that keeping the support for bases 2, 8, and 16 requires
>> each single CTF 2 consumer to be able to convert those strings to
>> integers.
>>
>> * There's a clear relation between some field types that, the way it's
>> written now, have no common parent.
>>
>> For example, a variable-length integer field type describes fields
>> that, once decoded, provide integer values, just like the integer
>> field type does. However, they have no relation. Even though they both
>> share a `signed` property, the variable-length integer field type does
>> not need a `size` property, which is inherited from the bit array
>> field type.
>>
>> Same thing for the text array field type vs. the array field type
>> (former does not need an `element-field-type` property because it's
>> implicit).
>>
>> Array field type and sequence field type could also be related by
>> their common `element-field-type` property, but they are not as of
>> this version.
>>
>> Do you have any idea how to bring them into relation with one another
>> without making the text too heavy? I'm thinking about some kind of
>> property mixin (or trait?) which could be applied over a field type.
>> For example, the "integer field type mixin" could define a single
>> `signed` property and both the integer field type and the
>> variable-length integer field type could claim to "implement" this
>> mixin. "Mixin" is probably not the right term. This could simplify
>> some parts of the text where a field providing an integer value is
>> needed: the text could read something like "a field type with the
>> integer field type mixin applied is needed here".
>>
>> * I'm not impressed by the clock field tags, in that we define in an
>> upper layer an m-map which can be inserted _within_ an m-map which was
>> defined in a _lower_ layer of the specification.
>>
>> However I believe it's important that all field tags which target a
>> specific scope field be in the same fragment that defines the type of
>> this scope field. For example, all field tags which target the event
>> record header scope should be part of the data stream class fragment
>> where this event record header field type is defined.
>>
>> Any idea?
>>
>> Thanks for your comments!
>>
>> Philippe Proulx
>> EfficiOS Inc.
>> http://www.efficios.com/
>>
>> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
>>
>> = CTF2-PROP-1.0: Proposal for a major revision of the Common Trace Format,
>> version 1.8
>> Philippe Proulx <pproulx at efficios.com>
>> v1.0, 21 October 2016
>> :toc:
>> :toclevels: 5
>> :ieee754: IEEE 754-2008's binary interchange format
>>
>> This document is an informal proposal for the next major revision of the
>> **Common Trace Format** (CTF): version 2.0 (hereafter named
>> _CTF{nbsp}2_).
>>
>> This is _not_ a formal reference. Some parts of this document, however,
>> may be formal enough to be elligible for a specification document.
>>
>> .RFC 2119
>> NOTE: The key words _must_, _must not_, _required_, _shall_, _shall
>> not_, _should_, _should not_, _recommended_, _may_, and _optional_ in
>> this document, when emphasized, are to be interpreted as described in
>> https://www.ietf.org/rfc/rfc2119.txt[RFC 2119].
>>
>>
>> == A new workgroup responsible for the publication of CTF documents
>>
>> The http://diamon.org/[DiaMon Workgroup], a
>> https://www.linuxfoundation.org/[Linux Foundation] workgroup which
>> creates de-facto standards and tools for tracing, monitoring, and
>> diagnostics, is now responsible for the publication of the official
>> documents about CTF.
>>
>> The DiaMon Workgroup is also responsible for making available a platform
>> where interested parties can comment on the proposals related to CTF.
>>
>>
>> == A new method for identifying CTF{nbsp}2 documents
>>
>> We suggest that all documents related to CTF{nbsp}2 bear a unique
>> **document identifier** (ID) having the following format:
>>
>> CTF2-<short name>-<major>.<minor>[r<revision>]
>>
>> [options="header"]
>> .Descriptions and roles of CTF{nbsp}2 document ID parts
>>|===
>>|Part |Description |Bump _may_ introduce new concepts, procedures, and formats?
>>||Bump _may_ remove or change existing concepts, procedures, and formats?
>>
>>|+<short{nbsp}name>+
>>|The capitalized short name of the document,
>> unique amongst all the CTF{nbsp}2 documents.
>>|N/A
>>|N/A
>>
>>|`<major>`
>>|The major version number of the document.
>>|Yes
>>|Yes
>>
>>|`<minor>`
>>|The minor version number of the document.
>>|Yes
>>|No
>>
>>|`<revision>`
>>|
>> The revision letter of the document (from `A` to `Z`).
>>
>> Document revisions are used to add examples, clarify existing concepts,
>> fix grammar or content mistakes, or reword existing parts, for example.
>>|No
>>|No
>>|===
>>
>> For example, the short name of this document is `PROP`, for _proposal_,
>> and its full document ID is `CTF2-PROP-1.0`. The next revision would be
>> `CTF2-PROP-1.0rA`, and the following would be `CTF2-PROP-1.0rB`.
>>
>> In any CTF{nbsp}2 document, another CTF{nbsp}2 document _must_ be
>> referred to by using only its ID. For example: _This concept is further
>> explained in did:CTF2-SOMEID-1.2_. There is no need to refer to a
>> specific revision: the reference always targets the latest document's
>> revision.
>>
>> We suggest the following IDs for the initial documents:
>>
>> * did:CTF2-DOCID-1.0: _CTF{nbsp}2 document identifier format_
>> * did:CTF2-SPEC-2.0: _The Common Trace Format (CTF), version 2.0_
>> * did:CTF2-BASICATTRS-1.0: _Basic CTF{nbsp}2 user attributes_
>> * did:CTF2-FS-1.0: _Layout of a CTF{nbsp}2 trace stored on a file system_
>> * did:CTF2-PMETA-1.0: _CTF{nbsp}2 metadata stream packet format_
>>
>>
>> == Why CTF{nbsp}2?
>>
>> Why do we need a major version bump of the CTF specification?
>>
>> A major version bump is never an easy choice when it comes to revisiting
>> a software library, a communication protocol, a file format, or anything
>> that serves as a contract between a producer and a consumer. When such a
>> decision is taken, it must be justified by solid arguments, since it
>> makes it impossible for old consumers to consume the product of new
>> producers.
>>
>> In this proposal, for instance, CTF{nbsp}2 traces are not backward
>> compatible with CTF{nbsp}1 traces. Although the binary format is not
>> changed, the metadata stream is written in a different language.
>>
>> CTF{nbsp}1 has been used and tested for many years now, by different
>> producers and consumers. Over that time, we have noted a few gaps in the
>> trace format, gaps that prevent us from extending CTF{nbsp}1 as much as
>> we would like, amongst other things. CTF{nbsp}2 is designed to overcome
>> those gaps, as far as we know them, and to be flexible enough to
>> gracefully accept future additions while avoiding another major version
>> bump in the following years.
>>
>>
>> [[design-goals]]
>> === Design goals
>>
>> The design goals of CTF{nbsp}2 are as follows, in order, beginning with
>> the most important:
>>
>> . **CTF{nbsp}2 data streams _must_ be backward compatible with
>> CTF{nbsp}1 data streams.**
>> +
>> Many applications are already programmed to write valid CTF{nbsp}1
>> packets. Modifying the code of those applications to produce different
>> binary packets can be cumbersome, and sometimes impossible if the
>> application passed acceptance tests, for example.
>> +
>> Making sure that applications producing CTF{nbsp}1 traces can also
>> produce CTF{nbsp}2 traces only by changing the metadata stream is an
>> absolute necessity.
>>
>> . **The CTF{nbsp}2 streams _must_ be as efficient as possible to produce
>> by a tracer.**
>> +
>> This design goal was also one of the major ones which motivated the
>> design of CTF{nbsp}1.
>> +
>> In other words, a small embedded system _must_ be able to produce
>> CTF{nbsp}2 streams natively. Moreover, the tracer _must_ be able to copy
>> binary data to the packet buffer of a data stream without altering it.
>>
>> . **CTF{nbsp}2's model _should_ be backward compatible
>> with CTF{nbsp}1's.**
>> +
>> Some APIs are already written to deal with CTF{nbsp}1 ``objects'', or
>> concepts (event record classes, event records, field types, and data
>> stream clock classes, to name a few). The model of CTF{nbsp}2 _should_
>> be compatible with the model of CTF{nbsp}1, so that those existing APIs
>> can operate on CTF{nbsp}2 objects too without requiring huge
>> refactorings.
>>
>> . **The size of any CTF{nbsp}2 static field, that is, any field with a
>> non-dynamic type, _must_ always be the same in data streams to speed
>> up the validation in some situations.**
>> +
>> In other words, a field described by a fixed-size type, or by a compound
>> type containing only fixed-size types, _should_ always have the same
>> size, no matter its offset in the data stream.
>> +
>> This guarantee allows, in certain situations, to greatly speed up the
>> validation process by having a great part of it done at the metadata
>> stream level.
>>
>> . **A CTF{nbsp}2 trace _should_ be as easy as possible to consume.**
>> +
>> CTF{nbsp}1 focuses on being easy to be produced, which is a good idea
>> since producers are tracers in this context, and a minimal tracer
>> _should_ be able to produce a correct CTF trace with minimal code
>> (design goal 2).
>> +
>> However, because CTF{nbsp}1's metadata stream is written in TSDL, a
>> custom, declarative, C-like DSL designed for CTF, writing a minimal
>> consumer of CTF{nbsp}1 is not an easy task. TSDL is an intricate
>> language, with many special cases, many of which are borrowed from the C
>> language, which cannot be ignored when writing a consumer supporting all
>> its features. TSDL was developed to ease the _manual_ (human) production
>> of metadata streams.
>> +
>> Over time, we realized that, while producing traces is important,
>> consuming them to solve problems by analysing the event records is just
>> as important, if not more.
>> +
>> This is why CTF{nbsp}2 _should_ encourage the development of CTF
>> consumers in any programming language by reducing the number of special
>> cases, as well as by using a very simple, yet well-known grammar for the
>> metadata stream.
>> +
>> CTF{nbsp}1 tries to accomodate other trace formats, which can be
>> converted to CTF without changing the data streams by writing the
>> matching metadata stream. This is also a source of special cases.
>> CTF{nbsp}2 _should_ build on binary trace conversion (from another,
>> non-CTF trace format to CTF{nbsp}2) rather than trying to accomodate
>> other formats.
>>
>> . **A CTF{nbsp}2 metadata stream _must_ be extensible by users and by
>> future minor revisions of the specification (forward compatibility).**
>> +
>> CTF{nbsp}1's TSDL grammar is pretty restrictive when it comes to
>> customizing existing blocks with user-defined attributes.
>> +
>> Many protocols and declarative languages support custom user data in
>> their payload. For example, HTML5 allows any element to have user
>> attributes by prefixing their names with `data-`.
>> +
>> A producer of CTF{nbsp}2 _should_ be able to add custom attributes to
>> almost any object defined by the specification. This allows standard
>> consumers to read any CTF{nbsp}2 trace and ignore unknown user
>> attributes, providing a ``bland'', yet complete view of the trace
>> fields, while special consumers can be written (or existing consumers
>> can be extended) to interpret specific user attributes and use them to
>> present a meaningful visualization.
>> +
>> It is also possible for the DiaMon Workgroup to publish a proposal for
>> new properties for a next minor revision of the specification, but test
>> them as temporary user attributes for some time in order to collect
>> comments before updating the specification itself.
>> +
>> This design goal also means that an ``old'' CTF{nbsp}2 consumer _should_
>> be able to decode a ``new'' CTF{nbsp}2 trace, possibly with missing
>> field semantics if field types are added in minor revisions.
>>
>> . **CTF{nbsp}2's specification _must_ focus on how to encode and decode
>> data streams.**
>> +
>> CTF{nbsp}1 has a few base properties in its metadata stream that are not
>> strictly needed to encode or decode data streams. For example, the
>> `base` property of the `integer` field type is only useful to visualize
>> the decoded integer fields: the decoding process does not depend on a
>> preferred radix. Also, the name of an event record class is not needed
>> to decode the event records it describes: only its numeric ID is needed
>> to select the appropriate context and payload field types to use for the
>> encoding/decoding process.
>> +
>> All the object properties defined by the CTF{nbsp}2 specification
>> document _should_ exist only because they have a role in the
>> encoding/decoding process. Everything else _should_ be delegated to
>> other documents which define optional extension layers using the
>> mechanisms designed as a response to design goal 6.
>>
>> . **CTF{nbsp}2's specification _must not_ specify how to transport a
>> trace, nor how a trace should be stored.**
>> +
>> In the CTF{nbsp}2 specification, a CTF{nbsp}2 trace _should_ be defined
>> as a set of bit streams, without specifying how those streams are
>> transported or stored. Other official documents published by the DiaMon
>> Workgroup can define standard ways to support and transport CTF{nbsp}2
>> streams for specific use cases. Trace producers and consumers can choose
>> to implement one or more transport/storage mechanisms by following the
>> other documents.
>>
>>
>> == Changes since CTF{nbsp}1
>>
>> Here is a brief summary of the changes, from CTF{nbsp}1 to CTF{nbsp}2,
>> introduced by this proposal.
>>
>> * The terminology of the specification and the binary layouts of the
>> data streams are **completely detached from the C language** and from
>> the behaviour of any C compiler.
>> +
>> CTF{nbsp}2 is a programming language-agnostic trace format.
>>
>> * **Terminology update**:
>> ** _Binary stream_ → _data stream_.
>> ** _Trace_ → _trace class_, when it names a block of
>> metadata which describes traces.
>> ** _Stream_ → _data stream class_, when it names a
>> block of metadata which describes data streams.
>> ** _Stream ID_ → _data stream class ID_.
>> ** _Stream instance ID_ → _data stream ID_.
>> ** _Event_ → _event record class_, when it names a
>> block of metadata which describes event records.
>> ** _Event ID_ → _event record class ID_.
>> ** _Event_ → _event record_, when it names an actual
>> recorded event contained in a packet.
>> ** _Declaration_ → _field type_.
>> ** _Type alias_ → _field type alias_.
>> ** _Clock_ → _data stream clock class_, when it names a
>> block of metadata which describes actual data stream clocks.
>> ** _Clock_ → _data stream clock_, when it names a
>> per-data stream instance of a specific data stream clock class.
>> ** _Native byte order_ → _default byte order_.
>> ** _Stream packet context_ → _data stream packet context_.
>> ** _Stream event header_ → _data stream event record header_.
>> ** _Stream event context_ → _data stream event record context_.
>> ** _Event context_ → _event record context_.
>> ** _Event fields_ → _event record payload_.
>> ** _Events discarded_ → _discarded event record count_.
>> ** _Packet size_ → _packet's total size_.
>> ** _Content size_ → _packet's content size_.
>> * **The <<metadata-stream,metadata stream>> is written in JSON.** JSON
>> values are used to represent <<metadata-types,metadata types>>, the
>> internal type system of the CTF{nbsp}2 metadata.
>> * The CTF{nbsp}2 specification **does not specify a ``packetized''
>> metadata stream format**. This is a back-end-specific way of wrapping
>> a <<metadata-stream,metadata stream>> as defined in this document.
>> Another document specifies the packetized metadata stream format,
>> which can be used by standard storage and transport documents if
>> needed.
>> * Most objects (called mdt:map values) of the CTF{nbsp}2 metadata model
>> _may_ contain **<<user-attrs,custom user attributes>>**.
>> * **Properties that are not strictly needed to _encode_ or _decode_ the
>> data streams are defined as user attributes in other documents.**
>> This includes, but is not limited to, the trace's environment,
>> the event record class's name and log level, and the integer field
>> type's preferred display base (CTF{nbsp}1's `base` property).
>> * **New field types**:
>> ** A <<bitarray-field-type,**bit array** field type>> describes the most
>> primitive fields of a data stream actually holding values.
>> +
>> An integer field type is now defined as a bit array field type with a
>> signedness property.
>> +
>> A floating point number field type is now defined as a bit array field
>> type: its size property is enough to determine its encoding under
>> {ieee754}.
>>
>> ** A <<null-field-type,**null** field type>>, which represents
>> nonexistent, or missing fields. The intended use of this field type
>> is as one of the possible types of a variant field type, especially
>> when representing the types of a dynamically-typed language using a
>> variant field type.
>> +
>> This field type _should_ be used to represent Python's `None`, Java's
>> and JavaScript's `null`, and Ruby's `nil`, for example.
>>
>> ** A <<bool-field-type,**boolean** field type>>, which is a bit array
>> field type with a special meaning. When all the bits of a boolean
>> field are cleared, the field's value is said to be _false_.
>> Otherwise, the field's value is said to be _true_.
>> ** A <<varbitarray-field-type,**variable-length bit array** field
>> type>>. Each byte of a field having this type has its most
>> significant bit set if one more byte must be encoded. The 7 low-order
>> bits of each byte are concatenated in a specific way to form the
>> final, equivalent bit array.
>> ** A <<varbool-field-type,**variable-length boolean** field type>>, a
>> <<varint-field-type,**variable-length integer** field type>>, and a
>> <<varenum-field-type,**variable-length enumeration** field type>>,
>> which use the encoding mechanism of the variable-length bit array
>> field type.
>> ** A <<textarray-field-type,**text array** field type>> and a
>> <<textsequence-field-type,**text sequence** field type>>, which are
>> specialized versions of the array field type and sequence field type
>> with a byte as the element field type. Text array and sequence fields
>> hold possibly null-terminated UTF-8 string values.
>> ** A <<union-field-type,**union** field type>>, which provides a list of
>> one or more field types, each of which is an alternative
>> representation of the same binary field.
>> +
>> This mechanism _may_ be used to add field types in minor revisions of
>> CTF{nbsp}2, while still ensuring the forward compatibility of ``old''
>> consumers.
>>
>> * **Modified field types**:
>> ** All CTF{nbsp}2 field types have an **alignment** property. Some field
>> types, however, impose alignment constraints to match the constraints
>> of CTF{nbsp}1's field types and to make consumers easier to develop.
>> ** The default alignment of an <<int-field-type,integer field type>>
>> is{nbsp}1. It used to be{nbsp}8 if the size is a multiple of{nbsp}8,
>> and{nbsp}1 otherwise, in CTF{nbsp}1.
>> ** The **`base` and `encoding` properties are removed** from the
>> <<int-field-type,integer field type>>. The `encoding` property is
>> used in CTF{nbsp}1 to indicate that a byte is a UTF-8 character, for
>> example, but since some UTF-8 characters are encoded on more than one
>> byte, this property makes no sense here. The new
>> <<textarray-field-type,text array field type>> and the
>> <<textsequence-field-type,text sequence field type>> _may_ be used to
>> achieve the same result instead.
>> ** The **`exp` and `mant` properties are removed** from the
>> <<float-field-type,floating point number field type>>. As mentioned
>> above, a floating point number field type is now defined as a bit
>> array field type, which has a `size` property to indicate its total,
>> fixed size, in bits. A floating point number field encoded following
>> {ieee754} can be decoded knowing only this parameter, the storage
>> width of the bit array, from which other parameters can be deduced
>> according to the standard.
>> +
>> In other words, as far as CTF{nbsp}1's floating point number field type
>> is following {ieee754} for encoding its fields, only specific pairs of
>> `exp` and `mant` properties are valid: 8 and 24, 11 and 53, 15 and 113,
>> 20 and 237, and so on.
>>
>> ** The **`encoding` property** of the <<string-field-type,string field
>> type>> **is removed**. CTF{nbsp}2 string fields always contain a
>> sequence of bytes which encode a string with UTF-8. If a string is
>> encoded with the `ascii` encoding in a CTF{nbsp}1 data stream, it's
>> still valid in CTF{nbsp}2 since an ASCII string is a UTF-8 string.
>>
>> * The mechanism by which a relative variant field type's tag or sequence
>> field type's length is searched for in preceding scopes (trace packet
>> size, data stream packet context, event record context, event record
>> payload, etc.) when it's not found in the current scope is removed. It
>> has not be shown to be useful and it adds complexity to consumers. It
>> is always possible to convert a CTF{nbsp}1 metadata stream using this
>> behaviour to a CTF{nbsp}2 metadata stream not using it.
>> * **``Special'' fields**, such as the magic number field, the data
>> stream class ID field, and the packet's total size field, **can have
>> any name**: they are _tagged_ with specified tag names by the producer
>> for the consumer to know that they have a special meaning without
>> relying on reserved names like CTF{nbsp}1's `magic`, `stream_id`, and
>> `packet_size`.
>> +
>> With this mechanism, it's possible for a field to be tagged multiple
>> times, with different meanings.
>>
>> * The frequency of a <<data-stream-clock-class-fragment,data stream
>> clock class>> no longer defaults to the arbitrary 1{nbsp}GHz (it's a
>> mandatory property).
>> * There is no more lexical scopes to limit the scope of field type
>> aliases and other definitions. <<field-type-alias-fragment,Field type
>> aliases>> must have unique names within the whole metadata stream.
>>
>>
>> == CTF{nbsp}2 actors
>>
>> There are two main _actors_ when it comes to tracing:
>>
>> Producer::
>> A software or hardware system which produces (writes) the streams of a
>> trace.
>> +
>> A trace producer is often called a _tracer_.
>> +
>> A producer is only concerned with how to write the metadata stream and
>> how to encode supported values as CTF{nbsp}2 data fields and serialize
>> them to one or more data streams.
>>
>> Consumer::
>> A software or hardware system which consumes (reads) the streams of a
>> trace.
>> +
>> A trace consumer is often called a _trace viewer_ or a _trace analyzer_.
>> +
>> A consumer is only concerned with how to read and interpret the metadata
>> stream, and how to deserialize CTF{nbsp}2 data fields from data streams
>> and decode them to retrieve the values they represent.
>>
>> Note that a piece of software can be both a consumer and a producer.
>> This is the case of a trace converter, for example.
>>
>>
>> == What is a CTF{nbsp}2 trace?
>>
>> A _CTF{nbsp}2 trace_ is a set of zero or more <<data-streams,data
>> streams>> and exactly one <<metadata-stream,metadata stream>>.
>>
>> The data streams contain actual packets of event records, while the
>> metadata stream contains information on how to interpret the data
>> streams of the same trace.
>>
>> The support or transport of data streams and the metadata stream is not
>> specified. A stream _may_ be serialized as a single file on a file
>> system, or it _may_ be sent over the network using TCP, to name a few
>> examples. The mechanism to identify the metadata stream amongst the
>> streams of a trace is also not specified.
>>
>>
>> [[metadata-types]]
>> === Metadata types
>>
>> Many of the following sections of this document describe the _required_
>> and _optional_ properties of _metadata mdt:map values_. All the metadata
>> mdt:map values can be represented using a defined set of types. The
>> values allowed by those types have no specific textual or binary
>> representation.
>>
>> To avoid any confusion with field types and JSON types, the `m-` prefix
>> is used before the names of the metadata types. An **m-value** is any
>> value allowed by any of the following types.
>>
>> [NOTE]
>> .Not to be confused with _field types_!
>> ====
>> The metadata types define the possible values that can be used to define
>> the metadata mdt:map values, for example:
>>
>> * Integer field type mdt:map
>> * Structure field type mdt:map
>> * Event record class mdt:map
>> * Data stream class mdt:map
>>
>> As an example, here's a JSON representation of a possible integer field
>> type mdt:map:
>>
>> [source,json]
>> ----
>> {
>> "field-type": "int",
>> "size": 23,
>> "alignment": 16
>> }
>> ----
>>
>> Here:
>>
>> * The whole JSON object represents an mdt:map value.
>> * `"field-type"` represents an mdt:string value, which is an mdt:map key
>> here.
>> * `23` represents an mdt:number value.
>>
>> The whole mdt:map value represents an integer field type. This integer
>> field type can be used to encode and decode integer values to and from
>> binary data fields, depending on where exactly this mdt:map is placed
>> within the whole <<metadata-array,metadata mdt:array>>.
>> ====
>>
>> The metadata types are:
>>
>> mdt:null::
>> Nullable type: the only possible value of this type is the _null_
>> value.
>>
>> mdt:bool::
>> Boolean type, that is, the following set of values:
>> +
>> --
>> * _True_
>> * _False_
>> --
>>
>> mdt:int::
>> Integer type, that is, the set of all the negative and positive
>> integer values.
>>
>> mdt:number::
>> Number type, that is, the set of all the rational numbers that can be
>> represented with the
>> https://en.wikipedia.org/wiki/Decimal_representation[decimal
>> representation].
>>
>> mdt:string::
>> String type, that is, the set of all the possible finite sequences of
>> Unicode characters, including the zero-length sequence.
>>
>> mdt:array::
>> Array type, that is, the set of all the possible finite sequences of
>> any m-values, including the zero-length sequence.
>>
>> mdt:map::
>> Unordered map type, that is, the set of all the possible sets of
>> (mdt:string value, m-value) pairs, including the zero-length set. The
>> mdt:string value in a given pair is called the _key_ of the
>> association. An association _may_ also be called a _property_.
>>
>> NOTE: For reasons of brevity and style, the word _value_ after a
>> metadata type name is sometimes discarded in this text. For example,
>> _you can use an mdt:int to..._ means _you can use an mdt:int value
>> to..._.
>>
>>
>> [[json]]
>> === Bidirectional association between metadata types and JSON values
>>
>> The <<metadata-types,metadata types>> can be bidirectionally mapped to
>> http://json.org/[JSON] values as follows:
>>
>> .Bidirectional association between metadata types and JSON values
>> [options="header"]
>>|===
>>|Metadata type |JSON values
>>
>>|mdt:null
>>|
>> The _null_ m-value is mapped to the JSON `null` value.
>>
>>|mdt:bool
>>|
>> The _true_ and _false_ m-values are mapped to the `true` and `false`
>> JSON values respectively.
>>
>>|mdt:int
>>|
>> Any allowed m-value is mapped to a JSON number without a
>> fractional part or to a <<const-int,constant integer JSON object>>.
>>
>>|mdt:number
>>|
>> Any allowed m-value is mapped to a JSON number or to
>> a <<const-int,constant integer JSON object>>.
>>
>>|mdt:string
>>|
>> Any allowed value is mapped to a JSON string.
>>
>>|mdt:array
>>|
>> Any finite sequence is mapped to a JSON array, where each
>> m-value is mapped to a JSON value using this table.
>>
>>|mdt:map
>>|
>> Any set of associations is mapped to a JSON object, where each pair's
>> mdt:string value is mapped to a key (JSON string, using this table) in
>> this JSON object, and its associated m-value is mapped to a JSON value
>> using this table and associated to this key.
>>|===
>>
>> All the examples of m-values in this document use this mapping to show
>> textual representations.
>>
>>
>> [[const-int]]
>> ==== Constant integer JSON object
>>
>> Unfortunately, JSON does not support binary, octal, or hexadecimal
>> constant integers. Also, it is known that some JSON parsers have a
>> limited support for big integers (generally, integer values which do not
>> fit a 64-bit representation). A constant integer JSON object can
>> represent an mdt:int value or an mdt:number value without a fractional
>> part.
>>
>> It is _recommended_ to use a constant integer JSON object instead of a
>> JSON number when the mdt:int or mdt:number value to represent is lesser
>> than -9223372036854775808 or greater than 9223372036854775807 (signed
>> 64-bit range).
>>
>> .Constant integer JSON object properties
>> [options="header"]
>>|===
>>|Name |Allowed JSON values |Description |Required? |Default value
>>
>>|`base`
>>|`2`, `8`, `10`, and `16`
>>|Radix of the number.
>>|Optional
>>|`10`
>>
>>|`value`
>>|JSON string
>>|
>> Integer's value using the digits allowed by the base, _without_ the
>> typical `0b`/`0`/`0x` prefix. The string _may_ be prefixed with `-`
>> (U+002D) if the value is negative.
>>|Required
>>|
>>|===
>>
>> .Constant integer JSON object: positive decimal integer
>> ====
>> Equivalent to 2876321721982327:
>>
>> [source,json]
>> {"value": "2876321721982327"}
>> ====
>>
>> .Constant integer JSON object: negative binary integer
>> ====
>> Equivalent to -253339:
>>
>> [source,json]
>> {"base": 2, "value": "-111101110110011011"}
>> ====
>>
>> .Constant integer JSON object: positive octal integer
>> ====
>> Equivalent to 420:
>>
>> [source,json]
>> {"base": 8, "value": "644"}
>> ====
>>
>> .Constant integer JSON object: positive hexadecimal integer
>> ====
>> Equivalent to 3735928559:
>>
>> [source,json]
>> {"base": 16, "value": "deadbeef"}
>> ====
>>
>> .Constant integer JSON object: negative decimal integer
>> ====
>> Equivalent to -2317:
>>
>> [source,json]
>> {"value": "-2317"}
>> ====
>>
>>
>> [[metadata-array]]
>> === Metadata mdt:array
>>
>> The metadata mdt:array is an mdt:array of **fragments** which contains
>> all the metadata information of a given trace.
>>
>> A fragment is an m-value.
>>
>> A fragment is either:
>>
>> * The version fragment, that is, an mdt:string which is always `CTF 2`.
>> * One of the other allowed fragments, which are described in the upper
>> layers of CTF{nbsp}2.
>>
>> The first fragment in the metadata mdt:array is always the version
>> fragment. It is followed by one or more fragments, as described by the
>> upper layers of CTF{nbsp}2.
>>
>>
>> [[metadata-stream]]
>> === Metadata stream
>>
>> A _metadata stream_ is the <<json,JSON representation>> of a
>> <<metadata-array,metadata mdt:array>>, that is, a UTF-8 JSON array which
>> is written by the producer to describe the data streams of the same
>> trace.
>>
>> The rationale for choosing JSON over another representation, for example
>> TSDL (CTF{nbsp}1's metadata language), is as follows:
>>
>> . JSON can represent all the possible m-values using the
>> <<json,m-value to JSON value assocation table>>.
>> . JSON is a simple language to consume. A very basic JSON parser
>> can be written in a few hundred lines of C code. Moreover, tested
>> and documented JSON parsers exist for all the major programming
>> languages.
>> . JSON is a very simple language to produce.
>> . JSON strings support Unicode.
>>
>> One of the <<design-goals,design goals>> of CTF{nbsp}2 is to make
>> consumption as easy as possible. Relieving the burden of implementing a
>> custom TSDL parser is a substantial part of how this goal is achieved.
>>
>> Keep in mind that this JSON metadata is expected to be generated by
>> machines, thus shortcuts that would save time to human beings are
>> avoided in favor of easier consumption, but without compromising easy
>> and fast machine generation.
>>
>>
>> [[data-streams]]
>> === Data streams
>>
>> A CTF{nbsp}2 _data stream_ is a sequence of packets.
>>
>> Each packet starts with an _optional_ header field followed by an
>> _optional_ context field, after which is a sequence of event records.
>>
>> An event record starts with an _optional_ header, followed by an
>> _optional_ context field defined at the data stream class level,
>> followed by an _optional_ context field defined at the event record
>> class level, followed by an _optional_ payload field. An event record's
>> total binary size _must_ be greater than 0.
>>
>>
>> === Summary
>>
>> A _CTF{nbsp}2 trace_ is a set of:
>>
>> * One <<metadata-stream,metadata stream>>, which is the UTF-8 JSON
>> representation of a <<metadata-array,metadata mdt:array>>. A metadata
>> mdt:array is an mdt:array containing fragments. Fragments are m-values
>> which describe properties of the trace and the binary layouts of its
>> various parts.
>> * Zero or more <<data-streams,data streams>>. A data stream contains
>> packets. A packet contains event records. The layout of packet headers
>> and contexts, and of event record headers, contexts, and payloads, are
>> described by the metadata stream of the same trace.
>>
>>
>> == Structure of the CTF{nbsp}2 specification
>>
>> We suggest that the concepts of CTF{nbsp}2 be presented in the
>> specification document as **three layers**:
>>
>> . The first layer, named the <<ctffer,CTF{nbsp}2 field encoding rules>>
>> (CTFFER), shows **how to encode common programming language values as
>> binary data fields according to the their descriptions, field types**.
>> This is a serialization protocol. This is the foundation of
>> CTF{nbsp}2, in that the other layers need data fields to have any
>> meaning. This layer is independent of the tracing domain, in that it
>> can be used to encode any self-described bit stream for any
>> application.
>>
>> . The <<layer-2,second layer>> adds the concept of **packets** and
>> **event records**, and how different layouts of packet header and
>> context fields, and of event record header, context, and payload
>> fields, _may_ exist within different data streams and event records of
>> the same trace thanks to **data stream class fragments** and **event
>> record class fragments** in the metadata stream.
>> +
>> This layer also introduces the field type alias fragment and the trace
>> class fragment.
>>
>> . The <<layer-3,third layer>> adds the concept of **time** (clocks).
>> Clocks are essential data stream variables in a CTF{nbsp}2 trace
>> because they associate event records and packets with one or more
>> points in time. Data stream clocks are sampled by the producer when
>> writing specific, regular data fields. They are updated by the
>> consumer when reading the corresponding fields. Data stream clocks are
>> described by **data stream clock class fragments** in the metadata
>> stream.
>>
>> CTF{nbsp}2 is designed so that each layer _may_ be implemented in its
>> own software package. This structure separates the concepts of
>> CTF{nbsp}2 into different sections of the text, making it more easy to
>> read. This structure should also make testing more easy.
>>
>> Each layer depends on the previous one.
>>
>>
>> === Compliance
>>
>> A _CTF{nbsp}2 producer_, either a piece of software or a machine,
>> _must_ implement the first two layers of did:CTF2-SPEC-2.0.
>>
>> A _CTF{nbsp}2 consumer_, either a piece of software or a machine,
>> _must_ implement all three layers of did:CTF2-SPEC-2.0.
>>
>>
>> [[ctffer]]
>> == Layer 1: CTF{nbsp}2 field encoding rules (CTFFER)
>>
>> The _CTF{nbsp}2 field encoding rules_, or CTFFER, dictate how to
>> serialize a _value_ to a binary data field by using the properties of a
>> _field type_, that is, an mdt:map which describes a set of possible
>> binary data field values. The field type can later be used to
>> deserialize a data field back to a value.
>>
>> The representation of a _value_ depends on the programming language in
>> which the CTF{nbsp}2 producer or consumer is written here. For example,
>> a producer written in C _may_ serialize an `int` variable as a
>> CTF{nbsp}2 integer field described by an <<int-field-type,integer field
>> type>> having the appropriate size, alignment, byte order, and
>> signedness properties to accommodate any value that an `int` variable
>> could hold for a specific architecture (32-bit for IA-32 and 16-bit for
>> AVR, for example). However, since a Python{nbsp}3 `int` object can hold
>> any integer value, a better choice for a Python{nbsp}3 producer would be
>> to serialize such an object as a CTF{nbsp}2 variable-length integer
>> field described by a <<varint-field-type,variable-length integer field
>> type>>.
>>
>> The following subsections only describe how to encode values as binary
>> fields by using field types. The specification does not suggest specific
>> field type configurations. It is up to the producer side to choose
>> appropriate field type properties depending on its environment. The
>> procedures to encode values presented in the following subsections are
>> very generic: they take no account of optimizations that would be
>> possible in specific situations. For example, it is often possible, in
>> programming languages which are aware of their memory layout, to encode
>> a whole complex structure of values by a simple memory copy to the data
>> stream, as far as appropriate field types are used to describe this
>> exact memory layout for further correct decoding. It is in order to
>> satisfy those situations, which support faster producers, that field
>> types are flexible: a produder can encode some value in various ways by
>> choosing the resulting field's alignment, byte order, size, and the rest
>> within the data stream destination.
>>
>> The values which can be encoded are:
>>
>> Null values::
>> A value with no size, which usually represents missing or unknown
>> data.
>>
>> Bit array values::
>> A finite sequence of contiguous bits without a specific meaning. The
>> required size, in bits, to represent a bit array value can be known
>> statically or dynamically.
>>
>> Boolean values::
>> A bit array value which is either _false_ (all bits are cleared) or
>> _true_ (anything else).
>>
>> Integer values::
>> A bit array value which represents an integer (signed or not).
>>
>> Number values::
>> A real number which can be represented with {ieee754}.
>>
>> Enumeration values::
>> An integer value with an associated label (known by its type).
>>
>> String values::
>> A finite sequence, with a length known dynamically, of Unicode
>> characters.
>>
>> Structure values::
>> A finite sequence of values of different types.
>>
>> Array values::
>> A finite sequence, with a length known statically, of values sharing
>> the same type.
>>
>> Sequence values::
>> A finite sequence, with a length known dynamically, of values sharing
>> the same type.
>>
>> The CTFFER also support _variant_ and _union_ fields. A variant field is
>> an encoded value of a given type amongst many possible types. This type
>> is dynamically chosen by a tag (a previously encoded enumeration value).
>> A union field is a data field which represents, at the same time,
>> different values of different types.
>>
>>
>> [[byte-order]]
>> === Byte order mdt:string
>>
>> A _byte order mdt:string_ is one of the following values:
>>
>> `default`::
>> Use default byte order.
>>
>> `be`::
>> Big-endian.
>>
>> `le`::
>> Little-endian.
>>
>> CTF{nbsp}2 does not support middle or mixed endianness.
>>
>>
>> [[user-attrs]]
>> === User attributes mdt:map
>>
>> Many metadata mdt:map values described in this document may have a
>> `user-attrs` property, which _must_ be set to an mdt:map, if set at all.
>>
>> Each key of the user attributes mdt:map is a **namespace**. The value of
>> a given key is the custom user attribute within this namespace (any
>> m-value is valid).
>>
>> The format of a namespace is not specified. It is _recommended_ to use a
>> URI, or at least to include a domain name owned by the organization
>> defining the attributes nested under this namespace. A UUID is also a
>> rational option.
>>
>> What to do with those user attributes from a consumer's standpoint is
>> not specified by this document. The values of those attributes are _not_
>> needed to decode the CTF data streams, and _may_ be safely ignored by
>> any CTF{nbsp}2 consumer.
>>
>> It is expected that ``industrial standards'' defining sets of useful
>> attributes within given namespaces will emerge naturally over time.
>> Producers and consumers supporting the same attributes can enhance the
>> experience of the whole tracing ecosystem.
>>
>> It is expected that user attributes usually fall into one of the
>> following categories:
>>
>> * **Model**: Information about the application data model of an object.
>> * **Textual style**: Style attributes/hints that could be applied to a
>> textual rendering of the object (color, font attributes, print format,
>> etc.).
>> * **Graphical style**: Style attributes/hints that could be applied to a
>> graphical output of the object.
>>
>> .User attributes mdt:map with namespace `diamon.org/ctf/ns/std`
>> ====
>> JSON representation:
>>
>> [source,json]
>> {
>> "diamon.org/ctf/ns/std": {
>> "base": 16
>> }
>> }
>> ====
>>
>> .User attributes mdt:map with different namespaces
>> ====
>> JSON representation:
>>
>> [source,json]
>> {
>> "diamon.org/ctf/ns/std": {
>> "name": "sched_switch",
>> "ns": "lttng.org/ctf-ns/modules/2.9"
>> },
>> "lttng.org/ctf-ns": {
>> "tmp-event": true,
>> "ignore-ip": true
>> }
>> }
>> ====
>>
>> .User attributes mdt:map with namespace `mytracer.org/ctf-ns/hints`
>> ====
>> JSON representation:
>>
>> [source,json]
>> {
>> "mytracer.org/ctf-ns/hints": {
>> "format-string": "{src} sent {size} bytes to {dst} at {addr}"
>> }
>> }
>> ====
>>
>> Although _not recommended_, an empty mdt:string is a valid namespace:
>>
>> .User attributes mdt:map with empty namespace
>> ====
>> JSON representation:
>>
>> [source,json]
>> {
>> "": {
>> "my-option": 23,
>> "include": ["this", "and", "that"]
>> }
>> }
>> ====
>>
>> The value of user attributes for a given namespace need not be an
>> mdt:map:
>>
>> .User attributes mdt:map with an mdt:number attribute
>> ====
>> JSON representation:
>>
>> [source,json]
>> {
>> "my namespace": -17.22
>> }
>> ====
>>
>>
>> [[scope]]
>> === Scope
>>
>> A _scope_ is a specific field within a data stream. The exact location
>> of a scope within a data stream depends on the current encoding context.
>> The upper layer defines which scopes are available in its context and
>> how to find them by name (mdt:string).
>>
>>
>> [[field-path]]
>> === Field path m-value
>>
>> A _field path m-value_, used by <<sequence-field-type,sequence>> and
>> <<variant-field-type,variant>> field types, is a path leading to a
>> previously encoded data field by ``digging'' into structure and union
>> fields. It can be either _relative_ (starting from a known field), or
>> _absolute_ (starting from a user-specified scope field).
>>
>>
>> [[abs-field-path]]
>> ==== Absolute field path mdt:map
>>
>> An _absolute field path mdt:map_ defines a field path from a specific
>> scope.
>>
>> .Absolute field path mdt:map properties
>> [options="header"]
>>|===
>>|Name |Type |Description |Required? |Default m-value
>>
>>|`scope`
>>|mdt:string
>>|Name of the scope.
>>|Required
>>|
>>
>>|`path`
>>|mdt:array of mdt:string values
>>|Field names, from the scope's root field, to follow to reach the
>> desired field (last element of this path).
>>|Required
>>|
>>|===
>>
>> The `path` property _may_ be empty: this targets the scope field itself.
>>
>> .Absolute field path mdt:map
>> ====
>> JSON representation:
>>
>> [source,json]
>> {
>> "scope": "data-stream-packet-context",
>> "path": ["path", "to", "cpu_id"]
>> }
>> ====
>>
>>
>> ==== Relative field path mdt:array
>>
>> A _relative field path mdt:array_ is an mdt:array of field names
>> (mdt:string values) to follow, starting from the sequence/variant field
>> using the field path.
>>
>> .Relative field path array
>> ====
>> JSON representation:
>>
>> [source,json]
>> ----
>> ["path", "to", "cpu_id"]
>> ----
>> ====
>>
>>
>> ==== Field lookup mechanism
>>
>> Field path elements are names of _structure_ or _union_ fields. If one
>> of those fields is a variant field, then the lookup _must_ recursively
>> find the variant's current field.
>>
>> For example, let's say we have the following scope named `my-scope`
>> (_FT_ means _field type_):
>>
>> a: int FT
>> b: struct FT
>> v: variant FT
>> choice1: int FT
>> choice2: int FT
>> choice3: struct FT
>> a: int FT
>> b: float FT
>> choice4: enum FT
>> i: int FT
>>
>> All the following field path m-values are valid sequence field type
>> lengths here:
>>
>> * Trivial:
>> +
>> --
>> [source,json]
>> {
>> "scope": "my-scope",
>> "path": ["a"]
>> }
>> --
>> +
>> and
>> +
>> --
>> [source,json]
>> {
>> "scope": "my-scope",
>> "path": ["b", "i"]
>> }
>> --
>>
>> * If `choice1`, `choice2`, or `choice4` is selected
>> in `v` when performing the lookup:
>> +
>> --
>> [source,json]
>> {
>> "scope": "my-scope",
>> "path": ["b", "v"]
>> }
>> --
>>
>> * If `choice3` is selected in `v` when performing the lookup:
>> +
>> --
>> [source,json]
>> {
>> "scope": "my-scope",
>> "path": ["b", "v", "a"]
>> }
>> --
>>
>> Relative field paths are looked up by going back into the current
>> structure/union field, and then back into the current structure/union
>> field's parent structure/union field, and so on. For example:
>>
>> z: int FT <------------------------------------.
>> y: struct FT |
>> a: int FT |
>> b: struct FT |
>> c: int FT |
>> d: string FT |
>> e: struct FT |
>> f: int FT <----------------------------. |
>> g: int FT | |
>> h: int FT | |
>> i: struct FT | |
>> j: int FT | |
>> k: sequence FT, length: ["b", "e", "f"] -' |
>> x: sequence FT, length: ["z"] -----------------'
>>
>>
>> [[enc-ctx]]
>> === Encoding context
>>
>> We define a _current encoding head_, an integer variable which is
>> initialized by the upper layer before encoding a value to a data field.
>> This variable is the current position of the writing ``head''.
>>
>> When a bit array is written, the current encoding head is updated by
>> adding the written size to it.
>>
>> Before encoding a value as a data field, the current encoding head
>> _must_ be **aligned** to respect the alignment requirements of said
>> field (given by its field type). The following operation can be used to
>> update the current encoding head _p_ to the beginning of a field with an
>> effective alignment of _a_ (bits):
>>
>> p = (p + a - 1) & -a
>>
>> For example, if the current encoding head is 37 and the alignment of the
>> next field to write is 8, then the current encoding head _must_ be
>> updated to 40 before writing the field. If the current encoding head is
>> 48 and the alignment of the next field to write is 8, then the current
>> head is already aligned.
>>
>>
>> [[field-type-m-value]]
>> === Field type m-value
>>
>> A _field type m-value_ can be either an mdt:string value or an mdt:map
>> value:
>>
>> * If it's an mdt:string value, it is the name of a field type alias. The
>> upper layer has a mapping of field type alias names to complete field
>> types (mdt:map values).
>> +
>> --
>> .Field type alias
>> ====
>> JSON representation:
>>
>> [source,json]
>> "my alias"
>> ====
>> --
>>
>> * [[field-type-m-map]]If it's an mdt:map value, it has the following
>> base properties:
>> +
>> --
>> .Field type mdt:map properties
>> [options="header"]
>>|===
>>|Name |Type |Description |Required? |Default m-value
>>
>>|`field-type`
>>|mdt:string
>>|Field type's class.
>>|Required
>>|
>>
>>|`user-attrs`
>>|<<user-attrs,User attributes mdt:map>>
>>|User attributes.
>>|Optional
>>|Empty mdt:map value.
>>
>>|`alignment`
>>|mdt:int
>>|Field's alignment (_must_ be a power of two, greater than 0).
>>|Optional
>>|1
>>|===
>> --
>> +
>> The following table summarizes the available field types:
>> +
>> --
>> .Available field types
>> [options="header"]
>>|===
>>|`field-type` property (mdt:string) |Name |Inherits properties from
>>
>>|`null`
>>|<<null-field-type,Null field type>>.
>>|<<field-type-m-map,Field type m-map>>.
>>
>>|`bitarray`
>>|<<bitarray-field-type,Bit array field type>>.
>>|<<field-type-m-map,Field type m-map>>.
>>
>>|`bool`
>>|<<bool-field-type,Boolean field type>>.
>>|<<field-type-m-map,Field type m-map>>.
>>
>>|`int`
>>|<<int-field-type,Integer field type>>.
>>|<<bitarray-field-type,Bit array field type>>.
>>
>>|`float`
>>|<<float-field-type,Floating point number field type>>.
>>|<<bitarray-field-type,Bit array field type>>.
>>
>>|`enum`
>>|<<enum-field-type,Enumeration field type>>.
>>|<<int-field-type,Integer field type>>.
>>
>>|`varbitarray`
>>|<<varbitarray-field-type,Variable-length bit array field type>>.
>>|<<field-type-m-map,Field type m-map>>.
>>
>>|`varbool`
>>|<<varbool-field-type,Variable-length boolean field type>>.
>>|<<varbitarray-field-type,Variable-length bit array field type>>.
>>
>>|`varint`
>>|<<varint-field-type,Variable-length integer field type>>.
>>|<<varbitarray-field-type,Variable-length bit array field type>>.
>>
>>|`varenum`
>>|<<varenum-field-type,Variable-length enumeration field type>>.
>>|<<varint-field-type,Variable-length integer field type>>.
>>
>>|`string`
>>|Null-terminated UTF-8 <<string-field-type,string field type>>.
>>|<<field-type-m-map,Field type m-map>>.
>>
>>|`struct`
>>|<<struct-field-type,Structure field type>>.
>>|<<field-type-m-map,Field type m-map>>.
>>
>>|`array`
>>|<<array-field-type,Array field type>>.
>>|<<field-type-m-map,Field type m-map>>.
>>
>>|`textarray`
>>|<<textarray-field-type,Text array field type>>.
>>|<<field-type-m-map,Field type m-map>>.
>>
>>|`sequence`
>>|<<sequence-field-type,Sequence field type>>.
>>|<<field-type-m-map,Field type m-map>>.
>>
>>|`textsequence`
>>|<<textsequence-field-type,Text sequence field type>>.
>>|<<field-type-m-map,Field type m-map>>.
>>
>>|`variant`
>>|<<variant-field-type,Variant field type>>.
>>|<<field-type-m-map,Field type m-map>>.
>>
>>|`union`
>>|<<union-field-type,Union field type>>.
>>|<<field-type-m-map,Field type m-map>>.
>>|===
>> --
>> +
>> Note that, on the decoding side, any unknown field type must be ignored,
>> and any unknown field type mdt:map property must also be ignored.
>>
>>
>> [[null-field-type]]
>> ==== Null field type
>>
>> A _null field type_ describes null fields.
>>
>> A null value usually represents missing or unknown data.
>>
>> .Null field type mdt:map properties
>> [options="header"]
>>|===
>>|Name |Type |Description |Required? |Default m-value
>>
>>|`field-type`
>>|mdt:string
>>|_Must_ be set to `null`.
>>|Required
>>|
>>
>>|`user-attrs`
>>|<<user-attrs,User attributes mdt:map>>
>>|User attributes.
>>|Optional
>>|Empty mdt:map value.
>>
>>|`alignment`
>>|mdt:int
>>|Field's alignment (_must_ be a power of two, greater than 0).
>>|Optional
>>|1
>>|===
>>
>> .Null field type
>> ====
>> JSON representation:
>>
>> [source,json]
>> {
>> "user-attrs": {
>> "my-namespace": {
>> "my-attr": "desc"
>> }
>> },
>> "field-type": "null",
>> "alignment": 4
>> }
>> ====
>>
>> .Minimal null field type
>> ====
>> JSON representation:
>>
>> [source,json]
>> {"field-type": "null"}
>> ====
>>
>>
>> ===== Encode a null value as a null field
>>
>> To encode a null value using a null field type:
>>
>> * <<enc-ctx,Align>> the current encoding head using the `alignment`
>> property of the null field type.
>>
>>
>> [[bitarray-field-type]]
>> ==== Bit array field type
>>
>> A _bit array field type_ describes bit array fields.
>>
>> A bit array value is a simple array of bits. It is not an integer
>> value (it has no signedness).
>>
>> .Bit array field type mdt:map properties
>> [options="header"]
>>|===
>>|Name |Type |Description |Required? |Default m-value
>>
>>|`field-type`
>>|mdt:string
>>|_Must_ be set to `bitarray`.
>>|Required
>>|
>>
>>|`user-attrs`
>>|<<user-attrs,User attributes mdt:map>>
>>|User attributes.
>>|Optional
>>|Empty mdt:map value.
>>
>>|`alignment`
>>|mdt:int
>>|Field's alignment (_must_ be a power of two, greater than 0).
>>|Optional
>>|1
>>
>>|`size`
>>|mdt:int
>>|Field's size, in bits (_must_ be greater than 0).
>>|Required
>>|
>>
>>|`byte-order`
>>|<<byte-order,Byte order mdt:string>>
>>|Field's byte order.
>>|Optional
>>|`default`
>>|===
>>
>> .Bit array field type
>> ====
>> JSON representation:
>>
>> [source,json]
>> {
>> "field-type": "bitarray",
>> "alignment": 16,
>> "size": 5,
>> "byte-order": "le",
>> "user-attrs": {
>> "my-namespace": {
>> "my-attr": "desc"
>> }
>> }
>> }
>> ====
>>
>> .Minimal bit array field type
>> ====
>> JSON representation:
>>
>> [source,json]
>> {
>> "field-type": "bitarray",
>> "size": 32
>> }
>> ====
>>
>>
>>
>> [[enc-bit-array-field]]
>> ===== Encode a bit array value as a bit array field
>>
>> To encode a bit array value using a bit array field type:
>>
>> . <<enc-ctx,Align>> the current encoding head using the `alignment`
>> property of the bit array field type.
>> . Follow the rules of _Common Trace Format v1.8.2_, section 4.1.5, to
>> encode the bit array value according to its `byte-order` and `size`
>> properties.
>> . Add the value of the `size` property to the current encoding head.
>>
>>
>> [[bool-field-type]]
>> ==== Boolean field type
>>
>> A _boolean field type_ describes boolean fields.
>>
>> A boolean value is a bit array value which, when all its bits are
>> cleared, is said to be _false_, and otherwise is said to be _true_.
>>
>> .Boolean field type mdt:map properties
>> [options="header"]
>>|===
>>|Name |Type |Description |Required? |Default m-value
>>
>>|`field-type`
>>|mdt:string
>>|_Must_ be set to `bool`.
>>|Required
>>|
>>
>>|`user-attrs`
>>|<<user-attrs,User attributes mdt:map>>
>>|User attributes.
>>|Optional
>>|Empty mdt:map value.
>>
>>|`alignment`
>>|mdt:int
>>|Field's alignment (_must_ be a power of two, greater than 0).
>>|Optional
>>|1
>>
>>|`size`
>>|mdt:int
>>|Field's size, in bits (_must_ be greater than 0).
>>|Required
>>|
>>
>>|`byte-order`
>>|<<byte-order,Byte order mdt:string>>
>>|Field's byte order.
>>|Optional
>>|`default`
>>|===
>>
>> .Boolean field type
>> ====
>> JSON representation:
>>
>> [source,json]
>> {
>> "field-type": "bool",
>> "size": 8,
>> "byte-order": "be",
>> "user-attrs": {
>> "my-namespace": {
>> "my-attr": "desc"
>> }
>> }
>> }
>> ====
>>
>> .Minimal boolean field type
>> ====
>> JSON representation:
>>
>> [source,json]
>> {
>> "field-type": "bool",
>> "size": 8
>> }
>> ====
>>
>>
>> [[enc-bool-field]]
>> ===== Encode a boolean value as a boolean field
>>
>> To encode a boolean value using a boolean field type:
>>
>> . Encode the boolean value as a bit array value. This process is
>> platform-dependent.
>> . Follow the rules of how to <<enc-bit-array-field,encode a bit array
>> value as a bit array field>>.
>>
>>
>> [[int-field-type]]
>> ==== Integer field type
>>
>> An _integer field type_ describes integer fields.
>>
>> .Integer field type mdt:map properties
>> [options="header"]
>>|===
>>|Name |Type |Description |Required? |Default m-value
>>
>>|`field-type`
>>|mdt:string
>>|_Must_ be set to `int`.
>>|Required
>>|
>>
>>|`user-attrs`
>>|<<user-attrs,User attributes mdt:map>>
>>|User attributes.
>>|Optional
>>|Empty mdt:map value.
>>
>>|`alignment`
>>|mdt:int
>>|Field's alignment (_must_ be a power of two, greater than 0).
>>|Optional
>>|1
>>
>>|`size`
>>|mdt:int
>>|Field's size, in bits (_must_ be greater than 0).
>>|Required
>>|
>>
>>|`byte-order`
>>|<<byte-order,Byte order mdt:string>>
>>|Field's byte order.
>>|Optional
>>|`default`
>>
>>|`signed`
>>|mdt:bool
>>|_True_ if the integer field represents a signed integer value, in
>> which case the field has the two's complement format.
>>|Optional
>>|_False_
>>|===
>>
>> .Integer field type
>> ====
>> JSON representation:
>>
>> [source,json]
>> {
>> "field-type": "int",
>> "alignment": 16,
>> "size": 5,
>> "byte-order": "le",
>> "signed": true,
>> "user-attrs": {
>> "my-namespace": {
>> "my-attr": "desc"
>> }
>> }
>> }
>> ====
>>
>> .Minimal integer field type
>> ====
>> JSON representation:
>>
>> [source,json]
>> {
>> "field-type": "int",
>> "size": 32
>> }
>> ====
>>
>>
>> [[enc-int-field]]
>> ===== Encode an integer value as an integer field
>>
>> To encode an integer value using an integer field type:
>>
>> . Encode the integer value as a bit array value. Follow the two's
>> complement representation if the integer value is signed. This
>> process is platform-dependent.
>> . Follow the rules of how to <<enc-bit-array-field,encode a bit array
>> value as a bit array field>>.
>>
>>
>>
>> [[float-field-type]]
>> ==== Floating point number field type
>>
>> A _floating point number field type_ describes floating point number
>> fields encoded with {ieee754}.
>>
>> A number value (real number) can be encoded as a floating point number
>> field provided it is representable with one of the versions of
>> {ieee754}.
>>
>> .Floating point number field type mdt:map properties
>> [options="header"]
>>|===
>>|Name |Type |Description |Required? |Default m-value
>>
>>|`field-type`
>>|mdt:string
>>|_Must_ be set to `float`.
>>|Required
>>|
>>
>>|`user-attrs`
>>|<<user-attrs,User attributes mdt:map>>
>>|User attributes.
>>|Optional
>>|Empty mdt:map value.
>>
>>|`alignment`
>>|mdt:int
>>|Field's alignment (_must_ be a power of two, greater than 0).
>>|Optional
>>|1
>>
>>|`size`
>>|mdt:int
>>|Field's size, in bits (_must_ be greater than 0).
>>|Required
>>|
>>
>>|`byte-order`
>>|<<byte-order,Byte order mdt:string>>
>>|Field's byte order.
>>|Optional
>>|`default`
>>|===
>>
>> The value of the `size` property corresponds to the value of the
>> parameter _k_ (storage width in bits) in Table 3.5, _Binary interchange
>> format parameters_, of the IEEE Std 754-2008 document. All the other
>> parameters of the format needed to encode and decode the floating point
>> number value can be deduced from the value of _k_.
>>
>> .Floating point number field type describing the basic binary64 format
>> ====
>> This floating point number field type describes fields encoded with the
>> parameters of the basic binary64 format, which is the encoding used by
>> the ``double'' type of most programming languages.
>>
>> JSON representation:
>>
>> [source,json]
>> {
>> "field-type": "float",
>> "alignment": 8,
>> "size": 64,
>> "user-attrs": {
>> "my-namespace": {
>> "my-attr": "desc"
>> }
>> }
>> }
>> ====
>>
>> .Minimal floating point number field type
>> ====
>> JSON representation:
>>
>> [source,json]
>> {
>> "field-type": "float",
>> "size": 32
>> }
>> ====
>>
>>
>> [[enc-float-field]]
>> ===== Encode a number value as a floating point number field
>>
>> To encode a number value using a floating point number field type:
>>
>> . Encode the number value as a bit array value following {ieee754}. This
>> process is platform-dependent.
>> . Follow the rules of how to <<enc-bit-array-field,encode a bit array
>> value as a bit array field>>.
>>
>>
>> [[enum-field-type-member]]
>> ==== Enumeration field type member m-value
>>
>> An _enumeration field type member m-value_ represents the range of
>> values mapped to the label of an <<enum-field-type,enumeration field
>> type>> member.
>>
>> An enumeration field type member m-value is either:
>>
>> * An mdt:int value, in which case the member's label is mapped to this
>> value. For example (JSON representation):
>> +
>> [source,json]
>> ----
>> 28
>> ----
>>
>> * An mdt:map with the `lower` and `upper` properties (mdt:int values)
>> which indicate the lower (inclusive) and upper (inclusive) limits of a
>> range to which the member's label is mapped. For example (JSON
>> representation):
>> +
>> [source,json]
>> ----
>> {"lower": -3, "upper": 17}
>> ----
>>
>>
>> [[enum-field-type]]
>> ==== Enumeration field type
>>
>> An _enumeration field type_ describes enumeration fields.
>>
>> An enumeration value is an integer value mapped to a label.
>>
>> .Enumeration field type mdt:map properties
>> [options="header"]
>>|===
>>|Name |Type |Description |Required? |Default m-value
>>
>>|`field-type`
>>|mdt:string
>>|_Must_ be set to `enum`.
>>|Required
>>|
>>
>>|`user-attrs`
>>|<<user-attrs,User attributes mdt:map>>
>>|User attributes.
>>|Optional
>>|Empty mdt:map value.
>>
>>|`alignment`
>>|mdt:int
>>|Field's alignment (_must_ be a power of two, greater than 0).
>>|Optional
>>|1
>>
>>|`size`
>>|mdt:int
>>|Field's size, in bits (_must_ be greater than 0).
>>|Required
>>|
>>
>>|`byte-order`
>>|<<byte-order,Byte order mdt:string>>
>>|Field's byte order.
>>|Optional
>>|`default`
>>
>>|`signed`
>>|mdt:bool
>>|_True_ if the integer field is signed, in which case the field has
>> the two's complement format.
>>|Optional
>>|_False_
>>
>>|`members`
>>|mdt:map which maps label names (mdt:string) to mdt:array values of
>> <<enum-field-type-member,enumeration field type member m-values>>.
>>|Enumeration field type's members.
>>|Required
>>|
>>|===
>>
>> .Enumeration field type
>> ====
>> JSON representation:
>>
>> [source,json]
>> {
>> "field-type": "enum",
>> "alignment": 16,
>> "size": 32,
>> "signed": true,
>> "members": {
>> "NEW": [0],
>> "TERMINATED": [-1],
>> "READY": [2, 17],
>> "RUNNING": [-3],
>> "WAITING": [
>> {"lower": 19, "upper": 199},
>> 1000
>> ],
>> "RESTARTING": [
>> {"base": 8, "value": "126674015"},
>> {"lower": -155, "upper": -98}
>> ]
>> },
>> "user-attrs": {
>> "my-namespace": {
>> "my-attr": "desc"
>> }
>> }
>> }
>>
>> With this enumeration field type, the following enumeration fields would
>> have the following associated labels:
>>
>> * -1: `TERMINATED`
>> * 17: `READY`
>> * -101: `RESTARTING`
>> * 1000: `WAITING`
>> * 22771725: `RESTARTING`
>> * 2: `READY`
>> * 50: `WAITING`
>> ====
>>
>> .Minimal enumeration field type
>> ====
>> JSON representation:
>>
>> [source,json]
>> {
>> "field-type": "enum",
>> "members": {
>> "": [0]
>> }
>> }
>> ====
>>
>>
>> [[enc-enum-field]]
>> ===== Encode an enumeration value as an enumeration field
>>
>> To encode an enumeration value (which is an integer value) using an
>> enumeration field type:
>>
>> * Follow the rules of how to <<enc-int-field,encode an integer value as
>> an integer field>>.
>>
>>
>> [[string-field-type]]
>> ==== String field type
>>
>> A _string field type_ describes string fields.
>>
>> A string value is a finite sequence of Unicode characters.
>>
>> .String field type mdt:map properties
>> [options="header"]
>>|===
>>|Name |Type |Description |Required? |Default m-value
>>
>>|`user-attrs`
>>|<<user-attrs,User attributes mdt:map>>
>>|User attributes.
>>|Optional
>>|Empty mdt:map value.
>>
>>|`field-type`
>>|mdt:string
>>|_Must_ be set to `string`.
>>|Required
>>|
>>
>>|`alignment`
>>|mdt:int
>>|Field's alignment (_must_ be a power of two,
>> greater than or equal to 8).
>>|Optional
>>|8
>>|===
>>
>> .String field type
>> ====
>> JSON representation:
>>
>> [source,json]
>> {
>> "field-type": "string",
>> "alignment": 16,
>> "user-attrs": {
>> "my-namespace": {
>> "my-attr": "desc"
>> }
>> }
>> }
>> ====
>>
>> .Minimal string field type
>> ====
>> JSON representation:
>>
>> [source,json]
>> {"field-type": "string"}
>> ====
>>
>>
>> [[enc-string-field]]
>> ===== Encode a string value as a string field
>>
>> To encode a string value using a string field type:
>>
>> . <<enc-ctx,Align>> the current encoding head using the `alignment`
>> property of the string field type.
>> . For each Unicode character of the string value:
>> .. Encode this Unicode character as a sequence of 8-bit bit arrays
>> (bytes) following UTF-8. This process is platform-dependent.
>> .. For each resulting UTF-8 byte of this character:
>> *** Follow the rules of how to <<enc-bit-array-field,encode a bit
>> array value as a bit array field>>.
>> . Follow the rules of how to <<enc-int-field,encode an integer value as
>> an integer field>> to encode the UTF-8 null character (U+0000).
>>
>>
>> [[varbitarray-field-type]]
>> ==== Variable-length bit array field type
>>
>> A _variable-length bit array field type_ describes variable-length bit
>> array fields.
>>
>> A bit array value of any size that is a multiple of 7{nbsp}bits, and at
>> least 7{nbsp}bits, can be dynamically encoded as a variable-length bit
>> array field.
>>
>> .Variable-length bit array field type mdt:map
>> [options="header"]
>>|===
>>|Name |Type |Description |Required? |Default m-value
>>
>>|`field-type`
>>|mdt:string
>>|_Must_ be set to `varbitarray`.
>>|Required
>>|
>>
>>|`user-attrs`
>>|<<user-attrs,User attributes mdt:map>>
>>|User attributes.
>>|Optional
>>|Empty mdt:map value.
>>
>>|`alignment`
>>|mdt:int
>>|Field's alignment (_must_ be a power of two,
>> greater than or equal to 8).
>>|Optional
>>|8
>>|===
>>
>> .Variable-length bit array field type
>> ====
>> JSON representation:
>>
>> [source,json]
>> {
>> "field-type": "varbitarray",
>> "user-attrs": {
>> "my-namespace": {
>> "my-attr": "desc"
>> }
>> }
>> }
>> ====
>>
>> .Minimal variable-length bit array field type
>> ====
>> JSON representation:
>>
>> [source,json]
>> {"field-type": "varbitarray"}
>> ====
>>
>>
>> [[enc-varbitarray-field]]
>> ===== Encode a bit array value as a variable-length bit array field
>>
>> To encode a bit array value using a variable-length bit array field type:
>>
>> . <<enc-ctx,Align>> the current encoding head using the `alignment`
>> property of the variable-length bit array field type.
>> . Encode the bit array value as a bit array field following the unsigned
>> https://en.wikipedia.org/wiki/LEB128[LEB128] format.
>> . Add the encoded variable-length bit array field's size (_not_ the
>> original bit array value's size) to the current encoding head.
>>
>>
>> [[varbool-field-type]]
>> ==== Variable-length boolean field type
>>
>> A _variable-length boolean field type_ describes variable-length boolean
>> fields.
>>
>> A boolean value is a bit array value which, when all its bits are
>> cleared, is said to be _false_, and otherwise is said to be _true_.
>>
>> A boolean value of any size that is a multiple of 7{nbsp}bits, and at
>> least 7{nbsp}bits, can be dynamically encoded as a variable-length bit
>> array field.
>>
>> .Variable-length boolean field type mdt:map properties
>> [options="header"]
>>|===
>>|Name |Type |Description |Required? |Default m-value
>>
>>|`field-type`
>>|mdt:string
>>|_Must_ be set to `varbool`.
>>|Required
>>|
>>
>>|`user-attrs`
>>|<<user-attrs,User attributes mdt:map>>
>>|User attributes.
>>|Optional
>>|Empty mdt:map value.
>>
>>|`alignment`
>>|mdt:int
>>|Field's alignment (_must_ be a power of two,
>> greater than or equal to 8).
>>|Optional
>>|8
>>|===
>>
>> .Variable-length boolean field type
>> ====
>> JSON representation:
>>
>> [source,json]
>> {
>> "field-type": "varbool",
>> "alignment": 32,
>> "user-attrs": {
>> "my-namespace": {
>> "my-attr": "desc"
>> }
>> }
>> }
>> ====
>>
>> .Minimal variable-length boolean field type
>> ====
>> JSON representation:
>>
>> [source,json]
>> {"field-type": "varbool"}
>> ====
>>
>>
>> [[enc-varbool-field]]
>> ===== Encode a boolean value as a variable-length boolean field
>>
>> To encode a boolean value using a variable-length boolean field type:
>>
>> . Encode the boolean value as a bit array value. This process is
>> platform-dependent.
>> . Follow the rules of how to <<enc-varbitarray-field,encode a bit array
>> value as a variable-length bit array field>>.
>>
>>
>> [[varint-field-type]]
>> ==== Variable-length integer field type
>>
>> A _variable-length integer field type_ describes variable-length integer
>> fields.
>>
>> An integer value of any size can be encoded dynamically as a
>> variable-length integer field.
>>
>> .Variable-length integer field type mdt:map properties
>> [options="header"]
>>|===
>>|Name |Type |Description |Required? |Default m-value
>>
>>|`field-type`
>>|mdt:string
>>|_Must_ be set to `varint`.
>>|Required
>>|
>>
>>|`user-attrs`
>>|<<user-attrs,User attributes mdt:map>>
>>|User attributes.
>>|Optional
>>|Empty mdt:map value.
>>
>>|`alignment`
>>|mdt:int
>>|Field's alignment (_must_ be a power of two,
>> greater than or equal to 8).
>>|Optional
>>|8
>>
>>|`signed`
>>|mdt:bool
>>|_True_ if the integer field is signed, in which case the field has
>> the two's complement format.
>>|Optional
>>|_False_
>>|===
>>
>> .Variable-length integer field type
>> ====
>> JSON representation:
>>
>> [source,json]
>> {
>> "field-type": "varint",
>> "alignment": 16,
>> "signed": true,
>> "user-attrs": {
>> "my-namespace": {
>> "my-attr": "desc"
>> }
>> }
>> }
>> ====
>>
>> .Minimal variable-length integer field type
>> ====
>> JSON representation:
>>
>> [source,json]
>> {"field-type": "varint"}
>> ====
>>
>>
>> [[enc-varint-field]]
>> ===== Encode an integer value as a variable-length integer field
>>
>> To encode an integer value using a variable-length integer field type:
>>
>> . Encode the integer value as a bit array value. Follow the two's
>> complement representation if the integer value is signed. Sign-extend
>> the bit array to the next multiple of 7{nbsp}bits. This process is
>> platform-dependent.
>> . Follow the rules of how to <<enc-varbitarray-field,encode a bit array
>> value as a variable-length bit array field>>.
>>
>>
>> [[varenum-field-type]]
>> ==== Variable-length enumeration field type
>>
>> A _variable-length enumeration field type_ describes variable-length
>> enumeration fields.
>>
>> An enumeration value is an integer value mapped to a label.
>>
>> An enumeration value of any size can be encoded dynamically as a
>> variable-length enumeration field.
>>
>> .Variable-length enumeration field type mdt:map properties
>> [options="header"]
>>|===
>>|Name |Type |Description |Required? |Default m-value
>>
>>|`field-type`
>>|mdt:string
>>|_Must_ be set to `varint`.
>>|Required
>>|
>>
>>|`user-attrs`
>>|<<user-attrs,User attributes mdt:map>>
>>|User attributes.
>>|Optional
>>|Empty mdt:map value.
>>
>>|`alignment`
>>|mdt:int
>>|Field's alignment (_must_ be a power of two,
>> greater than or equal to 8).
>>|Optional
>>|8
>>
>>|`signed`
>>|mdt:bool
>>|_True_ if the integer field is signed, in which case the field has
>> the two's complement format.
>>|Optional
>>|_False_
>>
>>|`members`
>>|mdt:map which maps label names (mdt:string) to mdt:array values of
>> <<enum-field-type-member,enumeration field type member m-values>>.
>>|Enumeration field type's members.
>>|Required
>>|
>>|===
>>
>> .Variable-length enumeration field type
>> ====
>> JSON representation:
>>
>> [source,json]
>> {
>> "field-type": "varenum",
>> "signed": true,
>> "members": {
>> "NEW": [0],
>> "TERMINATED": [-1],
>> "READY": [2, 17],
>> "RUNNING": [-3],
>> "WAITING": [
>> {"lower": 19, "upper": 199},
>> 1000
>> ],
>> "RESTARTING": [
>> {"base": 8, "value": "126674015"},
>> {"lower": -155, "upper": -98}
>> ]
>> },
>> "user-attrs": {
>> "my-namespace": {
>> "my-attr": "desc"
>> }
>> }
>> }
>>
>> With this enumeration field type, the following enumeration fields would
>> have the following associated labels:
>>
>> * -1: `TERMINATED`
>> * 17: `READY`
>> * -101: `RESTARTING`
>> * 1000: `WAITING`
>> * 22771725: `RESTARTING`
>> * 2: `READY`
>> * 50: `WAITING`
>> ====
>>
>> .Minimal variable-length enumeration field type
>> ====
>> JSON representation:
>>
>> [source,json]
>> {
>> "field-type": "varenum",
>> "members": {
>> "": [0]
>> }
>> }
>> ====
>>
>>
>> [[enc-varenum-field]]
>> ===== Encode an enumeration value as a variable-length integer field
>>
>> To encode an enumeration value (which is an integer value) using a
>> variable-length enumeration field type:
>>
>> . Encode the integer value as a bit array value. Follow the two's
>> complement representation if the integer value is signed. Sign-extend
>> the bit array to the next multiple of 7{nbsp}bits. This process is
>> platform-dependent.
>> . Follow the rules of how to <<enc-varbitarray-field,encode a bit array
>> value as a variable-length bit array field>>.
>>
>>
>> [[struct-union-variant-field]]
>> ==== Structure/union/variant field type field mdt:map
>>
>> A _structure/union/variant field type field mdt:map_ represents one
>> field of a <<struct-field-type,structure field type>> or of a
>> <<union-field-type,union field type>>, or one choice of a
>> <<variant-field-type,variant field type>>.
>>
>> .Structure/union/variant field type field mdt:map properties
>> [options="header"]
>>|===
>>|Name |Type |Description |Required? |Default m-value
>>
>>|`user-attrs`
>>|<<user-attrs,User attributes mdt:map>>
>>|User attributes.
>>|Optional
>>|Empty mdt:map value.
>>
>>|`name`
>>|mdt:string
>>|Structure/union/variant field type field's name.
>>|Required
>>|
>>
>>|`field-type`
>>|<<field-type-m-value,Field type m-value>>
>>|Structure/union/variant field type field's type.
>>|Required
>>|
>>|===
>>
>> .Structure/union/variant field type field mdt:map
>> ====
>> JSON representation:
>>
>> [source,json]
>> {
>> "name": "src_addr",
>> "field-type": {
>> "field-type": "array",
>> "length": 4,
>> "element-field-type": "uint8"
>> },
>> "user-attrs": {
>> "my-namespace": {
>> "my-attr": "desc"
>> }
>> }
>> }
>> ====
>>
>>
>> [[struct-field-type]]
>> ==== Structure field type
>>
>> A _structure field type_ describes structure fields.
>>
>> A structure value is a finite sequence of values of different types.
>> This is sometimes also called a _record_.
>>
>> .Structure field type mdt:map properties
>> [options="header"]
>>|===
>>|Name |Type |Description |Required? |Default m-value
>>
>>|`field-type`
>>|mdt:string
>>|_Must_ be set to `struct`.
>>|Required
>>|
>>
>>|`user-attrs`
>>|<<user-attrs,User attributes mdt:map>>
>>|User attributes.
>>|Optional
>>|Empty mdt:map value.
>>
>>|`alignment`
>>|mdt:int
>>|Field's minimal alignment (_must_ be a power of two, greater than 0).
>>|Optional
>>|1
>>
>>|`fields`
>>|mdt:array of <<struct-union-variant-field,structure/union/variant
>> field type field mdt:map values>>
>>|Fields of the structure field type.
>>|Optional
>>|Empty mdt:array value.
>>|===
>>
>> The `alignment` property indicates the _minimal_ alignment of the
>> structure fields encoded with this field type. The _automatic_ alignment
>> of the structure field type is the greatest value amongst all the
>> effective alignments of the field type's fields. The _effective_
>> alignment of the structure field type is the greatest value amongst the
>> field type's minimal and automatic alignments.
>>
>> .Structure field type
>> ====
>> JSON representation:
>>
>> [source,json]
>> {
>> "field-type": "struct",
>> "alignment": 8,
>> "fields": [
>> {
>> "name": "timestamp_begin",
>> "field-type": "uint64"
>> },
>> {
>> "name": "timestamp_end",
>> "field-type": "uint64"
>> },
>> {
>> "name": "packet_size",
>> "field-type": "uint32"
>> },
>> {
>> "name": "content_size",
>> "field-type": "uint32"
>> },
>> {
>> "name": "core location",
>> "field-type": {
>> "field-type": "struct",
>> "fields": [
>> {
>> "name": "x",
>> "field-type": {
>> "field-type": "int",
>> "size": 3
>> }
>> },
>> {
>> "name": "y",
>> "field-type": {
>> "field-type": "int",
>> "size": 5
>> }
>> }
>> ]
>> }
>> }
>> ],
>> "user-attrs": {
>> "my-namespace": {
>> "my-attr": "desc"
>> }
>> }
>> }
>>
>> In this example, assuming that the effective alignment of the
>> `timestamp_end` field is 64, and that this is the greatest alignment
>> amongst all the alignments of the structure field type's fields, then
>> the structure field type's effective alignment is also 64.
>> ====
>>
>> .Minimal (empty) structure field type
>> ====
>> JSON representation:
>>
>> [source,json]
>> {"field-type": "struct"}
>> ====
>>
>>
>> [[enc-struct-field]]
>> ===== Encode a structure value as a structure field
>>
>> To encode a structure value using a structure field type:
>>
>> . <<enc-ctx,Align>> the current encoding head using the _effective_
>> alignment of the structure field type.
>> . For each field of the structure value:
>> ** Encode the field's value using the field type of the
>> structure/union/variant field type field mdt:map at the corresponding
>> position in the `fields` mdt:array of the structure field type.
>>
>>
>> [[array-field-type]]
>> ==== Array field type
>>
>> An _array field type_ describes array fields.
>>
>> An array value is a finite sequence of values.
>>
>> The length of all the possible array fields represented by a given array
>> field type is known statically (when producing the array field type).
>>
>> .Array field type mdt:map properties
>> [options="header"]
>>|===
>>|Name |Type |Description |Required? |Default m-value
>>
>>|`field-type`
>>|mdt:string
>>|_Must_ be set to `array`.
>>|Required
>>|
>>
>>|`user-attrs`
>>|<<user-attrs,User attributes mdt:map>>
>>|User attributes.
>>|Optional
>>|Empty mdt:map value.
>>
>>|`alignment`
>>|mdt:int
>>|Field's alignment (_must_ be a power of two, greater than 0).
>>|Optional
>>|1
>>
>>|`length`
>>|mdt:int
>>|Number of elements contained in array fields described by this
>> field type.
>>|Required
>>|
>>
>>|`element-field-type`
>>|<<field-type-m-value,Field type m-value>>
>>|Field type of the elements contained in array fields described by
>> this field type.
>>|Required
>>|
>>|===
>>
>> .Array field type
>> ====
>> [source,json]
>> {
>> "field-type": "array",
>> "alignment": 64,
>> "length": 72,
>> "element-field-type": {
>> "field-type": "float",
>> "size": 64,
>> "byte-order": "be"
>> },
>> "user-attrs": {
>> "my-namespace": {
>> "my-attr": "desc"
>> }
>> }
>> }
>> ====
>>
>> .Array field type describing UUID fields
>> ====
>> JSON representation:
>>
>> [source,json]
>> {
>> "field-type": "array",
>> "alignment": 8,
>> "length": 16,
>> "element-field-type": {
>> "field-type": "int",
>> "size": 8
>> },
>> "user-attrs": {
>> "my-namespace": {
>> "my-attr": "desc"
>> }
>> }
>> }
>> ====
>>
>> .Minimal array field type
>> ====
>> JSON representation:
>>
>> [source,json]
>> {
>> "field-type": "array",
>> "length": 32,
>> "element-field-type": "elem-ft"
>> }
>> ====
>>
>>
>> [[enc-array-field]]
>> ===== Encode an array value as an array field
>>
>> To encode an array value using an array field type:
>>
>> . <<enc-ctx,Align>> the current encoding head using the `alignment`
>> property of the array field type.
>> . For each element of the array value:
>> ** Encode the value using the `element-field-type` property of the array
>> field type.
>>
>>
>> [[textarray-field-type]]
>> ==== Text array field type
>>
>> A _text array field type_ describes text array fields. It is a
>> specialized version of the <<array-field-type,array field type>>.
>>
>> A text array value is a finite sequence of bytes which form a UTF-8
>> string. The length of all the possible text array fields represented by
>> a given text array field type is known statically (when producing the
>> text array field type). The text array value's length _may_ be greater
>> than the number of effective UTF-8 bytes, as long as the string is
>> null-terminated. In this case, the padding bytes after the UTF-8 null
>> character can have any value.
>>
>> .Text array field type mdt:map properties
>> [options="header"]
>>|===
>>|Name |Type |Description |Required? |Default m-value
>>
>>|`field-type`
>>|mdt:string
>>|_Must_ be set to `textarray`.
>>|Required
>>|
>>
>>|`user-attrs`
>>|<<user-attrs,User attributes mdt:map>>
>>|User attributes.
>>|Optional
>>|Empty mdt:map value.
>>
>>|`alignment`
>>|mdt:int
>>|Field's alignment (_must_ be a power of two, greater than 0).
>>|Optional
>>|1
>>
>>|`length`
>>|mdt:int
>>|Number of bytes contained in text array fields described by this
>> field type.
>>|Required
>>|
>>|===
>>
>> .Text array field type
>> ====
>> JSON representation:
>>
>> [source,json]
>> {
>> "field-type": "textarray",
>> "alignment": 32,
>> "length": 16,
>> "user-attrs": {
>> "my-namespace": {
>> "my-attr": "desc"
>> }
>> }
>> }
>> ====
>>
>> .Minimal text array field type
>> ====
>> JSON representation:
>>
>> [source,json]
>> {
>> "field-type": "textarray",
>> "length": 32
>> }
>> ====
>>
>>
>> [[enc-textarray-field]]
>> ===== Encode a text array value as a text array field
>>
>> A text array value is an array value with bytes as elements.
>>
>> To encode a text array value using a text array field type:
>>
>> * Follow the rules of how to <<enc-array-field,encode an array value as
>> an array field>>.
>>
>>
>> [[sequence-field-type]]
>> ==== Sequence field type
>>
>> A _sequence field type_ describes sequence fields.
>>
>> A sequence value is a finite sequence of values. Its length is known
>> dynamically.
>>
>> .Sequence field type mdt:map properties
>> [options="header"]
>>|===
>>|Name |Type |Description |Required? |Default m-value
>>
>>|`field-type`
>>|mdt:string
>>|_Must_ be set to `sequence`.
>>|Required
>>|
>>
>>|`user-attrs`
>>|<<user-attrs,User attributes mdt:map>>
>>|User attributes.
>>|Optional
>>|Empty mdt:map value.
>>
>>|`alignment`
>>|mdt:int
>>|Field's alignment (_must_ be a power of two, greater than 0).
>>|Optional
>>|1
>>
>>|`length`
>>|<<field-path,Field path m-value>>
>>|Path to a previously encoded integer, enumeration, variable-length
>> integer, or variable-length enumeration field which
>> indicates the number of elements contained in the sequence field.
>>|Required
>>|
>>
>>|`element-field-type`
>>|<<field-type-m-value,Field type m-value>>
>>|Field type of the elements contained in sequence fields described by
>> this field type.
>>|Required
>>|
>>|===
>>
>> .Sequence field type
>> ====
>> JSON representation:
>>
>> [source,json]
>> {
>> "field-type": "sequence",
>> "alignment": 32,
>> "length": ["msg", "info", "count"],
>> "element-field-type": {
>> "field-type": "string"
>> },
>> "user-attrs": {
>> "my-namespace": {
>> "my-attr": "desc"
>> }
>> }
>> }
>> ====
>>
>> .Minimal sequence field type
>> ====
>> JSON representation:
>>
>> [source,json]
>> {
>> "field-type": "sequence",
>> "length": ["len"],
>> "element-field-type": "elem-ft"
>> }
>> ====
>>
>>
>> [[enc-sequence-field]]
>> ===== Encode a sequence value as a sequence field
>>
>> To encode a sequence value using a sequence field type:
>>
>> . <<enc-ctx,Align>> the current encoding head using the `alignment`
>> property of the sequence field type.
>> . For each element of the sequence value (the count given by a
>> previously encoded integer or enumeration field, located thanks to the
>> `length` property):
>> ** Encode the value using the `element-field-type` property of the
>> sequence field type.
>>
>>
>> [[textsequence-field-type]]
>> ==== Text sequence field type
>>
>> A _text sequence field type_ describes text sequence fields. It is a
>> specialized version of the <<sequence-field-type,sequence field type>>.
>>
>> A text sequence value is a finite sequence of bytes which form a UTF-8
>> string. Its length is known dynamically. The text sequence value's
>> length _may_ be greater than the number of effective UTF-8 bytes, as long
>> as the string is null-terminated. In this case the padding bytes after
>> the UTF-8 null character can have any value.
>>
>> .Text sequence field type mdt:map properties
>> [options="header"]
>>|===
>>|Name |Type |Description |Required? |Default m-value
>>
>>|`field-type`
>>|mdt:string
>>|_Must_ be set to `textsequence`.
>>|Required
>>|
>>
>>|`user-attrs`
>>|<<user-attrs,User attributes mdt:map>>
>>|User attributes.
>>|Optional
>>|Empty mdt:map value.
>>
>>|`alignment`
>>|mdt:int
>>|Field's alignment (_must_ be a power of two, greater than 0).
>>|Optional
>>|1
>>
>>|`length`
>>|<<field-path,Field path m-value>>
>>|Path to a previously encoded integer, enumeration, variable-length
>> integer, or variable-length enumeration field which
>> indicates the number of bytes contained in the text sequence field.
>>|Required
>>|
>>|===
>>
>> .Text sequence field type
>> ====
>> JSON representation:
>>
>> [source,json]
>> {
>> "field-type": "textsequence",
>> "alignment": 32,
>> "length": {
>> "scope": "my-scope",
>> "path": "cmd-len"
>> },
>> "user-attrs": {
>> "my-namespace": {
>> "my-attr": "desc"
>> }
>> }
>> }
>> ====
>>
>> .Minimal text sequence field type
>> ====
>> JSON representation:
>>
>> [source,json]
>> {
>> "field-type": "textsequence",
>> "length": ["len"]
>> }
>> ====
>>
>>
>> [[enc-textsequence-field]]
>> ===== Encode a text sequence value as a text sequence field
>>
>> A text sequence value is a sequence value with bytes as elements.
>>
>> To encode a text sequence value using a text sequence field type:
>>
>> * Follow the rules of how to <<enc-sequence-field,encode a sequence
>> value as a sequence field>>.
>>
>>
>> [[variant-field-type]]
>> ==== Variant field type
>>
>> A _variant field type_ describes variant fields.
>>
>> A variant value is a value of some type amongst many possible types. The
>> exact type of the value is indicated dynamically by a previously encoded
>> tag field (an enumeration or variable-length enumeration field).
>>
>> .Variant field type mdt:map properties
>> [options="header"]
>>|===
>>|Name |Type |Description |Required? |Default m-value
>>
>>|`field-type`
>>|mdt:string
>>|_Must_ be set to `textsequence`.
>>|Required
>>|
>>
>>|`user-attrs`
>>|<<user-attrs,User attributes mdt:map>>
>>|User attributes.
>>|Optional
>>|Empty mdt:map value.
>>
>>|`alignment`
>>|mdt:int
>>|Field's alignment (_must_ be a power of two, greater than 0).
>>|Optional
>>|1
>>
>>|`tag`
>>|<<field-path,Field path m-value>>
>>|Path to a previously encoded enumeration or variable-length
>> enumeration field which indicates the type, by label name to choice name
>> association, of the variant field.
>>|Required
>>|
>>
>>|`choices`
>>|mdt:array of <<struct-union-variant-field,structure/union/variant
>> field type field mdt:map values>>
>>|Choices of the variant field type.
>>|Required
>>|
>>|===
>>
>> The `name` property of the all the structure/union/variant field type
>> field mdt:map values listed in the `choices` property _must_ exist as a
>> member's label name in the tag's enumeration field type.
>>
>> .Variant field type
>> ====
>> JSON representation:
>>
>> [source,json]
>> {
>> "field-type": "variant",
>> "alignment": 16,
>> "tag": ["path", "to", "tag"],
>> "choices": [
>> {
>> "user-attrs": {
>> "ns": {
>> "split": 5
>> }
>> },
>> "name": "ID",
>> "field-type": {
>> "field-type": "int",
>> "size": 35,
>> "signed": true,
>> "alignment": 32
>> }
>> },
>> {
>> "name": "NAME",
>> "field-type": {
>> "field-type": "string"
>> }
>> }
>> ],
>> "user-attrs": {
>> "my-namespace": {
>> "my-attr": "desc"
>> }
>> }
>> }
>> ====
>>
>> .Minimal variant field type
>> ====
>> JSON representation:
>>
>> [source,json]
>> {
>> "field-type": "variant",
>> "tag": ["tag"],
>> "choices": [
>> {
>> "name": "",
>> "field-type": "some-ft"
>> }
>> ]
>> }
>>
>> Note that such a variant field type, with a single choice, is useless
>> because this choice could be used directly instead.
>> ====
>>
>>
>> [[enc-variant-field]]
>> ===== Encode a variant value as a variant field
>>
>> To encode a variant value using a variant field type:
>>
>> . <<enc-ctx,Align>> the current encoding head using the `alignment`
>> property of the variant field type.
>> . Follow the encoding rules of the field type, amongst the field types
>> of the choices listed in the `choices` property, currently selected by
>> the previously encoded `tag` field.
>>
>>
>> [[union-field-type]]
>> ==== Union field type
>>
>> A _union field type_ describes union fields.
>>
>> A union field is a binary field which, once encoded using some field
>> type, can be decoded using other field types.
>>
>> .Union field type mdt:map properties
>> [options="header"]
>>|===
>>|Name |Type |Description |Required? |Default m-value
>>
>>|`field-type`
>>|mdt:string
>>|_Must_ be set to `struct`.
>>|Required
>>|
>>
>>|`user-attrs`
>>|<<user-attrs,User attributes mdt:map>>
>>|User attributes.
>>|Optional
>>|Empty mdt:map value.
>>
>>|`alignment`
>>|mdt:int
>>|Field's minimal alignment (_must_ be a power of two, greater than 0).
>>|Optional
>>|1
>>
>>|`fields`
>>|mdt:array of at least one
>> <<struct-union-variant-field,structure/union/variant field type
>> field mdt:map value>>
>>|Fields of the union field type.
>>|Required
>>|
>>|===
>>
>> .Union field type
>> ====
>> In this example, the union fields represented by this field type can
>> _always_ be decoded as either string fields, or as unsigned 64-bit
>> integer fields. This means that the producer ensures that, when writing
>> a string field, its length is always 64 bits (including the terminating
>> null character).
>>
>> JSON representation:
>>
>> [source,json]
>> {
>> "field-type": "union",
>> "alignment": 8,
>> "fields": [
>> {
>> "name": "as string",
>> "field-type": {
>> "field-type": "string"
>> }
>> },
>> {
>> "name": "as int",
>> "field-type": {
>> "field-type": "int",
>> "size": 64
>> }
>> }
>> ],
>> "user-attrs": {
>> "my-namespace": {
>> "my-attr": "desc"
>> }
>> }
>> }
>> ====
>>
>> .Minimal union field type
>> ====
>> JSON representation:
>>
>> [source,json]
>> {
>> "field-type": "union",
>> "length": 32,
>> "fields": [
>> {
>> "name": "",
>> "field-type": "some-ft"
>> }
>> ]
>> }
>>
>> Note that such a union field type, with a single field, is useless
>> because this field could be used directly instead.
>> ====
>>
>>
>> [[enc-variant-field]]
>> ===== Encode a value as a union field
>>
>> To encode a value using a union field type:
>>
>> . <<enc-ctx,Align>> the current encoding head using the `alignment`
>> property of the union field type.
>> . Follow the encoding rules of the chosen field type, amongst the field
>> types of the fields listed in the `fields` property, corresponding to
>> the type of the value to encode.
>>
>> An important condition when encoding a union field is that, whichever
>> field type is chosen to decode the field afterwards, the current
>> decoding head _must_ always be the same after the process.
>>
>>
>> [[layer-2]]
>> == Layer 2: Data streams, packets, and event records
>>
>> This layer adds the following concepts to the CTF{nbsp}2 specification:
>>
>> * Field type alias fragment.
>> * Field tag mdt:map.
>> * A _trace_ contains zero or more _data streams_. A data stream is a
>> sequence of zero or more _packets_. A packet contains zero or more
>> _event records_.
>> * The concepts and layouts of data streams, packets, and event records.
>> * Trace class, data stream class, and event record class fragments.
>>
>>
>> [[data-stream]]
>> === Data stream
>>
>> A CTF{nbsp}2 _data stream_ is defined as a sequence of
>> <<packet,packets>>.
>>
>> [packet]
>> [packet]
>> [packet]
>> [packet]
>> [packet]
>> ...
>>
>> A <<data-stream-class-fragment,data stream class fragment>> describes,
>> in the <<metadata-array,metadata mdt:array>>, a class of data streams.
>> For a single data stream class, there can be zero or more data streams
>> in the trace.
>>
>> There are two ways to distinguish individual data streams:
>>
>> * Rely on the storage or transport back-end to separate individual data
>> streams.
>> +
>> For example, a trace stored on a file system could contain one data
>> stream per file. If a trace is sent over the network, the wrapping
>> network protocol could assign a unique ID to each data stream.
>>
>> * Tag a field of the trace packet header field with the
>> <<data-stream-id,`data-stream-id` field tag>>.
>> +
>> This is the _recommended_ way to isolate a data stream: it is more
>> robust and more portable. With this method, each packet holds the unique
>> ID of the data stream to which it logically belongs.
>>
>>
>> [[packet]]
>> === Packet
>>
>> A _packet_ contains two _optional_, contiguous scope fields, named the
>> _trace packet header_ and the _data stream packet context_ fields,
>> followed by zero or more event records, and finally by _optional_
>> padding bits to honor its total size:
>>
>> [trace packet header field]
>> [data stream packet context field]
>> [event record]
>> [event record]
>> [event record]
>> ...
>> [padding]
>>
>> Before the first bit of a packet is written, the current encoding head
>> of the <<enc-ctx,CTFFER encoding context>> is set to 0. This current
>> encoding head keeps on incrementing as fields are encoded following the
>> <<ctffer,CTFFER>> until the beginning of the next packet in the same
>> <<data-stream,data stream>>, where it is reset to 0 again. This means
>> that the reference to align any binary field within a packet is the
>> beginning of a packet, _not_ the beginning of a data stream.
>>
>> To simplify matters for CTF{nbsp}2 consumers, the size of a packet, in
>> bits, _must_ be greater than 8, and _must_ be a multiple of 8.
>>
>> The first packet's padding bit is reached when the current encoding head
>> is equal to the value of the packet's content size field found in the
>> data stream packet context field (if any).
>>
>> If there is more than one data stream class in the trace, the trace
>> packet header field contains a data stream class ID field which
>> indicates which data stream class describes the data stream packet
>> context field and the event records.
>>
>>
>> [[event-record]]
>> === Event record
>>
>> An _event record_ contains four _optional_, contiguous scope fields,
>> named the _data stream event record header_, the _data stream event
>> record context_, the _event record context_, and the _event record
>> payload_ fields.
>>
>> [data stream event record header field]
>> [data stream event record context field]
>> [event record context]
>> [event record payload]
>>
>> If there is more than one event record class in a given data stream
>> class, the data stream event record header field contains an event
>> record class ID field which indicates which event record class describes
>> the event record context and event record payload fields.
>>
>> The encoded size of any event record must be at least 1{nbsp}bit.
>>
>> [[field-type-alias-fragment]]
>> === Field type alias fragment
>>
>> A _field type alias fragment_ is a <<metadata-array,fragment>> which
>> associates a name (mdt:string) to a <<field-type-m-value,field type
>> m-value>> (complete field type mdt:map, or previously defined field type
>> alias's name).
>>
>> The name of a field type alias can be used by field types which are
>> written after the field type alias fragment in the metadata mdt:array.
>>
>> .Field type alias fragment
>> [options="header"]
>>|===
>>|Name |Type |Description |Required? |Default m-value
>>
>>|`fragment`
>>|mdt:string
>>|_Must_ be set to `field-type-alias`.
>>|Required
>>|
>>
>>|`user-attrs`
>>|<<user-attrs,User attributes mdt:map>>
>>|User attributes.
>>|Optional
>>|Empty mdt:map value.
>>
>>|`name`
>>|mdt:string
>>|Name of the field type alias.
>>|Required
>>|
>>
>>|`field-type`
>>|<<field-type-m-value,Field type m-value>>
>>|Field type of the field type alias.
>>|Required
>>|
>>|===
>>
>> Within a given <<metadata-array,metadata mdt:array>>, two field type
>> alias fragments cannot have the same `name` property.
>>
>> .Field type alias fragment
>> ====
>> JSON representation:
>>
>> [source,json]
>> {
>> "fragment": "field-type-alias",
>> "name": "uint8",
>> "field-type": {
>> "field-type": "integer",
>> "size": 8,
>> "alignment": 8
>> }
>> }
>> ====
>>
>> .Field type alias fragment giving another name to a previously defined alias
>> ====
>> JSON representation:
>>
>> [source,json]
>> {
>> "fragment": "field-type-alias",
>> "name": "uint8_t",
>> "field-type": "uint8"
>> }
>> ====
>>
>>
>> [[field-tag]]
>> === Field tag mdt:map
>>
>> A _field tag mdt:map_ ``tags'' a scope's field with a special meaning.
>>
>> The following sections define specific field tag mdt:map values which
>> can be used in specific contexts.
>>
>> .Field tag mdt:map base properties
>> [options="header"]
>>|===
>>|Name |Type |Description |Required? |Default m-value
>>
>>|`tag`
>>|mdt:string
>>|Name of the tag (fragment-dependent).
>>|Required
>>|
>>
>>|`path`
>>|<<abs-field-path,Absolute field path mdt:map>>
>>|Absolute path to the tagged field.
>>|Required
>>|
>>|===
>>
>>
>> [[discarded-event-record-count-field-tag]]
>> === Discarded event record count field tag mdt:map
>>
>> A _discarded event record count field tag mdt:map_ is a
>> <<field-tag,field tag>> which tags a field as being a counter of
>> discarded event records.
>>
>> Event records can be discarded for multiple reasons from the producer's
>> perspective. This document specifies the available reasons, when event
>> records are lost for those reasons, and how to compute the total number
>> of discarded event records so far for a given <<data-stream,data
>> stream>>.
>>
>> .Discarded event record count field tag mdt:map properties
>> [options="header"]
>>|===
>>|Name |Type |Description |Required? |Default m-value
>>
>>|`tag`
>>|mdt:string
>>|_Must_ be set to `discarded-event-record-count`.
>>|Required
>>|
>>
>>|`path`
>>|<<abs-field-path,Absolute field path mdt:map>>
>>|Absolute path to the tagged field.
>>|Required
>>|
>>
>>|`reason`
>>|mdt:string
>>|_Must_ be set to `legacy` as of this version.
>>|Required
>>|
>>|===
>>
>> A field tagged with the `legacy` reason has the same behaviour as the
>> `events_discarded` field of the stream packet context of CTF v1.8.2.
>>
>> The type of the field located using the `path` property _must_ be an
>> unsigned <<int-field-type,integer field type>>, an unsigned
>> <<enum-field-type,enumeration field type>>, an unsigned
>> <<varint-field-type,variable-length integer field type>>, or an unsigned
>> <<varenum-field-type,variable-length enumeration field type>>.
>>
>> .Discarded event record count field tag
>> ====
>> JSON representation:
>>
>> [source,json]
>> {
>> "tag": "discarded-event-record-count",
>> "path": {
>> "scope": "data-stream-packet-context",
>> "path": ["number of discarded events"]
>> },
>> "reason": "legacy"
>> }
>> ====
>>
>>
>> [[trace-class-fragment]]
>> === Trace class fragment
>>
>> A _trace class fragment_ is a <<metadata-array,fragment>> which defines
>> properties that are common to the whole trace, that is, to all the
>> <<data-stream,data streams>>.
>>
>> Exactly one trace class fragment _must_ exist in a given
>> <<metadata-array,metadata mdt:array>>, and it _must_ precede any
>> <<data-stream-class-fragment,data stream class fragment>>.
>>
>> .Trace class fragment mdt:map properties
>> [options="header"]
>>|===
>>|Name |Type |Description |Required? |Default m-value
>>
>>|`fragment`
>>|mdt:string
>>|_Must_ be set to `trace-class`.
>>|Required
>>|
>>
>>|`user-attrs`
>>|<<user-attrs,User attributes mdt:map>>
>>|User attributes.
>>|Optional
>>|Empty mdt:map value.
>>
>>|`default-byte-order`
>>|<<byte-order,Byte order mdt:string>> (excluding `default`)
>>|Trace's default byte order.
>>|Optional
>>|No trace's default byte order.
>>
>> Note that, if this property is missing, no field types in the whole
>> <<metadata-array,metadata mdt:array>> can have a
>> `byte-order` property set to `default`.
>>
>>|`uuid`
>>|mdt:string
>>|https://en.wikipedia.org/wiki/Universally_unique_identifier[UUID]
>> (canonical form) of the trace.
>>|Optional
>>|No trace UUID.
>>
>>|`packet-header-field-type`
>>|<<field-type-m-value,Field type m-value>>
>>|Field type of the trace packet header field.
>>
>> The name of this scope is `trace-packet-header`, to locate it
>> with an <<abs-field-path,absolute field path mdt:map>>.
>>|Optional
>>|1-bit aligned <<null-field-type,null field type>>.
>>
>>|`tags`
>>|mdt:array of <<field-tag,field tag mdt:map values>>.
>>|Field tags of this trace class. See the allowed field tags below.
>>
>> Upper layers may also define specific field tags that are allowed here.
>>|Optional
>>|Empty mdt:array value.
>>|===
>>
>> .Trace class fragment
>> ====
>> JSON representation:
>>
>> [source,json]
>> {
>> "fragment": "trace-class",
>> "default-byte-order": "le",
>> "uuid": "1255cddc-5afe-4b4a-92b2-17aa5dde2ea6",
>> "packet-header-field-type": {
>> "field-type": "struct",
>> "fields": [
>> {
>> "name": "the magic",
>> "field-type": "uint32"
>> },
>> {
>> "name": "the uuid",
>> "field-type": {
>> "field-type": "array",
>> "element-field-type": "uint8"
>> }
>> },
>> {
>> "name": "the data stream class ID",
>> "field-type": "uint8"
>> }
>> ]
>> },
>> "tags": [
>> {
>> "tag": "magic",
>> "path": {
>> "scope": "trace-packet-header",
>> "path": ["the magic"]
>> }
>> },
>> {
>> "tag": "uuid",
>> "path": {
>> "scope": "trace-packet-header",
>> "path": ["the uuid"]
>> }
>> },
>> {
>> "tag": "data-stream-class-id",
>> "path": {
>> "scope": "trace-packet-header",
>> "path": ["the data stream class ID"]
>> }
>> }
>> ],
>> "user-attrs": {
>> "my ns": "yes"
>> }
>> }
>> ====
>>
>>
>> ==== Allowed field tags targetting trace packet header fields
>>
>> In addition to the tags below,
>> <<discarded-event-record-count-field-tag,discarded event record count
>> field tags>> are allowed, and any field tag defined by the upper layers
>> of CTF{nbsp}2.
>>
>> .Trace class fragment's allowed tags for the trace packet header fields
>> [options="header"]
>>|===
>>|Tag name |Meaning |Tagged field constraints
>>
>>|`magic`
>>|**Magic number field**.
>>
>> This field indicates the CTF{nbsp}2 data stream magic number.
>>
>>|This field _must_ be the first field of the trace packet header field
>> type.
>>
>> This field's type _must_ be a 32-bit unsigned <<int-field-type,integer
>> field type>>.
>>
>> The value of this field in all the data streams _must_ be 3254525889
>> (0xc1fc1fc1).
>>
>>|`uuid`
>>|**Trace's UUID field**.
>>
>> This field indicates the UUID of the trace.
>>
>>|This field's type _must_ be an <<array-field-type,array field type>>
>> of length 16, with an 8-bit aligned, 8-bit
>> <<int-field-type,integer field type>> as its element.
>>
>> The value of this field in all the data streams _must_ be equal to the
>> binary equivalent of the trace class fragment's `uuid` property.
>>
>>|`data-stream-class-id`
>>|**Data stream class ID field**.
>>
>> This field indicates the numeric ID of the
>> <<data-stream-class-fragment,data stream class>> used to encode the rest
>> of the packet.
>>
>> If this tag is not specified, the ID of the data stream class used to
>> encode the rest of the packet is implicitly 0.
>>
>> If more than one field are tagged with this tag, the _last_ one to be
>> encoded in the entire trace packet header field is the effective ID of
>> the data stream class used to encode the rest of the <<packet,packet>>.
>>
>>|This field's type _must_ be an unsigned
>> <<int-field-type,integer field type>>, an unsigned
>> <<enum-field-type,enumeration field type>>, an unsigned
>> <<varint-field-type,variable-length integer field type>>, or an
>> unsigned <<varenum-field-type,variable-length enumeration field type>>.
>>
>>|[[data-stream-id]]`data-stream-id`
>>|**Data stream ID field**.
>>
>> This field indicates the unique numeric ID of the <<data-stream,data
>> stream>> to which the packet belongs.
>>
>> If this tag is not specified, the data stream to which the packet
>> belongs is identified using the storage or transport back-end of the
>> trace.
>>
>> If more than one field are tagged with this tag, the _last_ one to be
>> encoded in the entire trace packet header field is the effective unique
>> data stream ID.
>>
>>|This field's type _must_ be an unsigned
>> <<int-field-type,integer field type>>, an unsigned
>> <<enum-field-type,enumeration field type>>, an unsigned
>> <<varint-field-type,variable-length integer field type>>, or an
>> unsigned <<varenum-field-type,variable-length enumeration field type>>.
>>|===
>>
>>
>> [[data-stream-class-fragment]]
>> === Data stream class fragment
>>
>> A _data stream class fragment_ is a <<metadata-array,fragment>> which
>> defines properties that are common to one or more <<data-stream,data
>> streams>>.
>>
>> More than one data stream class fragment may exist in a given
>> <<metadata-array,metadata mdt:array>>, but they must come after the
>> <<trace-class-fragment,trace class fragment>>.
>>
>> Any <<event-record-class-fragment,event record class fragment>> which is
>> a child of a given data stream class fragment must come after the latter
>> in the metadata mdt:array.
>>
>> .Data stream class fragment mdt:map properties
>> [options="header"]
>>|===
>>|Name |Type |Description |Required? |Default m-value
>>
>>|`fragment`
>>|mdt:string
>>|_Must_ be set to `data-stream-class`.
>>|Required
>>|
>>
>>|`user-attrs`
>>|<<user-attrs,User attributes mdt:map>>
>>|User attributes.
>>|Optional
>>|Empty mdt:map value.
>>
>>|`id`
>>|mdt:int
>>|Data stream class's numeric ID.
>>|Optional
>>|0
>>
>>|`packet-context-field-type`
>>|<<field-type-m-value,Field type m-value>>
>>|Field type of the data stream packet context field.
>>
>> The name of this scope is `data-stream-packet-context`, to locate it
>> with an <<abs-field-path,absolute field path mdt:map>>.
>>|Optional
>>|1-bit aligned <<null-field-type,null field type>>.
>>
>>|`event-record-context-field-type`
>>|<<field-type-m-value,Field type m-value>>
>>|Field type of the data stream event record context field.
>>
>> The name of this scope is `data-stream-event-record-context`, to refer
>> to it with an <<abs-field-path,absolute field path mdt:map>>.
>>|Optional
>>|1-bit aligned <<null-field-type,null field type>>.
>>
>>|`event-record-header-field-type`
>>|<<field-type-m-value,Field type m-value>>
>>|Field type of the data stream event record header field.
>>
>> The name of this scope is `data-stream-event-record-header`, to refer
>> to it with an <<abs-field-path,absolute field path mdt:map>>.
>>|Optional
>>|1-bit aligned <<null-field-type,null field type>>.
>>
>>|`tags`
>>|mdt:array of <<field-tag,field tag mdt:map values>>.
>>|Field tags of this data stream class. See the allowed field tags below.
>>
>> Upper layers may also define specific field tags that are allowed here.
>>|Optional
>>|Empty mdt:array value.
>>|===
>>
>> Two data stream class fragments with the same `id` property cannot exist
>> in the same <<metadata-array,metadata mdt:array>>.
>>
>> .Data stream class fragment
>> ====
>> JSON representation:
>>
>> [source,json]
>> {
>> "fragment": "data-stream-class",
>> "id": 3,
>> "packet-context-field-type": {
>> "field-type": "struct",
>> "fields": [
>> {
>> "name": "packet size",
>> "field-type": "uint32"
>> },
>> {
>> "name": "content size",
>> "field-type": "uint32"
>> },
>> {
>> "name": "discarded events",
>> "field-type": "uint32"
>> },
>> {
>> "name": "timestamp begin",
>> "field-type": "uint64"
>> },
>> {
>> "name": "timestamp end",
>> "field-type": "uint64"
>> },
>> {
>> "name": "cpu ID",
>> "field-type": "uint8"
>> }
>> ]
>> },
>> "event-record-header-field-type": {
>> "field-type": "struct",
>> "fields": [
>> {
>> "name": "ID",
>> "field-type": {
>> "field-type": "enum",
>> "size": 5,
>> "members": {
>> "compact": [{"lower": 0, "upper": 30}],
>> "extended": [31]
>> }
>> }
>> },
>> {
>> "name": "compact or extended",
>> "field-type": {
>> "field-type": "variant",
>> "tag": ["ID"],
>> "choices": [
>> {
>> "name": "compact",
>> "field-type": {
>> "field-type": "struct",
>> "fields": [
>> {
>> "name": "timestamp",
>> "field-type": "uint27"
>> }
>> ]
>> }
>> },
>> {
>> "name": "extended",
>> "field-type": {
>> "field-type": "struct",
>> "fields": [
>> {
>> "name": "ID",
>> "field-type": "uint32"
>> },
>> {
>> "name": "timestamp",
>> "field-type": "uint64"
>> }
>> ]
>> }
>> }
>> ]
>> }
>> }
>> ]
>> },
>> "tags": [
>> {
>> "tag": "packet-total-size",
>> "path": {
>> "scope": "data-stream-packet-context",
>> "path": ["packet size"]
>> }
>> },
>> {
>> "tag": "packet-content-size",
>> "path": {
>> "scope": "data-stream-packet-context",
>> "path": ["content size"]
>> }
>> },
>> {
>> "tag": "discarded-event-record-count",
>> "path": {
>> "scope": "data-stream-packet-context",
>> "path": ["discarded events"]
>> },
>> "reason": "legacy"
>> },
>> {
>> "tag": "event-record-class-id",
>> "path": {
>> "scope": "data-stream-event-record-header",
>> "path": ["ID"]
>> }
>> },
>> {
>> "tag": "event-record-class-id",
>> "path": {
>> "scope": "data-stream-event-record-header",
>> "path": ["compact or extended", "ID"]
>> }
>> }
>> ],
>> "user-attrs": {
>> "my ns": "yes"
>> }
>> }
>> ====
>>
>>
>> ==== Allowed field tags targetting data stream packet context fields
>>
>> In addition to the tags below,
>> <<discarded-event-record-count-field-tag,discarded event record count
>> field tags>> are allowed, and any field tag defined by the upper layers
>> of CTF{nbsp}2.
>>
>> .Data stream class fragment's allowed tags for the data stream packet context
>> fields
>> [options="header"]
>>|===
>>|Tag name |Meaning |Tagged field constraints
>>
>>|`packet-total-size`
>>|**Packet's total size field**.
>>
>> This field indicates the size, in bits, of the _whole_ <<packet,packet>>
>> in which this data stream packet context field is encoded. This size
>> includes the padding bits after the packet's content, if any.
>>
>> If this tag is not specified, this is the only packet of its data
>> stream, that is, it ends where the <<data-stream,data stream>> ends.
>>
>>|This field's type _must_ be an unsigned
>> <<int-field-type,integer field type>>, an unsigned
>> <<enum-field-type,enumeration field type>>, an unsigned
>> <<varint-field-type,variable-length integer field type>>, or an
>> unsigned <<varenum-field-type,variable-length enumeration field type>>.
>>
>>|`packet-content-size`
>>|**Packet's content size field**.
>>
>> This field indicates the content size, in bits, of the <<packet,packet>>
>> in which this data stream packet context field is encoded. The packet's
>> content size is the number of bits from the packet's first bit to the
>> last bit of the last event record (included). The difference between the
>> packet's total size and the packet's content size is the padding size.
>>
>> If this tag is not specified, the packet has no padding bits, thus its
>> content size is the same as its total size.
>>
>>|This field's type _must_ be an unsigned
>> <<int-field-type,integer field type>>, an unsigned
>> <<enum-field-type,enumeration field type>>, an unsigned
>> <<varint-field-type,variable-length integer field type>>, or an
>> unsigned <<varenum-field-type,variable-length enumeration field type>>.
>>
>>|`packet-sequence-number`
>>|**Packet's sequence number field**.
>>
>> This field indicates the sequence number of the packet in which this
>> data stream packet context field is encoded. This is the zero-based
>> index of the packet within its <<data-stream,data stream>>.
>>
>>|This field's type _must_ be an unsigned
>> <<int-field-type,integer field type>>, an unsigned
>> <<enum-field-type,enumeration field type>>, an unsigned
>> <<varint-field-type,variable-length integer field type>>, or an
>> unsigned <<varenum-field-type,variable-length enumeration field type>>.
>>|===
>>
>>
>> ==== Allowed field tags targetting data stream event record header fields
>>
>> In addition to the tags below, any field tag defined by the upper layers
>> of CTF{nbsp}2 is allowed.
>>
>> .Data stream class fragment's allowed tags for the data stream event record
>> header fields
>> [options="header"]
>>|===
>>|Tag name |Meaning |Tagged field constraints
>>
>>|`event-record-class-id`
>>|**Event record class ID field**.
>>
>> This field indicates the numeric ID of the
>> <<event-record-class-fragment,event record class>> used to encode the
>> rest of the <<event-record,event record>>.
>>
>> If this tag is not specified, the ID of the event record class used to
>> encode the rest of the event record is implicitly 0.
>>
>> If more than one field are tagged with this tag, the _last_ one to be
>> encoded in the entire data stream event record header field is the
>> effective ID of the event record class used to encode the rest of the
>> event record.
>>
>>|This field's type _must_ be an unsigned
>> <<int-field-type,integer field type>>, an unsigned
>> <<enum-field-type,enumeration field type>>, an unsigned
>> <<varint-field-type,variable-length integer field type>>, or an
>> unsigned <<varenum-field-type,variable-length enumeration field type>>.
>>|===
>>
>>
>> [[event-record-class-fragment]]
>> === Event record class fragment
>>
>> An _event record class fragment_ is a <<metadata-array,fragment>> which
>> defines properties that are common to one or more event records.
>>
>> More than one event record class fragment may exist in a given
>> <<metadata-array,metadata mdt:array>>, but they must come after their
>> parent <<data-stream-class-fragment,data stream class fragment>>.
>>
>> .Event record class fragment mdt:map properties
>> [options="header"]
>>|===
>>|Name |Type |Description |Required? |Default m-value
>>
>>|`fragment`
>>|mdt:string
>>|_Must_ be set to `event-record-class`.
>>|Required
>>|
>>
>>|`user-attrs`
>>|<<user-attrs,User attributes mdt:map>>
>>|User attributes.
>>|Optional
>>|Empty mdt:map value.
>>
>>|`id`
>>|mdt:int
>>|Event record class's numeric ID.
>>|Optional
>>|0
>>
>>|`parent-data-stream-class-id`
>>|mdt:int
>>|Numeric ID of parent <<data-stream-class-fragment,data stream class>>.
>>|Optional
>>|0
>>
>>|`context-field-type`
>>|<<field-type-m-value,Field type m-value>>
>>|Field type of the event record context field.
>>
>> The name of this scope is `event-record-context`, to locate it
>> with an <<abs-field-path,absolute field path mdt:map>>.
>>|Optional
>>|1-bit aligned <<null-field-type,null field type>>.
>>
>>|`payload-field-type`
>>|<<field-type-m-value,Field type m-value>>
>>|Field type of the event record payload field.
>>
>> The name of this scope is `event-record-payload`, to locate it
>> with an <<abs-field-path,absolute field path mdt:map>>.
>>|Optional
>>|1-bit aligned <<null-field-type,null field type>>.
>>
>>|`tags`
>>|mdt:array of <<field-tag,field tag mdt:map values>>.
>>|Field tags of this event record class.
>>
>> Upper layers may also define specific field tags that are allowed here.
>>|Optional
>>|Empty mdt:array value.
>>|===
>>
>> Two event record class fragments with the same `id` property, and with
>> the same `parent-data-stream-class-id` property, cannot exist in the
>> same <<metadata-array,metadata mdt:array>>.
>>
>> .Event record class fragment
>> ====
>> JSON representation:
>>
>> [source,json]
>> {
>> "fragment": "event-record-class",
>> "id": 45,
>> "parent-data-stream-class-id": 3,
>> "payload-field-type": {
>> "field-type": "struct",
>> "fields": [
>> {
>> "name": "prev_comm",
>> "field-type": {
>> "field-type": "textarray",
>> "length": 16
>> }
>> },
>> {"name": "prev_tid", "field-type": "uint32"},
>> {"name": "prev_prio", "field-type": "uint32"},
>> {"name": "prev_state", "field-type": "uint64"},
>> {
>> "name": "next_comm",
>> "field-type": {
>> "field-type": "textarray",
>> "length": 16
>> }
>> },
>> {"name": "next_tid", "field-type": "uint32"},
>> {"name": "next_prio", "field-type": "uint32"}
>> ]
>> },
>> "user-attrs": {
>> "my ns": "yes"
>> }
>> }
>> ====
>>
>>
>> [[layer-3]]
>> == Layer 3: Timekeeping
>>
>> This layer adds concepts of time to the CTF{nbsp}2 specification. With
>> this layer, timestamps _may_ be associated to packet and event record
>> fields.
>>
>>
>> [[data-stream-clock-class-fragment]]
>> === Data stream clock class fragment
>>
>> A _data stream clock class fragment_ is a <<metadata-array,fragment>>
>> which defines properties that are common to one or more data stream
>> clocks.
>>
>> .Data stream clock class fragment mdt:map properties
>> [options="header"]
>>|===
>>|Name |Type |Description |Required? |Default m-value
>>
>>|`fragment`
>>|mdt:string
>>|_Must_ be set to `data-stream-clock-class`.
>>|Required
>>|
>>
>>|`user-attrs`
>>|<<user-attrs,User attributes mdt:map>>
>>|User attributes.
>>|Optional
>>|Empty mdt:map value.
>>
>>|`name`
>>|mdt:string
>>|Name of this data stream clock class.
>>|Required
>>|
>>
>>|`freq`
>>|mdt:int
>>|Frequency (Hz).
>>|Required
>>|
>>
>>|`uuid`
>>|mdt:string
>>|https://en.wikipedia.org/wiki/Universally_unique_identifier[UUID]
>> (canonical form) of this data stream clock class.
>>|Optional
>>|No UUID.
>>
>>|`error-cycles`
>>|mdt:int
>>|Error in cycles.
>>|Optional
>>|0
>>
>>|`offset-seconds`
>>|mdt:int
>>|Offset in seconds.
>>|Optional
>>|0
>>
>>|`offset-cycles`
>>|mdt:int
>>|Offset in cycles.
>>|Optional
>>|0
>>
>>|`is-absolute`
>>|mdt:bool
>>|_True_ if this data stream clock class defines absolute data stream
>> clocks, that is, clocks that are considered to be global references,
>> even across different UUIDs.
>>|Optional
>>|_False_
>>|===
>>
>> Two data stream clock class fragments with the same `name` property
>> cannot exist in the same <<metadata-array,metadata mdt:array>>.
>>
>> See _Common Trace Format v1.8.2_, section 8, for more information about
>> data stream clock classes (equivalent to TSDL's `clock` block).
>>
>> .Data stream clock class fragment
>> ====
>> JSON representation:
>>
>> [source,json]
>> {
>> "fragment": "data-stream-clock-class",
>> "name": "monotonic",
>> "uuid": "96a25753-91af-4602-a71b-d53b7c3dde45",
>> "freq": 1000000000,
>> "error-cycles": 1000,
>> "offset-seconds": 1326476837,
>> "offset-cycles": 897235420,
>> "is-absolute": true,
>> "user-attrs": {
>> "my ns": "yes"
>> }
>> }
>> ====
>>
>>
>> [[data-stream-clock]]
>> === Data stream clock
>>
>> A _data stream clock_ is an instance of a
>> <<data-stream-clock-class-fragment,data stream clock class>>.
>>
>> Each <<data-stream,data stream>> has one such clock instance for each
>> known data stream clock class.
>>
>> A data stream clock is an integer variable initialized to 0 before
>> decoding the <<data-stream,data stream>> to which it is attached. This
>> variable holds the current value, in cycles, for this specific data
>> stream, of its data stream clock class.
>>
>> When any field tagged with one of the data stream clock update tags is
>> decoded, its associated data stream clock can be updated.
>>
>>
>> [[update-data-stream-clock-now-field-tag]]
>> === Update data stream clock now field tag mdt:map
>>
>> An _update data stream clock now field tag mdt:map_ is a
>> <<field-tag,field tag>> which tags a field to update a data stream clock
>> with its value when it is decoded.
>>
>> .Update data stream clock now field tag mdt:map properties
>> [options="header"]
>>|===
>>|Name |Type |Description |Required? |Default m-value
>>
>>|`path`
>>|<<abs-field-path,Absolute field path mdt:map>>
>>|Absolute path to the tagged field.
>>|Required
>>|
>>
>>|`tag`
>>|mdt:string
>>|_Must_ be set to `update-data-stream-clock-now`.
>>|Required
>>|
>>
>>|`data-stream-clock-class-name`
>>|mdt:string
>>|Name of the data stream clock class of the data stream clock to
>> update.
>>|Required
>>|
>>|===
>>
>> This tag _may_ be used in the `tags` property of a
>> <<trace-class-fragment,trace class fragment mdt:map>>, a
>> <<data-stream-class-fragment,data stream class fragment mdt:map>>, or an
>> <<event-record-class-fragment,event record class fragment mdt:map>>.
>>
>> If this tag is used, a matching <<data-stream-clock-class-fragment,data
>> stream clock class fragment>> _must_ exist in the
>> <<metadata-array,metadata mdt:array>> before the fragment in which it is
>> used.
>>
>> The tagged field's type _must_ be an unsigned <<int-field-type,integer
>> field type>>, an unsigned <<enum-field-type,enumeration field type>>, an
>> unsigned <<varint-field-type,variable-length integer field type>>, or an
>> unsigned <<varenum-field-type,variable-length enumeration field type>>.
>>
>> .Data stream class fragment using this field tag
>> ====
>> JSON representation:
>>
>> [source,json]
>> {
>> "fragment": "data-stream-class",
>> "id": 2,
>> "event-record-header-field-type": {
>> "field-type": "struct",
>> "fields": [
>> {
>> "name": "ts",
>> "field-type": "uint32"
>> }
>> ]
>> },
>> "tags": [
>> {
>> "tag": "update-data-stream-clock-now",
>> "data-stream-clock-class-name": "monotonic",
>> "path": {
>> "scope": "data-stream-event-record-header",
>> "path": ["ts"]
>> }
>> }
>> ]
>> }
>> ====
>>
>>
>> [[update-data-stream-clock-after-packet-field-tag]]
>> === Update data stream clock after packet field tag mdt:map
>>
>> An _update data stream clock after packet field tag mdt:map_ is a
>> <<field-tag,field tag>> which tags a field to update a data stream clock
>> with its value after the whole packet is decoded (delayed update).
>>
>> .Update data stream clock after packet field tag mdt:map properties
>> [options="header"]
>>|===
>>|Name |Type |Description |Required? |Default m-value
>>
>>|`path`
>>|<<abs-field-path,Absolute field path mdt:map>>
>>|Absolute path to the tagged field.
>>|Required
>>|
>>
>>|`tag`
>>|mdt:string
>>|_Must_ be set to `update-data-stream-clock-after-packet`.
>>|Required
>>|
>>
>>|`data-stream-clock-class-name`
>>|mdt:string
>>|Name of the data stream clock class of the data stream clock to
>> update.
>>|Required
>>|
>>|===
>>
>> This tag is only allowed in the `tags` property of a
>> <<data-stream-class-fragment,data stream class fragment mdt:map>>. It
>> _must_ target the `data-stream-packet-context` scope.
>>
>> If this tag is used, a matching <<data-stream-clock-class-fragment,data
>> stream clock class fragment>>
>> _must_ exist in the <<metadata-array,metadata mdt:array>>
>> before the fragment in which it is used.
>>
>> The tagged field's type _must_ be an unsigned <<int-field-type,integer
>> field type>>, an unsigned <<enum-field-type,enumeration field type>>, an
>> unsigned <<varint-field-type,variable-length integer field type>>, or an
>> unsigned <<varenum-field-type,variable-length enumeration field type>>.
>>
>>
>> == Complete metadata stream example
>>
>> Here's an example of a complete, valid <<metadata-stream,metadata
>> stream>>. It contains one <<data-stream-class-fragment,data stream class
>> fragment>> with two <<event-record-class-fragment,event record class
>> fragments>> as its children.
>>
>> [source,json]
>> ----
>> [
>> "CTF 2",
>> {
>> "fragment": "field-type-alias",
>> "name": "uint8",
>> "field-type": {
>> "field-type": "int",
>> "size": 8,
>> "align": 8
>> }
>> },
>> {
>> "fragment": "field-type-alias",
>> "name": "uint16",
>> "field-type": {
>> "field-type": "int",
>> "size": 16,
>> "align": 8
>> }
>> },
>> {
>> "fragment": "field-type-alias",
>> "name": "uint32",
>> "field-type": {
>> "field-type": "int",
>> "size": 32,
>> "align": 8
>> }
>> },
>> {
>> "fragment": "field-type-alias",
>> "name": "uint64",
>> "field-type": {
>> "field-type": "int",
>> "size": 64,
>> "align": 8
>> }
>> },
>> {
>> "fragment": "field-type-alias",
>> "name": "int64",
>> "field-type": {
>> "field-type": "int",
>> "size": 64,
>> "align": 8,
>> "signed": true
>> }
>> },
>> {
>> "fragment": "field-type-alias",
>> "name": "uint27",
>> "field-type": {
>> "field-type": "int",
>> "size": 27
>> }
>> },
>> {
>> "fragment": "field-type-alias",
>> "name": "uuid",
>> "field-type": {
>> "field-type": "array",
>> "alignment": 8,
>> "length": 16,
>> "field-type": "uint8"
>> }
>> },
>> {
>> "fragment": "trace-class",
>> "default-byte-order": "le",
>> "uuid": "908d7a0d-2bbc-4584-ba3b-a9c73a62f52e",
>> "packet-header-field-type": {
>> "field-type": "struct",
>> "fields": [
>> {
>> "name": "the magic",
>> "field-type": "uint32"
>> },
>> {
>> "name": "the UUID",
>> "field-type": "uuid"
>> },
>> {
>> "name": "ids",
>> "field-type": {
>> "field-type": "struct",
>> "fields": [
>> {
>> "name": "data stream class",
>> "field-type": "uint8"
>> },
>> {
>> "name": "data stream",
>> "field-type": "uint8"
>> }
>> ]
>> }
>> }
>> ]
>> },
>> "tags": [
>> {
>> "tag": "magic",
>> "path": {
>> "scope": "trace-packet-header",
>> "path": ["the magic"]
>> }
>> },
>> {
>> "tag": "uuid",
>> "path": {
>> "scope": "trace-packet-header",
>> "path": ["the UUID"]
>> }
>> },
>> {
>> "tag": "data-stream-class-id",
>> "path": {
>> "scope": "trace-packet-header",
>> "path": ["ids", "data stream class"]
>> }
>> },
>> {
>> "tag": "data-stream-id",
>> "path": {
>> "scope": "trace-packet-header",
>> "path": ["ids", "data stream"]
>> }
>> }
>> ]
>> },
>> {
>> "fragment": "data-stream-clock-class",
>> "name": "clock src",
>> "uuid": "96a25753-91af-4602-a71b-d53b7c3dde45",
>> "freq": 1000000000,
>> "error-cycles": 1000,
>> "offset-seconds": 1326476837,
>> "offset-cycles": 897235420,
>> "is-absolute": true,
>> },
>> {
>> "fragment": "data-stream-class",
>> "packet-context-field-type": {
>> "field-type": "struct",
>> "fields": [
>> {
>> "name": "packet sizes",
>> "field-type": {
>> "field-type": "struct",
>> "fields": [
>> {
>> "name": "total",
>> "field-type": "uint32"
>> },
>> {
>> "name": "content",
>> "field-type": "uint32"
>> }
>> ]
>> }
>> },
>> {
>> "name": "discarded events",
>> "field-type": "uint32"
>> },
>> {
>> "name": "sequence number",
>> "field-type": "uint64"
>> },
>> {
>> "name": "packet begin TS",
>> "field-type": "uint64"
>> },
>> {
>> "name": "packet end TS",
>> "field-type": "uint64"
>> },
>> {
>> "name": "cpu ID",
>> "field-type": "uint8"
>> },
>> ]
>> },
>> "event-record-header-field-type": {
>> "field-type": "struct",
>> "fields": [
>> {
>> "name": "ID",
>> "field-type": {
>> "field-type": "enum",
>> "size": 5,
>> "members": {
>> "compact": [{"lower": 0, "upper": 30}],
>> "extended": [31]
>> }
>> }
>> },
>> {
>> "name": "compact or extended",
>> "field-type": {
>> "field-type": "variant",
>> "tag": ["ID"],
>> "choices": [
>> {
>> "name": "compact",
>> "field-type": {
>> "field-type": "struct",
>> "fields": [
>> {
>> "name": "timestamp",
>> "field-type": "uint27"
>> }
>> ]
>> }
>> },
>> {
>> "name": "extended",
>> "field-type": {
>> "field-type": "struct",
>> "fields": [
>> {
>> "name": "ID",
>> "field-type": "uint32"
>> },
>> {
>> "name": "timestamp",
>> "field-type": "uint64"
>> }
>> ]
>> }
>> }
>> ]
>> }
>> }
>> ]
>> },
>> "tags": [
>> {
>> "tag": "packet-total-size",
>> "path": {
>> "scope": "data-stream-packet-context",
>> "path": ["packet sizes", "total"]
>> }
>> },
>> {
>> "tag": "packet-content-size",
>> "path": {
>> "scope": "data-stream-packet-context",
>> "path": ["packet sizes", "content"]
>> }
>> },
>> {
>> "tag": "discarded-event-record-count",
>> "path": {
>> "scope": "data-stream-packet-context",
>> "path": ["discarded events"]
>> }
>> },
>> {
>> "tag": "packet-sequence-number",
>> "path": {
>> "scope": "data-stream-packet-context",
>> "path": ["sequence number"]
>> }
>> },
>> {
>> "tag": "update-data-stream-clock-now",
>> "data-stream-clock-class-name": "clock src",
>> "path": {
>> "scope": "data-stream-packet-context",
>> "path": ["packet begin TS"]
>> }
>> },
>> {
>> "tag": "update-data-stream-clock-after-packet",
>> "data-stream-clock-class-name": "clock src",
>> "path": {
>> "scope": "data-stream-packet-context",
>> "path": ["packet end TS"]
>> }
>> },
>> {
>> "tag": "event-record-class-id",
>> "path": {
>> "scope": "data-stream-event-record-header",
>> "path": ["ID"]
>> }
>> },
>> {
>> "tag": "event-record-class-id",
>> "path": {
>> "scope": "data-stream-event-record-header",
>> "path": ["compact or extended", "ID"]
>> }
>> },
>> {
>> "tag": "update-data-stream-clock-now",
>> "data-stream-clock-class-name": "clock src",
>> "path": {
>> "scope": "data-stream-event-record-header",
>> "path": ["compact or extended", "timestamp"]
>> }
>> }
>> ]
>> },
>> {
>> "fragment": "field-type-alias",
>> "name": "comm",
>> "field-type": {
>> "field-type": "textarray",
>> "length": 16
>> }
>> },
>> {
>> "fragment": "event-record-class",
>> "id": 0,
>> "payload-field-type": {
>> "field-type": "struct",
>> "fields": [
>> {"name": "prev_comm", "field-type": "comm"},
>> {"name": "prev_tid", "field-type": "uint32"},
>> {"name": "prev_prio", "field-type": "uint32"},
>> {"name": "prev_state", "field-type": "uint64"},
>> {"name": "next_comm", "field-type": "comm"},
>> {"name": "next_tid", "field-type": "uint32"},
>> {"name": "next_prio", "field-type": "uint32"}
>> ]
>> }
>> },
>> {
>> "fragment": "event-record-class",
>> "id": 1,
>> "payload-field-type": {
>> "field-type": "struct",
>> "fields": [
>> {"name": "ret", "field-type": "int64"},
>> {"name": "addr", "field-type": "uint64"},
>> {"name": "len", "field-type": "uint64"},
>> {"name": "prot", "field-type": "uint64"},
>> {"name": "flags", "field-type": "uint64"},
>> {"name": "fd", "field-type": "uint64"},
>> {"name": "pgoff", "field-type": "uint64"}
>> ]
>> }
>> }
>> ]
>> ----
>> _______________________________________________
>> lttng-dev mailing list
>> lttng-dev at lists.lttng.org
>> https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev
>
> --
> Mathieu Desnoyers
> EfficiOS Inc.
> http://www.efficios.com
> _______________________________________________
> lttng-dev mailing list
> lttng-dev at lists.lttng.org
> https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev
--
Mathieu Desnoyers
EfficiOS Inc.
http://www.efficios.com
More information about the lttng-dev
mailing list