Document barectf 3
[barectf.git] / docs / modules / platform / pages / example.adoc
1 = Platform example
2 :us: _
3
4 This barectf platform example is a stripped-down version of the
5 https://github.com/efficios/barectf/tree/stable-{page-component-version}/platforms/linux-fs[Linux FS]
6 demonstration platform.
7
8 == Header
9
10 .`my-platform.h`
11 [source,c]
12 ----
13 #ifndef _MY_PLATFORM_H
14 #define _MY_PLATFORM_H
15
16 #ifdef __cplusplus
17 extern "C" {
18 #endif
19
20 /* Platform context */
21 struct my_platform_ctx;
22
23 /* barectf context */
24 struct barectf_my_stream_ctx;
25
26 /* Platform initialization function */
27 struct my_platform_ctx *my_platform_init(unsigned int buf_size,
28 const char *data_stream_file_path);
29
30 /* Platform finalization function */
31 void my_platform_fini(struct my_platform_ctx *platform_ctx);
32
33 /* barectf context pointer access function */
34 struct barectf_my_stream_ctx *my_platform_get_barectf_ctx(
35 struct my_platform_ctx *platform_ctx);
36
37 #ifdef __cplusplus
38 }
39 #endif
40
41 #endif /* _MY_PLATFORM_H */
42 ----
43
44 == Source
45
46 .`my-platform.c`
47 [source,c]
48 ----
49 #include <stdio.h>
50 #include <stdlib.h>
51 #include <stdint.h>
52 #include <assert.h>
53 #include <time.h>
54
55 #include "barectf.h"
56
57 /* Platform context */
58 struct my_platform_ctx {
59 struct barectf_my_stream_ctx ctx;
60 FILE *fh;
61 };
62
63 /* Clock source platform function */
64 static uint64_t my_clock_get_value(void * const data)
65 {
66 struct timespec ts;
67
68 clock_gettime(CLOCK_REALTIME, &ts);
69 return ts.tv_sec * 1000000000ULL + ts.tv_nsec;
70 }
71
72 static void write_packet(const struct my_platform_ctx * const platform_ctx)
73 {
74 /* Append current packet to data stream file */
75 const size_t nmemb = fwrite(barectf_packet_buf_addr(&platform_ctx->ctx),
76 barectf_packet_buf_size(&platform_ctx->ctx),
77 1, platform_ctx->fh);
78
79 assert(nmemb == 1);
80 }
81
82 /* Full back end check platform function */
83 static int is_backend_full(void * const data)
84 {
85 return 0;
86 }
87
88 /* Packet opening platform function */
89 static void open_packet(void * const data)
90 {
91 struct my_platform_ctx * const platform_ctx = data;
92
93 barectf_my_stream_open_packet(&platform_ctx->ctx);
94 }
95
96 /* Packet closing platform function */
97 static void close_packet(void * const data)
98 {
99 struct my_platform_ctx * const platform_ctx = data;
100
101 /* Close packet now */
102 barectf_my_stream_close_packet(&platform_ctx->ctx);
103
104 /* Write packet to file */
105 write_packet(platform_ctx);
106 }
107
108 /* Platform initialization function */
109 struct my_platform_ctx *my_platform_init(const unsigned int buf_size,
110 const char * const data_stream_file_path)
111 {
112 char stream_path[256];
113 uint8_t *buf = NULL;
114 struct my_platform_ctx *platform_ctx;
115 struct barectf_platform_callbacks cbs;
116
117 /* Set platform callback functions */
118 cbs.my_clock_clock_get_value = my_clock_get_value;
119 cbs.is_backend_full = is_backend_full;
120 cbs.open_packet = open_packet;
121 cbs.close_packet = close_packet;
122
123 /* Allocate platform context (which contains a barectf context) */
124 platform_ctx = malloc(sizeof(*platform_ctx));
125
126 if (!platform_ctx) {
127 goto error;
128 }
129
130 /* Allocate packet buffer */
131 buf = malloc(buf_size);
132
133 if (!buf) {
134 goto error;
135 }
136
137 /* Open data stream file */
138 platform_ctx->fh = fopen(data_stream_file_path, "wb");
139
140 if (!platform_ctx->fh) {
141 goto error;
142 }
143
144 /* Initialize barectf context */
145 barectf_init(&platform_ctx->ctx, buf, buf_size, cbs, platform_ctx);
146
147 /* Open the first packet */
148 open_packet(platform_ctx);
149
150 goto end;
151
152 error:
153 free(platform_ctx);
154 free(buf);
155
156 end:
157 /* Return platform context to user */
158 return platform_ctx;
159 }
160
161 /* Platform finalization function */
162 void my_platform_fini(struct my_platform_ctx * const platform_ctx)
163 {
164 /* Close current packet if needed */
165 if (barectf_packet_is_open(&platform_ctx->ctx) &&
166 !barectf_packet_is_empty(&platform_ctx->ctx)) {
167 close_packet(platform_ctx);
168 }
169
170 /* Close data stream file */
171 fclose(platform_ctx->fh);
172
173 /* Deallocate packet buffer */
174 free(barectf_packet_buf(&platform_ctx->ctx));
175
176 /* Deallocate platform context */
177 free(platform_ctx);
178 }
179
180 /* barectf context pointer access function */
181 struct barectf_my_stream_ctx *my_platform_get_barectf_ctx(
182 struct my_platform_ctx * const platform_ctx)
183 {
184 return &platform_ctx->ctx;
185 }
186 ----
187
188 == Components
189
190 In this example, you can find all the required components of a barectf
191 platform:
192
193 xref:api.adoc#cbs[Platform callback functions]::
194 xref:api.adoc#cb-clk-src[Clock source]:::
195 +
196 [source,c]
197 ----
198 static uint64_t my_clock_get_value(void * const data)
199 {
200 struct timespec ts;
201
202 clock_gettime(CLOCK_REALTIME, &ts);
203 return ts.tv_sec * 1000000000ULL + ts.tv_nsec;
204 }
205 ----
206
207 xref:api.adoc#cb-open[Packet opening]:::
208 +
209 [source,c]
210 ----
211 static void open_packet(void * const data)
212 {
213 struct my_platform_ctx * const platform_ctx = data;
214
215 barectf_my_stream_open_packet(&platform_ctx->ctx);
216 }
217 ----
218
219 xref:api.adoc#cb-close[Packet closing]:::
220 +
221 [source,c]
222 ----
223 static void close_packet(void * const data)
224 {
225 struct my_platform_ctx * const platform_ctx = data;
226
227 barectf_my_stream_close_packet(&platform_ctx->ctx);
228 write_packet(platform_ctx);
229 }
230 ----
231
232 xref:api.adoc#cb-is-back-end-full[Is the back end full?]:::
233 +
234 [source,c]
235 ----
236 static int is_backend_full(void * const data)
237 {
238 return 0;
239 }
240 ----
241 +
242 This one always returns 0 as we assume that we can always append a
243 packet to the data stream file.
244
245 Platform initialization function::
246 +
247 [source,c]
248 ----
249 struct my_platform_ctx *my_platform_init(const unsigned int buf_size,
250 const char * const data_stream_file_path)
251 {
252 /* ... */
253 }
254 ----
255
256 Platform finalization function::
257 +
258 [source,c]
259 ----
260 void my_platform_fini(struct my_platform_ctx * const platform_ctx)
261 {
262 if (barectf_packet_is_open(&platform_ctx->ctx) &&
263 !barectf_packet_is_empty(&platform_ctx->ctx)) {
264 close_packet(platform_ctx);
265 }
266
267 /* ... */
268 }
269 ----
270
271 barectf context pointer access function::
272 +
273 [source,c]
274 ----
275 struct barectf_my_stream_ctx *my_platform_get_barectf_ctx(
276 struct my_platform_ctx * const platform_ctx)
277 {
278 return &platform_ctx->ctx;
279 }
280 ----
This page took 0.04193 seconds and 4 git commands to generate.