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