xref: /aosp_15_r20/system/extras/memory_replay/tests/ThreadsTest.cpp (revision 288bf5226967eb3dac5cce6c939ccc2a7f2b4fe5)
1*288bf522SAndroid Build Coastguard Worker /*
2*288bf522SAndroid Build Coastguard Worker  * Copyright (C) 2015 The Android Open Source Project
3*288bf522SAndroid Build Coastguard Worker  *
4*288bf522SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*288bf522SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*288bf522SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*288bf522SAndroid Build Coastguard Worker  *
8*288bf522SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*288bf522SAndroid Build Coastguard Worker  *
10*288bf522SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*288bf522SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*288bf522SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*288bf522SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*288bf522SAndroid Build Coastguard Worker  * limitations under the License.
15*288bf522SAndroid Build Coastguard Worker  */
16*288bf522SAndroid Build Coastguard Worker 
17*288bf522SAndroid Build Coastguard Worker #include <gtest/gtest.h>
18*288bf522SAndroid Build Coastguard Worker 
19*288bf522SAndroid Build Coastguard Worker #include <memory_trace/MemoryTrace.h>
20*288bf522SAndroid Build Coastguard Worker 
21*288bf522SAndroid Build Coastguard Worker #include "Pointers.h"
22*288bf522SAndroid Build Coastguard Worker #include "Thread.h"
23*288bf522SAndroid Build Coastguard Worker #include "Threads.h"
24*288bf522SAndroid Build Coastguard Worker 
TEST(ThreadsTest,single_thread)25*288bf522SAndroid Build Coastguard Worker TEST(ThreadsTest, single_thread) {
26*288bf522SAndroid Build Coastguard Worker   Pointers pointers(2);
27*288bf522SAndroid Build Coastguard Worker 
28*288bf522SAndroid Build Coastguard Worker   Threads threads(&pointers, 1);
29*288bf522SAndroid Build Coastguard Worker   Thread* thread = threads.CreateThread(900);
30*288bf522SAndroid Build Coastguard Worker   ASSERT_TRUE(thread != nullptr);
31*288bf522SAndroid Build Coastguard Worker   ASSERT_EQ(1U, threads.num_threads());
32*288bf522SAndroid Build Coastguard Worker 
33*288bf522SAndroid Build Coastguard Worker   Thread* found_thread = threads.FindThread(900);
34*288bf522SAndroid Build Coastguard Worker   ASSERT_EQ(thread, found_thread);
35*288bf522SAndroid Build Coastguard Worker 
36*288bf522SAndroid Build Coastguard Worker   memory_trace::Entry thread_done = {.type = memory_trace::THREAD_DONE};
37*288bf522SAndroid Build Coastguard Worker   thread->SetEntry(&thread_done);
38*288bf522SAndroid Build Coastguard Worker 
39*288bf522SAndroid Build Coastguard Worker   thread->SetPending();
40*288bf522SAndroid Build Coastguard Worker 
41*288bf522SAndroid Build Coastguard Worker   threads.Finish(thread);
42*288bf522SAndroid Build Coastguard Worker 
43*288bf522SAndroid Build Coastguard Worker   ASSERT_EQ(0U, threads.num_threads());
44*288bf522SAndroid Build Coastguard Worker }
45*288bf522SAndroid Build Coastguard Worker 
TEST(ThreadsTest,multiple_threads)46*288bf522SAndroid Build Coastguard Worker TEST(ThreadsTest, multiple_threads) {
47*288bf522SAndroid Build Coastguard Worker   Pointers pointers(4);
48*288bf522SAndroid Build Coastguard Worker 
49*288bf522SAndroid Build Coastguard Worker   Threads threads(&pointers, 1);
50*288bf522SAndroid Build Coastguard Worker   Thread* thread1 = threads.CreateThread(900);
51*288bf522SAndroid Build Coastguard Worker   ASSERT_TRUE(thread1 != nullptr);
52*288bf522SAndroid Build Coastguard Worker   ASSERT_EQ(1U, threads.num_threads());
53*288bf522SAndroid Build Coastguard Worker 
54*288bf522SAndroid Build Coastguard Worker   Thread* thread2 = threads.CreateThread(901);
55*288bf522SAndroid Build Coastguard Worker   ASSERT_TRUE(thread2 != nullptr);
56*288bf522SAndroid Build Coastguard Worker   ASSERT_EQ(2U, threads.num_threads());
57*288bf522SAndroid Build Coastguard Worker 
58*288bf522SAndroid Build Coastguard Worker   Thread* thread3 = threads.CreateThread(902);
59*288bf522SAndroid Build Coastguard Worker   ASSERT_TRUE(thread3 != nullptr);
60*288bf522SAndroid Build Coastguard Worker   ASSERT_EQ(3U, threads.num_threads());
61*288bf522SAndroid Build Coastguard Worker 
62*288bf522SAndroid Build Coastguard Worker   Thread* found_thread1 = threads.FindThread(900);
63*288bf522SAndroid Build Coastguard Worker   ASSERT_EQ(thread1, found_thread1);
64*288bf522SAndroid Build Coastguard Worker 
65*288bf522SAndroid Build Coastguard Worker   Thread* found_thread2 = threads.FindThread(901);
66*288bf522SAndroid Build Coastguard Worker   ASSERT_EQ(thread2, found_thread2);
67*288bf522SAndroid Build Coastguard Worker 
68*288bf522SAndroid Build Coastguard Worker   Thread* found_thread3 = threads.FindThread(902);
69*288bf522SAndroid Build Coastguard Worker   ASSERT_EQ(thread3, found_thread3);
70*288bf522SAndroid Build Coastguard Worker 
71*288bf522SAndroid Build Coastguard Worker   memory_trace::Entry thread_done = {.type = memory_trace::THREAD_DONE};
72*288bf522SAndroid Build Coastguard Worker   thread1->SetEntry(&thread_done);
73*288bf522SAndroid Build Coastguard Worker   thread2->SetEntry(&thread_done);
74*288bf522SAndroid Build Coastguard Worker   thread3->SetEntry(&thread_done);
75*288bf522SAndroid Build Coastguard Worker 
76*288bf522SAndroid Build Coastguard Worker   thread1->SetPending();
77*288bf522SAndroid Build Coastguard Worker   threads.Finish(thread1);
78*288bf522SAndroid Build Coastguard Worker   ASSERT_EQ(2U, threads.num_threads());
79*288bf522SAndroid Build Coastguard Worker 
80*288bf522SAndroid Build Coastguard Worker   thread3->SetPending();
81*288bf522SAndroid Build Coastguard Worker   threads.Finish(thread3);
82*288bf522SAndroid Build Coastguard Worker   ASSERT_EQ(1U, threads.num_threads());
83*288bf522SAndroid Build Coastguard Worker 
84*288bf522SAndroid Build Coastguard Worker   thread2->SetPending();
85*288bf522SAndroid Build Coastguard Worker   threads.Finish(thread2);
86*288bf522SAndroid Build Coastguard Worker   ASSERT_EQ(0U, threads.num_threads());
87*288bf522SAndroid Build Coastguard Worker }
88*288bf522SAndroid Build Coastguard Worker 
TEST(ThreadsTest,verify_quiesce)89*288bf522SAndroid Build Coastguard Worker TEST(ThreadsTest, verify_quiesce) {
90*288bf522SAndroid Build Coastguard Worker   Pointers pointers(4);
91*288bf522SAndroid Build Coastguard Worker 
92*288bf522SAndroid Build Coastguard Worker   Threads threads(&pointers, 1);
93*288bf522SAndroid Build Coastguard Worker   Thread* thread = threads.CreateThread(900);
94*288bf522SAndroid Build Coastguard Worker   ASSERT_TRUE(thread != nullptr);
95*288bf522SAndroid Build Coastguard Worker   ASSERT_EQ(1U, threads.num_threads());
96*288bf522SAndroid Build Coastguard Worker 
97*288bf522SAndroid Build Coastguard Worker   // If WaitForAllToQuiesce is not correct, then this should provoke an error
98*288bf522SAndroid Build Coastguard Worker   // since we are overwriting the action data while it's being used.
99*288bf522SAndroid Build Coastguard Worker   constexpr size_t kAllocEntries = 512;
100*288bf522SAndroid Build Coastguard Worker   std::vector<memory_trace::Entry> mallocs(kAllocEntries);
101*288bf522SAndroid Build Coastguard Worker   std::vector<memory_trace::Entry> frees(kAllocEntries);
102*288bf522SAndroid Build Coastguard Worker   for (size_t i = 0; i < kAllocEntries; i++) {
103*288bf522SAndroid Build Coastguard Worker     mallocs[i].type = memory_trace::MALLOC;
104*288bf522SAndroid Build Coastguard Worker     mallocs[i].ptr = 0x1234 + i;
105*288bf522SAndroid Build Coastguard Worker     mallocs[i].size = 100;
106*288bf522SAndroid Build Coastguard Worker     thread->SetEntry(&mallocs[i]);
107*288bf522SAndroid Build Coastguard Worker     thread->SetPending();
108*288bf522SAndroid Build Coastguard Worker     threads.WaitForAllToQuiesce();
109*288bf522SAndroid Build Coastguard Worker 
110*288bf522SAndroid Build Coastguard Worker     frees[i].type = memory_trace::FREE;
111*288bf522SAndroid Build Coastguard Worker     frees[i].ptr = 0x1234 + i;
112*288bf522SAndroid Build Coastguard Worker     thread->SetEntry(&frees[i]);
113*288bf522SAndroid Build Coastguard Worker     thread->SetPending();
114*288bf522SAndroid Build Coastguard Worker     threads.WaitForAllToQuiesce();
115*288bf522SAndroid Build Coastguard Worker   }
116*288bf522SAndroid Build Coastguard Worker 
117*288bf522SAndroid Build Coastguard Worker   memory_trace::Entry thread_done = {.type = memory_trace::THREAD_DONE};
118*288bf522SAndroid Build Coastguard Worker   thread->SetEntry(&thread_done);
119*288bf522SAndroid Build Coastguard Worker   thread->SetPending();
120*288bf522SAndroid Build Coastguard Worker   threads.Finish(thread);
121*288bf522SAndroid Build Coastguard Worker   ASSERT_EQ(0U, threads.num_threads());
122*288bf522SAndroid Build Coastguard Worker }
123*288bf522SAndroid Build Coastguard Worker 
TestTooManyThreads()124*288bf522SAndroid Build Coastguard Worker static void TestTooManyThreads() {
125*288bf522SAndroid Build Coastguard Worker   Pointers pointers(4);
126*288bf522SAndroid Build Coastguard Worker 
127*288bf522SAndroid Build Coastguard Worker   Threads threads(&pointers, 1);
128*288bf522SAndroid Build Coastguard Worker   for (size_t i = 0; i <= threads.max_threads(); i++) {
129*288bf522SAndroid Build Coastguard Worker     Thread* thread = threads.CreateThread(900+i);
130*288bf522SAndroid Build Coastguard Worker     ASSERT_EQ(thread, threads.FindThread(900+i));
131*288bf522SAndroid Build Coastguard Worker   }
132*288bf522SAndroid Build Coastguard Worker }
133*288bf522SAndroid Build Coastguard Worker 
TEST(ThreadsTest,too_many_threads)134*288bf522SAndroid Build Coastguard Worker TEST(ThreadsTest, too_many_threads) {
135*288bf522SAndroid Build Coastguard Worker   ASSERT_EXIT(TestTooManyThreads(), ::testing::ExitedWithCode(1), "");
136*288bf522SAndroid Build Coastguard Worker }
137