eecaad880ad0753fe67003ae8e150ec65e28e3cc
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/ctf-ir/event-class.h>
28 #include <babeltrace/object-internal.h>
34 struct bt_ctf_trace
*tc
;
35 struct bt_ctf_stream_class
*sc
;
36 struct bt_ctf_event_class
*ec
;
40 * Returns a structure containing the following fields:
41 * - uint8_t payload_8;
42 * - uint16_t payload_16;
43 * - uint32_t payload_32;
45 static struct bt_ctf_field_type
*create_integer_struct(void)
48 struct bt_ctf_field_type
*structure
= NULL
;
49 struct bt_ctf_field_type
*ui8
= NULL
, *ui16
= NULL
, *ui32
= NULL
;
51 structure
= bt_ctf_field_type_structure_create();
56 ui8
= bt_ctf_field_type_integer_create(8);
58 diag("Failed to create uint8_t type");
61 ret
= bt_ctf_field_type_structure_add_field(structure
, ui8
,
64 diag("Failed to add uint8_t to structure");
67 ui16
= bt_ctf_field_type_integer_create(16);
69 diag("Failed to create uint16_t type");
72 ret
= bt_ctf_field_type_structure_add_field(structure
, ui16
,
75 diag("Failed to add uint16_t to structure");
78 ui32
= bt_ctf_field_type_integer_create(32);
80 diag("Failed to create uint32_t type");
83 ret
= bt_ctf_field_type_structure_add_field(structure
, ui32
,
86 diag("Failed to add uint32_t to structure");
100 * A simple event has the following payload:
101 * - uint8_t payload_8;
102 * - uint16_t payload_16;
103 * - uint32_t payload_32;
105 static struct bt_ctf_event_class
*create_simple_event(const char *name
)
108 struct bt_ctf_event_class
*event
= NULL
;
109 struct bt_ctf_field_type
*payload
= NULL
;
112 event
= bt_ctf_event_class_create(name
);
114 diag("Failed to create simple event");
118 payload
= create_integer_struct();
120 diag("Failed to initialize integer structure");
124 ret
= bt_ctf_event_class_set_payload_type(event
, payload
);
126 diag("Failed to set simple event payload");
138 * A complex event has the following payload:
139 * - uint8_t payload_8;
140 * - uint16_t payload_16;
141 * - uint32_t payload_32;
142 * - struct payload_struct:
143 * - uint8_t payload_8;
144 * - uint16_t payload_16;
145 * - uint32_t payload_32;
147 static struct bt_ctf_event_class
*create_complex_event(const char *name
)
150 struct bt_ctf_event_class
*event
= NULL
;
151 struct bt_ctf_field_type
*inner
= NULL
, *outer
= NULL
;
154 event
= bt_ctf_event_class_create(name
);
156 diag("Failed to create complex event");
160 outer
= create_integer_struct();
162 diag("Failed to initialize integer structure");
166 inner
= create_integer_struct();
168 diag("Failed to initialize integer structure");
172 ret
= bt_ctf_field_type_structure_add_field(outer
, inner
,
175 diag("Failed to add inner structure to outer structure");
179 ret
= bt_ctf_event_class_set_payload_type(event
, outer
);
181 diag("Failed to set complex event payload");
193 static struct bt_ctf_stream_class
*create_sc1(void)
196 struct bt_ctf_event_class
*ec1
= NULL
, *ec2
= NULL
;
197 struct bt_ctf_stream_class
*sc1
= NULL
, *ret_stream
= NULL
;
199 sc1
= bt_ctf_stream_class_create("sc1");
201 diag("Failed to create Stream Class");
205 ec1
= create_complex_event("ec1");
207 diag("Failed to create complex event EC1");
210 ret
= bt_ctf_stream_class_add_event_class(sc1
, ec1
);
212 diag("Failed to add EC1 to SC1");
216 ec2
= create_simple_event("ec2");
218 diag("Failed to create simple event EC2");
221 ret
= bt_ctf_stream_class_add_event_class(sc1
, ec2
);
223 diag("Failed to add EC1 to SC1");
227 ret_stream
= bt_ctf_event_class_get_stream_class(ec1
);
228 ok(ret_stream
== sc1
, "Get parent stream SC1 from EC1");
231 ret_stream
= bt_ctf_event_class_get_stream_class(ec2
);
232 ok(ret_stream
== sc1
, "Get parent stream SC1 from EC2");
243 static struct bt_ctf_stream_class
*create_sc2(void)
246 struct bt_ctf_event_class
*ec3
= NULL
;
247 struct bt_ctf_stream_class
*sc2
= NULL
, *ret_stream
= NULL
;
249 sc2
= bt_ctf_stream_class_create("sc2");
251 diag("Failed to create Stream Class");
255 ec3
= create_simple_event("ec3");
257 diag("Failed to create simple event EC3");
260 ret
= bt_ctf_stream_class_add_event_class(sc2
, ec3
);
262 diag("Failed to add EC3 to SC2");
266 ret_stream
= bt_ctf_event_class_get_stream_class(ec3
);
267 ok(ret_stream
== sc2
, "Get parent stream SC2 from EC3");
277 static struct bt_ctf_trace
*create_tc1(void)
280 struct bt_ctf_trace
*tc1
= NULL
;
281 struct bt_ctf_stream_class
*sc1
= NULL
, *sc2
= NULL
;
283 tc1
= bt_ctf_trace_create();
285 diag("bt_ctf_trace_create returned NULL");
290 ok(sc1
, "Create SC1");
294 ret
= bt_ctf_trace_add_stream_class(tc1
, sc1
);
295 ok(!ret
, "Add SC1 to TC1");
301 ok(sc2
, "Create SC2");
305 ret
= bt_ctf_trace_add_stream_class(tc1
, sc2
);
306 ok(!ret
, "Add SC2 to TC1");
319 static void init_weak_refs(struct bt_ctf_trace
*tc
,
320 struct bt_ctf_trace
**tc1
,
321 struct bt_ctf_stream_class
**sc1
,
322 struct bt_ctf_stream_class
**sc2
,
323 struct bt_ctf_event_class
**ec1
,
324 struct bt_ctf_event_class
**ec2
,
325 struct bt_ctf_event_class
**ec3
)
328 *sc1
= bt_ctf_trace_get_stream_class(tc
, 0);
329 *sc2
= bt_ctf_trace_get_stream_class(tc
, 1);
330 *ec1
= bt_ctf_stream_class_get_event_class(*sc1
, 0);
331 *ec2
= bt_ctf_stream_class_get_event_class(*sc1
, 1);
332 *ec3
= bt_ctf_stream_class_get_event_class(*sc2
, 0);
341 * The objective of this test is to implement and expand upon the scenario
342 * described in the reference counting documentation and ensure that any node of
343 * the Trace, Stream Class, Event Class, Stream and Event hiearchy keeps all
344 * other "alive" and reachable.
346 * External tools (e.g. valgrind) should be used to confirm that this
347 * known-good test does not leak memory.
349 int main(int argc
, char **argv
)
352 * Weak pointers to CTF-IR objects are to be used very carefully.
353 * This is NOT a good practice and is strongly discouraged; this
354 * is only done to facilitate the validation of expected reference
355 * counts without affecting them by taking "real" references to the
358 struct bt_ctf_trace
*tc1
= NULL
, *weak_tc1
= NULL
;
359 struct bt_ctf_stream_class
*weak_sc1
= NULL
, *weak_sc2
= NULL
;
360 struct bt_ctf_event_class
*weak_ec1
= NULL
, *weak_ec2
= NULL
,
362 struct user user_a
= { 0 }, user_b
= { 0 }, user_c
= { 0 };
364 /* Initialize tap harness before any tests */
365 plan_tests(NR_TESTS
);
367 /* The only reference which exists at this point is on TC1. */
369 ok(tc1
, "Initialize trace");
374 init_weak_refs(tc1
, &weak_tc1
, &weak_sc1
, &weak_sc2
, &weak_ec1
,
375 &weak_ec2
, &weak_ec3
);
377 ok(bt_object_get_ref_count(weak_sc1
) == 0,
378 "Initial SC1 reference count is 0");
379 ok(bt_object_get_ref_count(weak_sc2
) == 0,
380 "Initial SC2 reference count is 0");
381 ok(bt_object_get_ref_count(weak_ec1
) == 0,
382 "Initial EC1 reference count is 0");
383 ok(bt_object_get_ref_count(weak_ec2
) == 0,
384 "Initial EC2 reference count is 0");
385 ok(bt_object_get_ref_count(weak_ec3
) == 0,
386 "Initial EC3 reference count is 0");
388 /* User A has ownership of the trace. */
389 BT_MOVE(user_a
.tc
, tc1
);
390 ok(bt_object_get_ref_count(user_a
.tc
) == 1,
391 "TC1 reference count is 1");
393 /* User A acquires a reference to SC2 from TC1. */
394 user_a
.sc
= bt_ctf_trace_get_stream_class(user_a
.tc
, 1);
395 ok(user_a
.sc
, "User A acquires SC2 from TC1");
396 ok(bt_object_get_ref_count(weak_tc1
) == 2,
397 "TC1 reference count is 2");
398 ok(bt_object_get_ref_count(weak_sc2
) == 1,
399 "SC2 reference count is 1");
401 /* User A acquires a reference to EC3 from SC2. */
402 user_a
.ec
= bt_ctf_stream_class_get_event_class(user_a
.sc
, 0);
403 ok(user_a
.ec
, "User A acquires EC3 from SC2");
404 ok(bt_object_get_ref_count(weak_tc1
) == 2,
405 "TC1 reference count is 2");
406 ok(bt_object_get_ref_count(weak_sc2
) == 2,
407 "SC2 reference count is 2");
408 ok(bt_object_get_ref_count(weak_ec3
) == 1,
409 "EC3 reference count is 1");
411 /* User A releases its reference to SC2. */
412 diag("User A releases SC2");
415 * We keep the pointer to SC2 around to validate its reference
418 ok(bt_object_get_ref_count(weak_tc1
) == 2,
419 "TC1 reference count is 2");
420 ok(bt_object_get_ref_count(weak_sc2
) == 1,
421 "SC2 reference count is 1");
422 ok(bt_object_get_ref_count(weak_ec3
) == 1,
423 "EC3 reference count is 1");
425 /* User A releases its reference to TC1. */
426 diag("User A releases TC1");
429 * We keep the pointer to TC1 around to validate its reference
432 ok(bt_object_get_ref_count(weak_tc1
) == 1,
433 "TC1 reference count is 1");
434 ok(bt_object_get_ref_count(weak_sc2
) == 1,
435 "SC2 reference count is 1");
436 ok(bt_object_get_ref_count(weak_ec3
) == 1,
437 "EC3 reference count is 1");
439 /* User B acquires a reference to SC1. */
440 diag("User B acquires a reference to SC1");
441 user_b
.sc
= bt_get(weak_sc1
);
442 ok(bt_object_get_ref_count(weak_tc1
) == 2,
443 "TC1 reference count is 2");
444 ok(bt_object_get_ref_count(weak_sc1
) == 1,
445 "SC1 reference count is 1");
447 /* User C acquires a reference to EC1. */
448 diag("User C acquires a reference to EC1");
449 user_c
.ec
= bt_ctf_stream_class_get_event_class(user_b
.sc
, 0);
450 ok(bt_object_get_ref_count(weak_ec1
) == 1,
451 "EC1 reference count is 1");
452 ok(bt_object_get_ref_count(weak_sc1
) == 2,
453 "SC1 reference count is 2");
455 /* User A releases its reference on EC3. */
456 diag("User A releases its reference on EC3");
458 ok(bt_object_get_ref_count(weak_ec3
) == 0,
459 "EC3 reference count is 1");
460 ok(bt_object_get_ref_count(weak_sc2
) == 0,
461 "SC2 reference count is 0");
462 ok(bt_object_get_ref_count(weak_tc1
) == 1,
463 "TC1 reference count is 1");
465 /* User B releases its reference on SC1. */
466 diag("User B releases its reference on SC1");
468 ok(bt_object_get_ref_count(weak_sc1
) == 1,
469 "SC1 reference count is 1");
472 * User C is the sole owner of an object and is keeping the whole
473 * trace hierarchy "alive" by holding a reference to EC1.
475 ok(bt_object_get_ref_count(weak_tc1
) == 1,
476 "TC1 reference count is 1");
477 ok(bt_object_get_ref_count(weak_sc1
) == 1,
478 "SC1 reference count is 1");
479 ok(bt_object_get_ref_count(weak_sc2
) == 0,
480 "SC2 reference count is 0");
481 ok(bt_object_get_ref_count(weak_ec1
) == 1,
482 "EC1 reference count is 1");
483 ok(bt_object_get_ref_count(weak_ec2
) == 0,
484 "EC2 reference count is 0");
485 ok(bt_object_get_ref_count(weak_ec3
) == 0,
486 "EC3 reference count is 0");
488 /* Reclaim last reference held by User C. */
491 return exit_status();
This page took 0.040851 seconds and 5 git commands to generate.