856715cb90857b6d1d7d2e579b7ee8fce8104d85
4 * CTF IR Reference Count test
6 * Copyright 2016 - Jérémie Galarneau <jeremie.galarneau@efficios.com>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; under version 2 of the License.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 #include <babeltrace/ctf-ir/trace.h>
24 #include <babeltrace/ctf-ir/stream-class.h>
25 #include <babeltrace/ctf-ir/stream.h>
26 #include <babeltrace/ctf-ir/event.h>
27 #include <babeltrace/object-internal.h>
31 struct bt_ctf_trace
*tc
;
32 struct bt_ctf_stream_class
*sc
;
33 struct bt_ctf_event_class
*ec
;
37 * Returns a structure containing the following fields:
38 * - uint8_t payload_8;
39 * - uint16_t payload_16;
40 * - uint32_t payload_32;
42 static struct bt_ctf_field_type
*create_integer_struct(void)
45 struct bt_ctf_field_type
*structure
= NULL
;
46 struct bt_ctf_field_type
*ui8
= NULL
, *ui16
= NULL
, *ui32
= NULL
;
48 structure
= bt_ctf_field_type_structure_create();
53 ui8
= bt_ctf_field_type_integer_create(8);
55 diag("Failed to create uint8_t type");
58 ret
= bt_ctf_field_type_structure_add_field(structure
, ui8
,
61 diag("Failed to add uint8_t to structure");
64 ui16
= bt_ctf_field_type_integer_create(16);
66 diag("Failed to create uint16_t type");
69 ret
= bt_ctf_field_type_structure_add_field(structure
, ui16
,
72 diag("Failed to add uint16_t to structure");
75 ui32
= bt_ctf_field_type_integer_create(32);
77 diag("Failed to create uint32_t type");
80 ret
= bt_ctf_field_type_structure_add_field(structure
, ui32
,
83 diag("Failed to add uint32_t to structure");
97 * A simple event has the following payload:
98 * - uint8_t payload_8;
99 * - uint16_t payload_16;
100 * - uint32_t payload_32;
102 static struct bt_ctf_event_class
*create_simple_event(const char *name
)
105 struct bt_ctf_event_class
*event
= NULL
;
106 struct bt_ctf_field_type
*payload
= NULL
;
109 event
= bt_ctf_event_class_create(name
);
111 diag("Failed to create simple event");
115 payload
= create_integer_struct();
117 diag("Failed to initialize integer structure");
121 ret
= bt_ctf_event_class_set_payload_type(event
, payload
);
123 diag("Failed to set simple event payload");
135 * A complex event has the following payload:
136 * - uint8_t payload_8;
137 * - uint16_t payload_16;
138 * - uint32_t payload_32;
139 * - struct payload_struct:
140 * - uint8_t payload_8;
141 * - uint16_t payload_16;
142 * - uint32_t payload_32;
144 static struct bt_ctf_event_class
*create_complex_event(const char *name
)
147 struct bt_ctf_event_class
*event
= NULL
;
148 struct bt_ctf_field_type
*inner
= NULL
, *outer
= NULL
;
151 event
= bt_ctf_event_class_create(name
);
153 diag("Failed to create complex event");
157 outer
= create_integer_struct();
159 diag("Failed to initialize integer structure");
163 inner
= create_integer_struct();
165 diag("Failed to initialize integer structure");
169 ret
= bt_ctf_field_type_structure_add_field(outer
, inner
,
172 diag("Failed to add inner structure to outer structure");
176 ret
= bt_ctf_event_class_set_payload_type(event
, outer
);
178 diag("Failed to set complex event payload");
190 static struct bt_ctf_stream_class
*create_sc1(void)
193 struct bt_ctf_event_class
*ec1
= NULL
, *ec2
= NULL
;
194 struct bt_ctf_stream_class
*sc1
= NULL
, *ret_stream
= NULL
;
196 sc1
= bt_ctf_stream_class_create("sc1");
198 diag("Failed to create Stream Class");
202 ec1
= create_complex_event("ec1");
204 diag("Failed to create complex event EC1");
207 ret
= bt_ctf_stream_class_add_event_class(sc1
, ec1
);
209 diag("Failed to add EC1 to SC1");
213 ec2
= create_simple_event("ec2");
215 diag("Failed to create simple event EC2");
218 ret
= bt_ctf_stream_class_add_event_class(sc1
, ec2
);
220 diag("Failed to add EC1 to SC1");
224 ret_stream
= bt_ctf_event_class_get_stream_class(ec1
);
225 ok(ret_stream
== sc1
, "Get parent stream SC1 from EC1");
228 ret_stream
= bt_ctf_event_class_get_stream_class(ec2
);
229 ok(ret_stream
== sc1
, "Get parent stream SC1 from EC2");
240 static struct bt_ctf_stream_class
*create_sc2(void)
243 struct bt_ctf_event_class
*ec3
= NULL
;
244 struct bt_ctf_stream_class
*sc2
= NULL
, *ret_stream
= NULL
;
246 sc2
= bt_ctf_stream_class_create("sc2");
248 diag("Failed to create Stream Class");
252 ec3
= create_simple_event("ec3");
254 diag("Failed to create simple event EC3");
257 ret
= bt_ctf_stream_class_add_event_class(sc2
, ec3
);
259 diag("Failed to add EC3 to SC2");
263 ret_stream
= bt_ctf_event_class_get_stream_class(ec3
);
264 ok(ret_stream
== sc2
, "Get parent stream SC2 from EC3");
274 static struct bt_ctf_trace
*create_tc1(void)
277 struct bt_ctf_trace
*tc1
= NULL
;
278 struct bt_ctf_stream_class
*sc1
= NULL
, *sc2
= NULL
;
280 tc1
= bt_ctf_trace_create();
282 diag("bt_ctf_trace_create returned NULL");
287 ok(sc1
, "Create SC1");
291 ret
= bt_ctf_trace_add_stream_class(tc1
, sc1
);
292 ok(!ret
, "Add SC1 to TC1");
298 ok(sc2
, "Create SC2");
302 ret
= bt_ctf_trace_add_stream_class(tc1
, sc2
);
303 ok(!ret
, "Add SC2 to TC1");
316 static void init_weak_refs(struct bt_ctf_trace
*tc
,
317 struct bt_ctf_trace
**tc1
,
318 struct bt_ctf_stream_class
**sc1
,
319 struct bt_ctf_stream_class
**sc2
,
320 struct bt_ctf_event_class
**ec1
,
321 struct bt_ctf_event_class
**ec2
,
322 struct bt_ctf_event_class
**ec3
)
325 *sc1
= bt_ctf_trace_get_stream_class(tc
, 0);
326 *sc2
= bt_ctf_trace_get_stream_class(tc
, 1);
327 *ec1
= bt_ctf_stream_class_get_event_class(*sc1
, 0);
328 *ec2
= bt_ctf_stream_class_get_event_class(*sc1
, 1);
329 *ec3
= bt_ctf_stream_class_get_event_class(*sc2
, 0);
338 * The objective of this test is to implement and expand upon the scenario
339 * described in the reference counting documentation and ensure that any node of
340 * the Trace, Stream Class, Event Class, Stream and Event hiearchy keeps all
341 * other "alive" and reachable.
343 * External tools (e.g. valgrind) should be used to confirm that this
344 * known-good test does not leak memory.
346 int main(int argc
, char **argv
)
349 * Weak pointers to CTF-IR objects are to be used very carefully.
350 * This is NOT a good practice and is strongly discouraged; this
351 * is only done to facilitate the validation of expected reference
352 * counts without affecting them by taking "real" references to the
355 struct bt_ctf_trace
*tc1
= NULL
, *weak_tc1
= NULL
;
356 struct bt_ctf_stream_class
*weak_sc1
= NULL
, *weak_sc2
= NULL
;
357 struct bt_ctf_event_class
*weak_ec1
= NULL
, *weak_ec2
= NULL
,
359 struct user user_a
= { 0 }, user_b
= { 0 }, user_c
= { 0 };
361 /* The only reference which exists at this point is on TC1. */
363 ok(tc1
, "Initialize trace");
368 init_weak_refs(tc1
, &weak_tc1
, &weak_sc1
, &weak_sc2
, &weak_ec1
,
369 &weak_ec2
, &weak_ec3
);
372 ok(bt_object_get_ref_count(weak_sc1
) == 0,
373 "Initial SC1 reference count is 0");
374 ok(bt_object_get_ref_count(weak_sc2
) == 0,
375 "Initial SC2 reference count is 0");
376 ok(bt_object_get_ref_count(weak_ec1
) == 0,
377 "Initial EC1 reference count is 0");
378 ok(bt_object_get_ref_count(weak_ec2
) == 0,
379 "Initial EC2 reference count is 0");
380 ok(bt_object_get_ref_count(weak_ec3
) == 0,
381 "Initial EC3 reference count is 0");
383 /* User A has ownership of the trace. */
384 BT_MOVE(user_a
.tc
, tc1
);
385 ok(bt_object_get_ref_count(user_a
.tc
) == 1,
386 "TC1 reference count is 1");
388 /* User A acquires a reference to SC2 from TC1. */
389 user_a
.sc
= bt_ctf_trace_get_stream_class(user_a
.tc
, 1);
390 ok(user_a
.sc
, "User A acquires SC2 from TC1");
391 ok(bt_object_get_ref_count(weak_tc1
) == 2,
392 "TC1 reference count is 2");
393 ok(bt_object_get_ref_count(weak_sc2
) == 1,
394 "SC2 reference count is 1");
396 /* User A acquires a reference to EC3 from SC2. */
397 user_a
.ec
= bt_ctf_stream_class_get_event_class(user_a
.sc
, 0);
398 ok(user_a
.ec
, "User A acquires EC3 from SC2");
399 ok(bt_object_get_ref_count(weak_tc1
) == 2,
400 "TC1 reference count is 2");
401 ok(bt_object_get_ref_count(weak_sc2
) == 2,
402 "SC2 reference count is 2");
403 ok(bt_object_get_ref_count(weak_ec3
) == 1,
404 "EC3 reference count is 1");
406 /* User A releases its reference to SC2. */
407 diag("User A releases SC2");
410 * We keep the pointer to SC2 around to validate its reference
413 ok(bt_object_get_ref_count(weak_tc1
) == 2,
414 "TC1 reference count is 2");
415 ok(bt_object_get_ref_count(weak_sc2
) == 1,
416 "SC2 reference count is 1");
417 ok(bt_object_get_ref_count(weak_ec3
) == 1,
418 "EC3 reference count is 1");
420 /* User A releases its reference to TC1. */
421 diag("User A releases TC1");
424 * We keep the pointer to TC1 around to validate its reference
427 ok(bt_object_get_ref_count(weak_tc1
) == 1,
428 "TC1 reference count is 1");
429 ok(bt_object_get_ref_count(weak_sc2
) == 1,
430 "SC2 reference count is 1");
431 ok(bt_object_get_ref_count(weak_ec3
) == 1,
432 "EC3 reference count is 1");
434 /* User B acquires a reference to SC1. */
435 diag("User B acquires a reference to SC1");
436 user_b
.sc
= bt_get(weak_sc1
);
437 ok(bt_object_get_ref_count(weak_tc1
) == 2,
438 "TC1 reference count is 2");
439 ok(bt_object_get_ref_count(weak_sc1
) == 1,
440 "SC1 reference count is 1");
442 /* User C acquires a reference to EC1. */
443 diag("User C acquires a reference to EC1");
444 user_c
.ec
= bt_ctf_stream_class_get_event_class(user_b
.sc
, 0);
445 ok(bt_object_get_ref_count(weak_ec1
) == 1,
446 "EC1 reference count is 1");
447 ok(bt_object_get_ref_count(weak_sc1
) == 2,
448 "SC1 reference count is 2");
450 /* User A releases its reference on EC3. */
451 diag("User A releases its reference on EC3");
453 ok(bt_object_get_ref_count(weak_ec3
) == 0,
454 "EC3 reference count is 1");
455 ok(bt_object_get_ref_count(weak_sc2
) == 0,
456 "SC2 reference count is 0");
457 ok(bt_object_get_ref_count(weak_tc1
) == 1,
458 "TC1 reference count is 1");
460 /* User B releases its reference on SC1. */
461 diag("User B releases its reference on SC1");
463 ok(bt_object_get_ref_count(weak_sc1
) == 1,
464 "SC1 reference count is 1");
467 * User C is the sole owner of an object and is keeping the whole
468 * trace hierarchy "alive" by holding a reference to EC1.
470 ok(bt_object_get_ref_count(weak_tc1
) == 1,
471 "TC1 reference count is 1");
472 ok(bt_object_get_ref_count(weak_sc1
) == 1,
473 "SC1 reference count is 1");
474 ok(bt_object_get_ref_count(weak_sc2
) == 0,
475 "SC2 reference count is 0");
476 ok(bt_object_get_ref_count(weak_ec1
) == 1,
477 "EC1 reference count is 1");
478 ok(bt_object_get_ref_count(weak_ec2
) == 0,
479 "EC2 reference count is 0");
480 ok(bt_object_get_ref_count(weak_ec3
) == 0,
481 "EC3 reference count is 0");
483 /* Reclaim last reference held by User C. */
486 return exit_status();
This page took 0.062094 seconds and 4 git commands to generate.