18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci#include "tests.h" 38c2ecf20Sopenharmony_ci#include "machine.h" 48c2ecf20Sopenharmony_ci#include "thread.h" 58c2ecf20Sopenharmony_ci#include "debug.h" 68c2ecf20Sopenharmony_ci 78c2ecf20Sopenharmony_ciint test__thread_maps_share(struct test *test __maybe_unused, int subtest __maybe_unused) 88c2ecf20Sopenharmony_ci{ 98c2ecf20Sopenharmony_ci struct machines machines; 108c2ecf20Sopenharmony_ci struct machine *machine; 118c2ecf20Sopenharmony_ci 128c2ecf20Sopenharmony_ci /* thread group */ 138c2ecf20Sopenharmony_ci struct thread *leader; 148c2ecf20Sopenharmony_ci struct thread *t1, *t2, *t3; 158c2ecf20Sopenharmony_ci struct maps *maps; 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_ci /* other process */ 188c2ecf20Sopenharmony_ci struct thread *other, *other_leader; 198c2ecf20Sopenharmony_ci struct maps *other_maps; 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_ci /* 228c2ecf20Sopenharmony_ci * This test create 2 processes abstractions (struct thread) 238c2ecf20Sopenharmony_ci * with several threads and checks they properly share and 248c2ecf20Sopenharmony_ci * maintain maps info (struct maps). 258c2ecf20Sopenharmony_ci * 268c2ecf20Sopenharmony_ci * thread group (pid: 0, tids: 0, 1, 2, 3) 278c2ecf20Sopenharmony_ci * other group (pid: 4, tids: 4, 5) 288c2ecf20Sopenharmony_ci */ 298c2ecf20Sopenharmony_ci 308c2ecf20Sopenharmony_ci machines__init(&machines); 318c2ecf20Sopenharmony_ci machine = &machines.host; 328c2ecf20Sopenharmony_ci 338c2ecf20Sopenharmony_ci /* create process with 4 threads */ 348c2ecf20Sopenharmony_ci leader = machine__findnew_thread(machine, 0, 0); 358c2ecf20Sopenharmony_ci t1 = machine__findnew_thread(machine, 0, 1); 368c2ecf20Sopenharmony_ci t2 = machine__findnew_thread(machine, 0, 2); 378c2ecf20Sopenharmony_ci t3 = machine__findnew_thread(machine, 0, 3); 388c2ecf20Sopenharmony_ci 398c2ecf20Sopenharmony_ci /* and create 1 separated process, without thread leader */ 408c2ecf20Sopenharmony_ci other = machine__findnew_thread(machine, 4, 5); 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_ci TEST_ASSERT_VAL("failed to create threads", 438c2ecf20Sopenharmony_ci leader && t1 && t2 && t3 && other); 448c2ecf20Sopenharmony_ci 458c2ecf20Sopenharmony_ci maps = leader->maps; 468c2ecf20Sopenharmony_ci TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(&maps->refcnt), 4); 478c2ecf20Sopenharmony_ci 488c2ecf20Sopenharmony_ci /* test the maps pointer is shared */ 498c2ecf20Sopenharmony_ci TEST_ASSERT_VAL("maps don't match", maps == t1->maps); 508c2ecf20Sopenharmony_ci TEST_ASSERT_VAL("maps don't match", maps == t2->maps); 518c2ecf20Sopenharmony_ci TEST_ASSERT_VAL("maps don't match", maps == t3->maps); 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_ci /* 548c2ecf20Sopenharmony_ci * Verify the other leader was created by previous call. 558c2ecf20Sopenharmony_ci * It should have shared maps with no change in 568c2ecf20Sopenharmony_ci * refcnt. 578c2ecf20Sopenharmony_ci */ 588c2ecf20Sopenharmony_ci other_leader = machine__find_thread(machine, 4, 4); 598c2ecf20Sopenharmony_ci TEST_ASSERT_VAL("failed to find other leader", other_leader); 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_ci /* 628c2ecf20Sopenharmony_ci * Ok, now that all the rbtree related operations were done, 638c2ecf20Sopenharmony_ci * lets remove all of them from there so that we can do the 648c2ecf20Sopenharmony_ci * refcounting tests. 658c2ecf20Sopenharmony_ci */ 668c2ecf20Sopenharmony_ci machine__remove_thread(machine, leader); 678c2ecf20Sopenharmony_ci machine__remove_thread(machine, t1); 688c2ecf20Sopenharmony_ci machine__remove_thread(machine, t2); 698c2ecf20Sopenharmony_ci machine__remove_thread(machine, t3); 708c2ecf20Sopenharmony_ci machine__remove_thread(machine, other); 718c2ecf20Sopenharmony_ci machine__remove_thread(machine, other_leader); 728c2ecf20Sopenharmony_ci 738c2ecf20Sopenharmony_ci other_maps = other->maps; 748c2ecf20Sopenharmony_ci TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(&other_maps->refcnt), 2); 758c2ecf20Sopenharmony_ci 768c2ecf20Sopenharmony_ci TEST_ASSERT_VAL("maps don't match", other_maps == other_leader->maps); 778c2ecf20Sopenharmony_ci 788c2ecf20Sopenharmony_ci /* release thread group */ 798c2ecf20Sopenharmony_ci thread__put(leader); 808c2ecf20Sopenharmony_ci TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(&maps->refcnt), 3); 818c2ecf20Sopenharmony_ci 828c2ecf20Sopenharmony_ci thread__put(t1); 838c2ecf20Sopenharmony_ci TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(&maps->refcnt), 2); 848c2ecf20Sopenharmony_ci 858c2ecf20Sopenharmony_ci thread__put(t2); 868c2ecf20Sopenharmony_ci TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(&maps->refcnt), 1); 878c2ecf20Sopenharmony_ci 888c2ecf20Sopenharmony_ci thread__put(t3); 898c2ecf20Sopenharmony_ci 908c2ecf20Sopenharmony_ci /* release other group */ 918c2ecf20Sopenharmony_ci thread__put(other_leader); 928c2ecf20Sopenharmony_ci TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(&other_maps->refcnt), 1); 938c2ecf20Sopenharmony_ci 948c2ecf20Sopenharmony_ci thread__put(other); 958c2ecf20Sopenharmony_ci 968c2ecf20Sopenharmony_ci machines__exit(&machines); 978c2ecf20Sopenharmony_ci return 0; 988c2ecf20Sopenharmony_ci} 99