Split CTF IR and CTF writer APIs and implementations
authorPhilippe Proulx <eeppeliteloop@gmail.com>
Sat, 7 Apr 2018 17:20:16 +0000 (13:20 -0400)
committerPhilippe Proulx <eeppeliteloop@gmail.com>
Thu, 2 May 2019 04:05:45 +0000 (00:05 -0400)
commit3dca22768a95bef664012559aa9ac977091de6ac
treedd23ef43d0dabcdd0550d547e899063c5cab9faa
parentd975f66c5dcfc7eade13db3edbc975d2055dfe4b
Split CTF IR and CTF writer APIs and implementations

This patch splits the CTF IR and CTF writer APIs, previously implemented
at a single place with aliases to make CTF writer functions and types be
synonymous to CTF IR ones, with as much common code as possible for both
APIs.

The goal of this change is to be able to modify one API/implementation
without disturbing the other, optimization being one major use case.

Common API
==========
Most of the CTF IR and CTF writer functions perform the exact same
tasks. Some functions, however, have minor differences. For example,
bt_trace_add_stream_class() tries to automatically map specific integer
field types to the stream class's CTF writer clock's class if the trace
object was created by a CTF writer object.

To keep as much common code as possible, `struct bt_*_common` types and
bt_*_common() functions are introduced. A common structure contains the
common data needed for both CTF IR and CTF writer, while actual
CTF IR/writer structures "inherit" this one. For example:

    struct bt_stream_common {
        struct bt_object base;
        int64_t id;
        struct bt_stream_class_common *stream_class;
        GString *name;
        GArray *destroy_listeners;
    };

    struct bt_stream {
        struct bt_stream_common common;
    };

    struct bt_ctf_stream {
        struct bt_stream_common common;
        struct bt_ctf_field *packet_header;
        struct bt_ctf_field *packet_context;
        GPtrArray *events;
        struct bt_ctf_stream_pos pos;
        unsigned int flushed_packet_count;
        uint64_t discarded_events;
        uint64_t size;
        uint64_t last_ts_end;
    };

All bt_stream_common_*() functions require a pointer to
`struct bt_stream_common`. You can use the BT_TO_COMMON() and
BT_FROM_COMMON() macros of `include/babeltrace/ctf-ir/utils-internal.h`
to statically cast the pointers in each direction. BT_TO_COMMON() needs
the concrete (non-common) structure to have a common structure member
named `common`.

A concrete implementation is responsible for the allocation and
deallocation of its objects, but the common API provides internal
functions to initialize and finalize the common parts. Examples are
bt_event_common_initialize(), bt_event_class_common_finalize(), and
bt_field_type_common_floating_point_initialize(). Those initialization
functions take a `release_func` parameter which is the concrete object
destruction function. The latter is responsible for finalizing the
specific part, calling bt_*_common_finalize() to finalize the common
part, and deallocating the object.

Most of the concrete functions look like this:

    struct bt_field_type *bt_event_class_get_payload_field_type(
            struct bt_event_class *event_class)
    {
        return BT_FROM_COMMON(bt_event_class_common_get_payload_field_type(
            BT_TO_COMMON(event_class)));
    }

Some common functions are more complicated and can be considered
template methods: they take various options and callback functions to be
called at specific places within the procedure.
bt_event_common_initialize() and bt_trace_common_add_stream_class() are
obvious examples.

The cases of field types and fields are special because those structures
already use inheritance: an integer field type structure inherits the
field type structure. In order for all the APIs to be able to statically
cast to the appropriate types, here's how a concrete field type is
arranged:

    +------------------------------------+
    | Common field type                  | <- bt_field_type_common_*()
    +------------------------------------+
    | Concrete common field type (union) | <- bt_(ctf_)field_type_*()
    +------------------------------------+
    | Common specific field type         | <- bt_field_type_common_integer_*()
    +------------------------------------+
    | Specific field type                | <- bt_(ctf_)field_type_integer_*()
    +------------------------------------+

The four parts are at a fixed offset.

Field objects follow the same structure.

As of this patch, `struct bt_field_type`, `struct bt_ctf_field_type`,
`struct bt_field`, and `struct bt_ctf_field` are only forward-declared
and always `(void *)` casted to and from the appropriate common type for
public APIs because they don't add specific data. For example:

    int bt_ctf_field_type_set_alignment(struct bt_ctf_field_type *ft,
            unsigned int alignment)
    {
        return bt_field_type_common_set_alignment((void *) ft, alignment);
    }

Also of interest is `struct bt_ctf_clock_class` which includes
`struct bt_clock_class`: there's no `struct bt_clock_class_common`
because as of this patch we don't expect a CTF IR clock class property
to be absent from a CTF writer clock class.

As of this patch, the common API and implementation are in the same
source and header files as CTF IR. Fast path common functions (most
getters and almost everything related to fields and events) are
implemented in internal header files as `static inline` functions.

Logging
=======
BT_LIB_LOG(), and consequently BT_ASSERT_PRE() and its variants, is
modified with an added prefix character to distinguish a CTF IR object
from a CTF writer object and from a common object. The prefix character
is inserted just before the format specifier: `_` means a common object
(underscore as in low as in base), and `w` means a CTF writer object. No
prefix means a CTF IR or other object (graph objects, value objects,
etc.).

Using `%!+_t` with a CTF IR trace object, for example, is correct
because it inherits the common part, but using `%!+t` with a common
trace object could eventually lead to bad data or to a segmentation
fault.

See the updated description in
`include/babeltrace/lib-logging-internal.h` for more details.

Testing
=======
Some tests in `tests/lib` are modified because they used a mix of CTF IR
and CTF writer APIs. Also there is a new precondition that a CTF IR
event class must be part of a trace before you can create an event from
it (the CTF writer API does not have this restriction for backward
compatibility reasons): this guarantee could make things easier in the
future and it is acceptable for a CTF IR user.

Some CTF writer tests are removed because they were in fact CTF IR
tests. In the future we should create specific CTF IR tests and reuse
the removed tests.

Limitations
===========
This patch does not address, and reserves for future work:

* Python bindings
* Python bindings tests
* `src.ctf.lttng-live`, `sink.ctf.fs`, `flt.utils.trimmer`,
  `flt.lttng-utils.debug-info`, and `src.text.dmesg` component classes

Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
99 files changed:
cli/Makefile.am
configure.ac
include/Makefile.am
include/babeltrace/babeltrace.h
include/babeltrace/common-internal.h
include/babeltrace/ctf-ir/clock-class-internal.h
include/babeltrace/ctf-ir/clock-class.h
include/babeltrace/ctf-ir/event-class-internal.h
include/babeltrace/ctf-ir/event-class.h
include/babeltrace/ctf-ir/event-internal.h
include/babeltrace/ctf-ir/event.h
include/babeltrace/ctf-ir/field-path-internal.h
include/babeltrace/ctf-ir/field-types-internal.h
include/babeltrace/ctf-ir/field-types.h
include/babeltrace/ctf-ir/fields-internal.h
include/babeltrace/ctf-ir/fields.h
include/babeltrace/ctf-ir/packet-internal.h
include/babeltrace/ctf-ir/resolve-internal.h
include/babeltrace/ctf-ir/stream-class-internal.h
include/babeltrace/ctf-ir/stream-class.h
include/babeltrace/ctf-ir/stream-internal.h
include/babeltrace/ctf-ir/stream.h
include/babeltrace/ctf-ir/trace-internal.h
include/babeltrace/ctf-ir/trace.h
include/babeltrace/ctf-ir/utils-internal.h
include/babeltrace/ctf-ir/utils.h
include/babeltrace/ctf-ir/validation-internal.h
include/babeltrace/ctf-writer/clock-class.h [new file with mode: 0644]
include/babeltrace/ctf-writer/clock-internal.h
include/babeltrace/ctf-writer/clock.h
include/babeltrace/ctf-writer/event-fields.h
include/babeltrace/ctf-writer/event-internal.h [new file with mode: 0644]
include/babeltrace/ctf-writer/event-types.h
include/babeltrace/ctf-writer/event.h
include/babeltrace/ctf-writer/field-types-internal.h [new file with mode: 0644]
include/babeltrace/ctf-writer/field-types.h [new file with mode: 0644]
include/babeltrace/ctf-writer/fields-internal.h [new file with mode: 0644]
include/babeltrace/ctf-writer/fields.h [new file with mode: 0644]
include/babeltrace/ctf-writer/functor-internal.h
include/babeltrace/ctf-writer/serialize-internal.h
include/babeltrace/ctf-writer/stream-class-internal.h [new file with mode: 0644]
include/babeltrace/ctf-writer/stream-class.h
include/babeltrace/ctf-writer/stream-internal.h [new file with mode: 0644]
include/babeltrace/ctf-writer/stream.h
include/babeltrace/ctf-writer/trace-internal.h [new file with mode: 0644]
include/babeltrace/ctf-writer/trace.h [new file with mode: 0644]
include/babeltrace/ctf-writer/writer-internal.h
include/babeltrace/ctf-writer/writer.h
include/babeltrace/lib-logging-internal.h
lib/ctf-ir/clock-class.c
lib/ctf-ir/event-class.c
lib/ctf-ir/event.c
lib/ctf-ir/field-types.c
lib/ctf-ir/fields.c
lib/ctf-ir/packet.c
lib/ctf-ir/resolve.c
lib/ctf-ir/stream-class.c
lib/ctf-ir/stream.c
lib/ctf-ir/trace.c
lib/ctf-ir/utils.c
lib/ctf-ir/validation.c
lib/ctf-writer/Makefile.am
lib/ctf-writer/clock.c
lib/ctf-writer/event-class.c [new file with mode: 0644]
lib/ctf-writer/event.c [new file with mode: 0644]
lib/ctf-writer/field-types.c [new file with mode: 0644]
lib/ctf-writer/fields.c [new file with mode: 0644]
lib/ctf-writer/functor.c
lib/ctf-writer/serialize.c
lib/ctf-writer/stream-class.c [new file with mode: 0644]
lib/ctf-writer/stream.c [new file with mode: 0644]
lib/ctf-writer/trace.c [new file with mode: 0644]
lib/ctf-writer/writer.c
lib/graph/iterator.c
lib/graph/notification/event.c
lib/graph/notification/packet.c
lib/graph/notification/stream.c
lib/lib-logging.c
plugins/Makefile.am
plugins/ctf/Makefile.am
plugins/ctf/common/btr/btr.c
plugins/ctf/common/metadata/visitor-generate-ir.c
plugins/ctf/common/notif-iter/notif-iter.c
plugins/ctf/common/utils/utils.c
plugins/ctf/fs-src/data-stream-file.c
plugins/ctf/fs-src/fs.c
plugins/ctf/fs-src/fs.h
plugins/ctf/plugin.c
plugins/text/Makefile.am
plugins/text/plugin.c
plugins/text/pretty/print.c
plugins/utils/Makefile.am
plugins/utils/plugin.c
tests/lib/test_bt_ctf_field_type_validation.c
tests/lib/test_bt_notification_iterator.c
tests/lib/test_ctf_ir_ref.c
tests/lib/test_ctf_writer.c
tests/lib/test_ir_visit.c
tests/plugins/test-utils-muxer.c
This page took 0.033559 seconds and 4 git commands to generate.