Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 #include "tests.h"
0003 #include "machine.h"
0004 #include "thread.h"
0005 #include "debug.h"
0006 
0007 static int test__thread_maps_share(struct test_suite *test __maybe_unused, int subtest __maybe_unused)
0008 {
0009     struct machines machines;
0010     struct machine *machine;
0011 
0012     /* thread group */
0013     struct thread *leader;
0014     struct thread *t1, *t2, *t3;
0015     struct maps *maps;
0016 
0017     /* other process */
0018     struct thread *other, *other_leader;
0019     struct maps *other_maps;
0020 
0021     /*
0022      * This test create 2 processes abstractions (struct thread)
0023      * with several threads and checks they properly share and
0024      * maintain maps info (struct maps).
0025      *
0026      * thread group (pid: 0, tids: 0, 1, 2, 3)
0027      * other  group (pid: 4, tids: 4, 5)
0028     */
0029 
0030     machines__init(&machines);
0031     machine = &machines.host;
0032 
0033     /* create process with 4 threads */
0034     leader = machine__findnew_thread(machine, 0, 0);
0035     t1     = machine__findnew_thread(machine, 0, 1);
0036     t2     = machine__findnew_thread(machine, 0, 2);
0037     t3     = machine__findnew_thread(machine, 0, 3);
0038 
0039     /* and create 1 separated process, without thread leader */
0040     other  = machine__findnew_thread(machine, 4, 5);
0041 
0042     TEST_ASSERT_VAL("failed to create threads",
0043             leader && t1 && t2 && t3 && other);
0044 
0045     maps = leader->maps;
0046     TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(&maps->refcnt), 4);
0047 
0048     /* test the maps pointer is shared */
0049     TEST_ASSERT_VAL("maps don't match", maps == t1->maps);
0050     TEST_ASSERT_VAL("maps don't match", maps == t2->maps);
0051     TEST_ASSERT_VAL("maps don't match", maps == t3->maps);
0052 
0053     /*
0054      * Verify the other leader was created by previous call.
0055      * It should have shared maps with no change in
0056      * refcnt.
0057      */
0058     other_leader = machine__find_thread(machine, 4, 4);
0059     TEST_ASSERT_VAL("failed to find other leader", other_leader);
0060 
0061     /*
0062      * Ok, now that all the rbtree related operations were done,
0063      * lets remove all of them from there so that we can do the
0064      * refcounting tests.
0065      */
0066     machine__remove_thread(machine, leader);
0067     machine__remove_thread(machine, t1);
0068     machine__remove_thread(machine, t2);
0069     machine__remove_thread(machine, t3);
0070     machine__remove_thread(machine, other);
0071     machine__remove_thread(machine, other_leader);
0072 
0073     other_maps = other->maps;
0074     TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(&other_maps->refcnt), 2);
0075 
0076     TEST_ASSERT_VAL("maps don't match", other_maps == other_leader->maps);
0077 
0078     /* release thread group */
0079     thread__put(leader);
0080     TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(&maps->refcnt), 3);
0081 
0082     thread__put(t1);
0083     TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(&maps->refcnt), 2);
0084 
0085     thread__put(t2);
0086     TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(&maps->refcnt), 1);
0087 
0088     thread__put(t3);
0089 
0090     /* release other group  */
0091     thread__put(other_leader);
0092     TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(&other_maps->refcnt), 1);
0093 
0094     thread__put(other);
0095 
0096     machines__exit(&machines);
0097     return 0;
0098 }
0099 
0100 DEFINE_SUITE("Share thread maps", thread_maps_share);