From: Philippe Proulx Date: Tue, 25 Nov 2014 23:28:39 +0000 (-0500) Subject: Add examples X-Git-Url: http://drtracing.org/?a=commitdiff_plain;h=ca3417e6f2a66d583a5072240b4e379062ddd3b1;p=deliverable%2Fbarectf.git Add examples --- diff --git a/README.md b/README.md index c3d3e02..79f4bd2 100644 --- a/README.md +++ b/README.md @@ -69,6 +69,9 @@ Using barectf involves: The following subsections explain the three steps above. +Also, have a look at the [`examples`](examples) directory which +contains a few complete examples. + ### writing the CTF metadata diff --git a/examples/simple/Makefile b/examples/simple/Makefile new file mode 100644 index 0000000..058f038 --- /dev/null +++ b/examples/simple/Makefile @@ -0,0 +1,27 @@ +BARECTF ?= barectf +RM = rm -rf + +CFLAGS = -O2 -Wall + +TARGET = simple +OBJS = $(TARGET).o barectf.o + +.PHONY: all view clean + +all: $(TARGET) + +$(TARGET): $(OBJS) + $(CC) -o $@ $^ + +barectf.h barectf.c: ctf/metadata + barectf $< + +barectf.o: barectf.c + $(CC) $(CFLAGS) -Wno-strict-aliasing -Wno-unused-variable -c $< + +$(TARGET).o: $(TARGET).c barectf.h + $(CC) $(CFLAGS) -c $< + +clean: + $(RM) $(TARGET) $(OBJS) ctf/stream* + $(RM) barectf.h barectf_bitfield.h barectf.c diff --git a/examples/simple/ctf/metadata b/examples/simple/ctf/metadata new file mode 100644 index 0000000..e3d36b4 --- /dev/null +++ b/examples/simple/ctf/metadata @@ -0,0 +1,169 @@ +/* CTF 1.8 */ + +typealias integer {size = 8; align = 8;} := uint8_t; +typealias integer {size = 16; align = 16;} := uint16_t; +typealias integer {size = 32; align = 32;} := uint32_t; +typealias integer {size = 64; align = 64;} := uint64_t; +typealias integer {size = 8; align = 8; signed = true;} := int8_t; +typealias integer {size = 16; align = 16; signed = true;} := int16_t; +typealias integer {size = 32; align = 32; signed = true;} := int32_t; +typealias integer {size = 64; align = 64; signed = true;} := int64_t; + +typealias floating_point { + exp_dig = 8; + mant_dig = 24; + align = 32; +} := float; + +typealias floating_point { + exp_dig = 11; + mant_dig = 53; + align = 64; +} := double; + +trace { + major = 1; + minor = 8; + byte_order = le; + + packet.header := struct { + uint32_t magic; + uint32_t stream_id; + }; +}; + +env { + domain = "bare"; + tracer_name = "barectf"; + tracer_major = 0; + tracer_minor = 1; + tracer_patchlevel = 0; +}; + +clock { + name = my_clock; + freq = 1000000000; + offset = 0; +}; + +typealias integer { + size = 64; + map = clock.my_clock.value; +} := my_clock_int_t; + +stream { + id = 0; + + packet.context := struct { + my_clock_int_t timestamp_begin; + my_clock_int_t timestamp_end; + uint64_t packet_size; + uint64_t content_size; + }; + + event.header := struct { + uint32_t id; + my_clock_int_t timestamp; + }; +}; + +/* an event with a simple 32-bit unsigned integer field */ +event { + name = "simple_uint32"; + id = 0; + stream_id = 0; + + fields := struct { + uint32_t _value; + }; +}; + +/* an event with a simple 16-bit signed integer field */ +event { + name = "simple_int16"; + id = 1; + stream_id = 0; + + fields := struct { + int16_t _value; + }; +}; + +/* + * An event with a simple IEEE 754 (see type alias above) single-precision + * floating point number. + */ +event { + name = "simple_float"; + id = 2; + stream_id = 0; + + fields := struct { + float _value; + }; +}; + +/* an event with a simple NULL-terminated string field */ +event { + name = "simple_string"; + id = 3; + stream_id = 0; + + fields := struct { + string _value; + }; +}; + +/* custom enumeration, of which the key is a 8-bit unsigned integer */ +typealias enum : uint8_t { + NEW, /* 0 */ + TERMINATED, /* 1 */ + READY, /* 2 */ + RUNNING, /* 3 */ + WAITING, /* 4 */ +} := state_t; + +/* an event with a simple enumeration (see type alias above) field */ +event { + name = "simple_enum"; + id = 4; + stream_id = 0; + + fields := struct { + state_t _state; + }; +}; + +/* an event with a few fields */ +event { + name = "a_few_fields"; + id = 5; + stream_id = 0; + + fields := struct { + int32_t _int32; + uint16_t _uint16; + double _double; + string _string; + state_t _state; + }; +}; + +/* an event with bit-packed integer fields */ +event { + name = "bit_packed_integers"; + id = 6; + stream_id = 0; + + fields := struct { + integer {size = 1;} _uint1; + integer {size = 1; signed = true;} _int1; + integer {size = 2;} _uint2; + integer {size = 3; signed = true;} _int3; + integer {size = 4;} _uint4; + integer {size = 5; signed = true;} _int5; + integer {size = 6;} _uint6; + integer {size = 7; signed = true;} _int7; + integer {size = 8; align = 1;} _uint8; + }; +}; diff --git a/examples/simple/simple.c b/examples/simple/simple.c new file mode 100644 index 0000000..bf296ee --- /dev/null +++ b/examples/simple/simple.c @@ -0,0 +1,78 @@ +#include +#include +#include +#include + +#include "barectf.h" + +static uint64_t get_clock(void* data) +{ + struct timespec ts; + + clock_gettime(CLOCK_MONOTONIC, &ts); + + return ts.tv_sec * 1000000000UL + ts.tv_nsec; +} + +enum state_t { + NEW, + TERMINATED, + READY, + RUNNING, + WAITING, +}; + +static void simple(uint8_t* buf, size_t sz) +{ + /* initialize barectf context */ + struct barectf_ctx ctx; + struct barectf_ctx* pctx = &ctx; + + barectf_init(pctx, buf, sz, get_clock, NULL); + + /* open packet */ + barectf_open_packet(pctx); + + /* record events */ + barectf_trace_simple_uint32(pctx, 20150101); + barectf_trace_simple_int16(pctx, -2999); + barectf_trace_simple_float(pctx, 23.57); + barectf_trace_simple_string(pctx, "Hello, World!"); + barectf_trace_simple_enum(pctx, RUNNING); + barectf_trace_a_few_fields(pctx, -1, 301, -3.14159, "Hello again!", NEW); + barectf_trace_bit_packed_integers(pctx, 1, -1, 3, -2, 2, 7, 23, -55, 232); + + /* close packet */ + barectf_close_packet(pctx); +} + +static void write_packet(const char* filename, const uint8_t* buf, size_t sz) +{ + FILE* fh = fopen(filename, "wb"); + + if (!fh) { + return; + } + + fwrite(buf, 1, sz, fh); + fclose(fh); +} + +int main(void) +{ + puts("simple barectf example!"); + + const size_t buf_sz = 8192; + + uint8_t* buf = malloc(buf_sz); + + if (!buf) { + return 1; + } + + simple(buf, buf_sz); + write_packet("ctf/stream_0", buf, buf_sz); + free(buf); + + return 0; +}