]>
Commit | Line | Data |
---|---|---|
b2441318 | 1 | // SPDX-License-Identifier: GPL-2.0 |
fabf0123 JO |
2 | #include "tests.h" |
3 | #include "machine.h" | |
4 | #include "thread.h" | |
84f5d36f | 5 | #include "debug.h" |
fabf0123 | 6 | |
81f17c90 | 7 | int test__thread_mg_share(struct test *test __maybe_unused, int subtest __maybe_unused) |
fabf0123 JO |
8 | { |
9 | struct machines machines; | |
10 | struct machine *machine; | |
11 | ||
12 | /* thread group */ | |
13 | struct thread *leader; | |
14 | struct thread *t1, *t2, *t3; | |
79b6bb73 | 15 | struct maps *mg; |
fabf0123 JO |
16 | |
17 | /* other process */ | |
18 | struct thread *other, *other_leader; | |
79b6bb73 | 19 | struct maps *other_mg; |
fabf0123 JO |
20 | |
21 | /* | |
22 | * This test create 2 processes abstractions (struct thread) | |
23 | * with several threads and checks they properly share and | |
79b6bb73 | 24 | * maintain maps info (struct maps). |
fabf0123 JO |
25 | * |
26 | * thread group (pid: 0, tids: 0, 1, 2, 3) | |
27 | * other group (pid: 4, tids: 4, 5) | |
28 | */ | |
29 | ||
30 | machines__init(&machines); | |
31 | machine = &machines.host; | |
32 | ||
33 | /* create process with 4 threads */ | |
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 | /* and create 1 separated process, without thread leader */ | |
40 | other = machine__findnew_thread(machine, 4, 5); | |
41 | ||
42 | TEST_ASSERT_VAL("failed to create threads", | |
43 | leader && t1 && t2 && t3 && other); | |
44 | ||
fe87797d | 45 | mg = leader->maps; |
ead05e8f | 46 | TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(&mg->refcnt), 4); |
fabf0123 JO |
47 | |
48 | /* test the map groups pointer is shared */ | |
fe87797d ACM |
49 | TEST_ASSERT_VAL("map groups don't match", mg == t1->maps); |
50 | TEST_ASSERT_VAL("map groups don't match", mg == t2->maps); | |
51 | TEST_ASSERT_VAL("map groups don't match", mg == t3->maps); | |
fabf0123 JO |
52 | |
53 | /* | |
54 | * Verify the other leader was created by previous call. | |
55 | * It should have shared map groups 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 | ||
8b00f469 ACM |
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 | ||
fe87797d | 73 | other_mg = other->maps; |
ead05e8f | 74 | TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(&other_mg->refcnt), 2); |
fabf0123 | 75 | |
fe87797d | 76 | TEST_ASSERT_VAL("map groups don't match", other_mg == other_leader->maps); |
fabf0123 JO |
77 | |
78 | /* release thread group */ | |
b91fc39f | 79 | thread__put(leader); |
ead05e8f | 80 | TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(&mg->refcnt), 3); |
fabf0123 | 81 | |
b91fc39f | 82 | thread__put(t1); |
ead05e8f | 83 | TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(&mg->refcnt), 2); |
fabf0123 | 84 | |
b91fc39f | 85 | thread__put(t2); |
ead05e8f | 86 | TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(&mg->refcnt), 1); |
fabf0123 | 87 | |
b91fc39f | 88 | thread__put(t3); |
fabf0123 JO |
89 | |
90 | /* release other group */ | |
b91fc39f | 91 | thread__put(other_leader); |
ead05e8f | 92 | TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(&other_mg->refcnt), 1); |
fabf0123 | 93 | |
b91fc39f | 94 | thread__put(other); |
fabf0123 | 95 | |
fabf0123 JO |
96 | machines__exit(&machines); |
97 | return 0; | |
98 | } |