| 1 | |
| 2 | #include "tests.h"
|
| 3 | #include "machine.h"
|
| 4 | #include "thread.h"
|
| 5 | #include "debug.h"
|
| 6 |
|
| 7 | static int test__thread_maps_share(struct test_suite *test __maybe_unused, int subtest __maybe_unused)
|
| 8 | {
|
| 9 | struct machines machines;
|
| 10 | struct machine *machine;
|
| 11 |
|
| 12 |
|
| 13 | struct thread *leader;
|
| 14 | struct thread *t1, *t2, *t3;
|
| 15 | struct maps *maps;
|
| 16 |
|
| 17 |
|
| 18 | struct thread *other, *other_leader;
|
| 19 | struct maps *other_maps;
|
| 20 |
|
| 21 | |
| 22 | * This test create 2 processes abstractions (struct thread)
|
| 23 | * with several threads and checks they properly share and
|
| 24 | * maintain maps info (struct maps).
|
| 25 | *
|
| 26 | * thread group (pid: 0, tids: 0, 1, 2, 3)
|
| 27 | * other group (pid: 4, tids: 4, 5)
|
| 28 |
|
| 29 |
|
| 30 | TEST_ASSERT_VAL("failed to init machines", machines__init(&machines) == 0);
|
| 31 | machine = &machines.host;
|
| 32 |
|
| 33 |
|
| 34 | leader = machine__findnew_thread(machine, 0, 0);
|
| 35 | t1 = machine__findnew_thread(machine, 0, 1);
|
| 36 | t2 = machine__findnew_thread(machine, 0, 2);
|
| 37 | t3 = machine__findnew_thread(machine, 0, 3);
|
| 38 |
|
| 39 |
|
| 40 | other = machine__findnew_thread(machine, 4, 5);
|
| 41 |
|
| 42 | TEST_ASSERT_VAL("failed to create threads",
|
| 43 | leader && t1 && t2 && t3 && other);
|
| 44 |
|
| 45 | maps = thread__maps(leader);
|
| 46 | TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(maps__refcnt(maps)), 4);
|
| 47 |
|
| 48 |
|
| 49 | TEST_ASSERT_VAL("maps don't match", maps__equal(maps, thread__maps(t1)));
|
| 50 | TEST_ASSERT_VAL("maps don't match", maps__equal(maps, thread__maps(t2)));
|
| 51 | TEST_ASSERT_VAL("maps don't match", maps__equal(maps, thread__maps(t3)));
|
| 52 |
|
| 53 | |
| 54 | * Verify the other leader was created by previous call.
|
| 55 | * It should have shared maps with no change in
|
| 56 | * refcnt.
|
| 57 |
|
| 58 | other_leader = machine__find_thread(machine, 4, 4);
|
| 59 | TEST_ASSERT_VAL("failed to find other leader", other_leader);
|
| 60 |
|
| 61 | |
| 62 | * Ok, now that all the rbtree related operations were done,
|
| 63 | * lets remove all of them from there so that we can do the
|
| 64 | * refcounting tests.
|
| 65 |
|
| 66 | machine__remove_thread(machine, leader);
|
| 67 | machine__remove_thread(machine, t1);
|
| 68 | machine__remove_thread(machine, t2);
|
| 69 | machine__remove_thread(machine, t3);
|
| 70 | machine__remove_thread(machine, other);
|
| 71 | machine__remove_thread(machine, other_leader);
|
| 72 |
|
| 73 | other_maps = thread__maps(other);
|
| 74 | TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(maps__refcnt(other_maps)), 2);
|
| 75 |
|
| 76 | TEST_ASSERT_VAL("maps don't match", maps__equal(other_maps, thread__maps(other_leader)));
|
| 77 |
|
| 78 |
|
| 79 | thread__put(t3);
|
| 80 | TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(maps__refcnt(maps)), 3);
|
| 81 |
|
| 82 | thread__put(t2);
|
| 83 | TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(maps__refcnt(maps)), 2);
|
| 84 |
|
| 85 | thread__put(t1);
|
| 86 | TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(maps__refcnt(maps)), 1);
|
| 87 |
|
| 88 | thread__put(leader);
|
| 89 |
|
| 90 |
|
| 91 | thread__put(other_leader);
|
| 92 | TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(maps__refcnt(other_maps)), 1);
|
| 93 |
|
| 94 | thread__put(other);
|
| 95 |
|
| 96 | machines__exit(&machines);
|
| 97 | return 0;
|
| 98 | }
|
| 99 |
|
| 100 | DEFINE_SUITE("Share thread maps", thread_maps_share);
|