thread-maps-share.c 2.8 KB
Newer Older
1
// SPDX-License-Identifier: GPL-2.0
2 3 4
#include "tests.h"
#include "machine.h"
#include "thread.h"
5
#include "debug.h"
6

7
int test__thread_maps_share(struct test *test __maybe_unused, int subtest __maybe_unused)
8 9 10 11 12 13 14
{
	struct machines machines;
	struct machine *machine;

	/* thread group */
	struct thread *leader;
	struct thread *t1, *t2, *t3;
15
	struct maps *maps;
16 17 18

	/* other process */
	struct thread *other, *other_leader;
19
	struct maps *other_maps;
20 21 22 23

	/*
	 * This test create 2 processes abstractions (struct thread)
	 * with several threads and checks they properly share and
24
	 * maintain maps info (struct maps).
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
	 *
	 * 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);

45 46
	maps = leader->maps;
	TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(&maps->refcnt), 4);
47

48 49 50 51
	/* 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);
52 53 54

	/*
	 * Verify the other leader was created by previous call.
55
	 * It should have shared maps with no change in
56 57 58 59 60
	 * refcnt.
	 */
	other_leader = machine__find_thread(machine, 4, 4);
	TEST_ASSERT_VAL("failed to find other leader", other_leader);

61 62 63 64 65 66 67 68 69 70 71 72
	/*
	 * 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);

73 74
	other_maps = other->maps;
	TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(&other_maps->refcnt), 2);
75

76
	TEST_ASSERT_VAL("maps don't match", other_maps == other_leader->maps);
77 78

	/* release thread group */
79
	thread__put(leader);
80
	TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(&maps->refcnt), 3);
81

82
	thread__put(t1);
83
	TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(&maps->refcnt), 2);
84

85
	thread__put(t2);
86
	TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(&maps->refcnt), 1);
87

88
	thread__put(t3);
89 90

	/* release other group  */
91
	thread__put(other_leader);
92
	TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(&other_maps->refcnt), 1);
93

94
	thread__put(other);
95 96 97 98

	machines__exit(&machines);
	return 0;
}