xref: /aosp_15_r20/system/chre/test/simulation/memory_test.cc (revision 84e339476a462649f82315436d70fd732297a399)
1 /*
2  * Copyright (C) 2022 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "chre_api/chre/re.h"
18 
19 #include <cstdint>
20 
21 #include "chre/core/event_loop_manager.h"
22 #include "chre/platform/log.h"
23 #include "chre/platform/memory_manager.h"
24 #include "chre_api/chre/event.h"
25 
26 #include "gtest/gtest.h"
27 #include "inc/test_util.h"
28 #include "test_base.h"
29 #include "test_event.h"
30 #include "test_event_queue.h"
31 #include "test_util.h"
32 
33 namespace chre {
34 namespace {
35 
TEST_F(TestBase,MemoryAllocateAndFree)36 TEST_F(TestBase, MemoryAllocateAndFree) {
37   CREATE_CHRE_TEST_EVENT(ALLOCATE, 0);
38   CREATE_CHRE_TEST_EVENT(FREE, 1);
39 
40   class App : public TestNanoapp {
41    public:
42     void handleEvent(uint32_t, uint16_t eventType,
43                      const void *eventData) override {
44       switch (eventType) {
45         case CHRE_EVENT_TEST_EVENT: {
46           auto event = static_cast<const TestEvent *>(eventData);
47           switch (event->type) {
48             case ALLOCATE: {
49               auto bytes = static_cast<const uint32_t *>(event->data);
50               void *ptr = chreHeapAlloc(*bytes);
51               TestEventQueueSingleton::get()->pushEvent(ALLOCATE, ptr);
52               break;
53             }
54             case FREE: {
55               auto ptr = static_cast<void **>(event->data);
56               chreHeapFree(*ptr);
57               TestEventQueueSingleton::get()->pushEvent(FREE);
58               break;
59             }
60           }
61         }
62       }
63     }
64   };
65 
66   uint64_t appId = loadNanoapp(MakeUnique<App>());
67 
68   MemoryManager &memManager =
69       EventLoopManagerSingleton::get()->getMemoryManager();
70   Nanoapp *nanoapp = getNanoappByAppId(appId);
71   ASSERT_NE(nanoapp, nullptr);
72 
73   EXPECT_EQ(nanoapp->getTotalAllocatedBytes(), 0);
74   EXPECT_EQ(memManager.getTotalAllocatedBytes(), 0);
75   EXPECT_EQ(memManager.getAllocationCount(), 0);
76 
77   void *ptr1;
78   sendEventToNanoapp(appId, ALLOCATE, 100);
79   waitForEvent(ALLOCATE, &ptr1);
80   EXPECT_NE(ptr1, nullptr);
81   EXPECT_EQ(nanoapp->getTotalAllocatedBytes(), 100);
82   EXPECT_EQ(memManager.getTotalAllocatedBytes(), 100);
83   EXPECT_EQ(memManager.getAllocationCount(), 1);
84 
85   void *ptr2;
86   sendEventToNanoapp(appId, ALLOCATE, 200);
87   waitForEvent(ALLOCATE, &ptr2);
88   EXPECT_NE(ptr2, nullptr);
89   EXPECT_EQ(nanoapp->getTotalAllocatedBytes(), 100 + 200);
90   EXPECT_EQ(memManager.getTotalAllocatedBytes(), 100 + 200);
91   EXPECT_EQ(memManager.getAllocationCount(), 2);
92 
93   sendEventToNanoapp(appId, FREE, ptr1);
94   waitForEvent(FREE);
95   EXPECT_EQ(nanoapp->getTotalAllocatedBytes(), 200);
96   EXPECT_EQ(memManager.getTotalAllocatedBytes(), 200);
97   EXPECT_EQ(memManager.getAllocationCount(), 1);
98 
99   sendEventToNanoapp(appId, FREE, ptr2);
100   waitForEvent(FREE);
101   EXPECT_EQ(nanoapp->getTotalAllocatedBytes(), 0);
102   EXPECT_EQ(memManager.getTotalAllocatedBytes(), 0);
103   EXPECT_EQ(memManager.getAllocationCount(), 0);
104 }
105 
TEST_F(TestBase,MemoryFreeOnNanoappUnload)106 TEST_F(TestBase, MemoryFreeOnNanoappUnload) {
107   CREATE_CHRE_TEST_EVENT(ALLOCATE, 0);
108 
109   class App : public TestNanoapp {
110    public:
111     void handleEvent(uint32_t, uint16_t eventType,
112                      const void *eventData) override {
113       switch (eventType) {
114         case CHRE_EVENT_TEST_EVENT: {
115           auto event = static_cast<const TestEvent *>(eventData);
116           switch (event->type) {
117             case ALLOCATE: {
118               auto bytes = static_cast<const uint32_t *>(event->data);
119               void *ptr = chreHeapAlloc(*bytes);
120               TestEventQueueSingleton::get()->pushEvent(ALLOCATE, ptr);
121               break;
122             }
123           }
124         }
125       }
126     }
127   };
128 
129   uint64_t appId = loadNanoapp(MakeUnique<App>());
130 
131   MemoryManager &memManager =
132       EventLoopManagerSingleton::get()->getMemoryManager();
133   Nanoapp *nanoapp = getNanoappByAppId(appId);
134   ASSERT_NE(nanoapp, nullptr);
135 
136   EXPECT_EQ(nanoapp->getTotalAllocatedBytes(), 0);
137   EXPECT_EQ(memManager.getTotalAllocatedBytes(), 0);
138   EXPECT_EQ(memManager.getAllocationCount(), 0);
139 
140   void *ptr1;
141   sendEventToNanoapp(appId, ALLOCATE, 100);
142   waitForEvent(ALLOCATE, &ptr1);
143   EXPECT_NE(ptr1, nullptr);
144   EXPECT_EQ(nanoapp->getTotalAllocatedBytes(), 100);
145   EXPECT_EQ(memManager.getTotalAllocatedBytes(), 100);
146   EXPECT_EQ(memManager.getAllocationCount(), 1);
147 
148   void *ptr2;
149   sendEventToNanoapp(appId, ALLOCATE, 200);
150   waitForEvent(ALLOCATE, &ptr2);
151   EXPECT_NE(ptr2, nullptr);
152   EXPECT_EQ(nanoapp->getTotalAllocatedBytes(), 100 + 200);
153   EXPECT_EQ(memManager.getTotalAllocatedBytes(), 100 + 200);
154   EXPECT_EQ(memManager.getAllocationCount(), 2);
155 
156   unloadNanoapp(appId);
157   EXPECT_EQ(memManager.getTotalAllocatedBytes(), 0);
158   EXPECT_EQ(memManager.getAllocationCount(), 0);
159 }
160 
TEST_F(TestBase,MemoryStressTestShouldNotTriggerErrors)161 TEST_F(TestBase, MemoryStressTestShouldNotTriggerErrors) {
162   CREATE_CHRE_TEST_EVENT(ALLOCATE, 0);
163   CREATE_CHRE_TEST_EVENT(FREE, 1);
164 
165   class App : public TestNanoapp {
166    public:
167     void handleEvent(uint32_t, uint16_t eventType,
168                      const void *eventData) override {
169       switch (eventType) {
170         case CHRE_EVENT_TEST_EVENT: {
171           auto event = static_cast<const TestEvent *>(eventData);
172           switch (event->type) {
173             case ALLOCATE: {
174               auto bytes = static_cast<const uint32_t *>(event->data);
175               void *ptr = chreHeapAlloc(*bytes);
176               TestEventQueueSingleton::get()->pushEvent(ALLOCATE, ptr);
177               break;
178             }
179             case FREE: {
180               auto ptr = static_cast<void **>(event->data);
181               chreHeapFree(*ptr);
182               TestEventQueueSingleton::get()->pushEvent(FREE);
183               break;
184             }
185           }
186         }
187       }
188     }
189   };
190 
191   MemoryManager &memManager =
192       EventLoopManagerSingleton::get()->getMemoryManager();
193 
194   uint64_t appId = loadNanoapp(MakeUnique<App>());
195 
196   EXPECT_EQ(memManager.getTotalAllocatedBytes(), 0);
197   EXPECT_EQ(memManager.getAllocationCount(), 0);
198 
199   void *ptr1;
200   void *ptr2;
201   void *ptr3;
202 
203   sendEventToNanoapp(appId, ALLOCATE, 100);
204   waitForEvent(ALLOCATE, &ptr1);
205   sendEventToNanoapp(appId, ALLOCATE, 200);
206   waitForEvent(ALLOCATE, &ptr2);
207   sendEventToNanoapp(appId, ALLOCATE, 300);
208   waitForEvent(ALLOCATE, &ptr3);
209   EXPECT_EQ(memManager.getTotalAllocatedBytes(), 100 + 200 + 300);
210   EXPECT_EQ(memManager.getAllocationCount(), 3);
211 
212   // Free middle, last, and first blocks.
213   sendEventToNanoapp(appId, FREE, ptr2);
214   waitForEvent(FREE);
215   sendEventToNanoapp(appId, FREE, ptr3);
216   waitForEvent(FREE);
217   sendEventToNanoapp(appId, FREE, ptr1);
218   waitForEvent(FREE);
219   EXPECT_EQ(memManager.getTotalAllocatedBytes(), 0);
220   EXPECT_EQ(memManager.getAllocationCount(), 0);
221 
222   sendEventToNanoapp(appId, ALLOCATE, 100);
223   waitForEvent(ALLOCATE, &ptr1);
224   sendEventToNanoapp(appId, ALLOCATE, 200);
225   waitForEvent(ALLOCATE, &ptr2);
226   sendEventToNanoapp(appId, ALLOCATE, 300);
227   waitForEvent(ALLOCATE, &ptr3);
228   EXPECT_EQ(memManager.getTotalAllocatedBytes(), 100 + 200 + 300);
229   EXPECT_EQ(memManager.getAllocationCount(), 3);
230 
231   // Free last, last and last blocks.
232   sendEventToNanoapp(appId, FREE, ptr3);
233   waitForEvent(FREE);
234   sendEventToNanoapp(appId, FREE, ptr2);
235   waitForEvent(FREE);
236   sendEventToNanoapp(appId, FREE, ptr1);
237   waitForEvent(FREE);
238   EXPECT_EQ(memManager.getTotalAllocatedBytes(), 0);
239   EXPECT_EQ(memManager.getAllocationCount(), 0);
240 
241   sendEventToNanoapp(appId, ALLOCATE, 100);
242   waitForEvent(ALLOCATE, &ptr1);
243   sendEventToNanoapp(appId, ALLOCATE, 200);
244   waitForEvent(ALLOCATE, &ptr2);
245   sendEventToNanoapp(appId, ALLOCATE, 300);
246   waitForEvent(ALLOCATE, &ptr3);
247   EXPECT_EQ(memManager.getTotalAllocatedBytes(), 100 + 200 + 300);
248   EXPECT_EQ(memManager.getAllocationCount(), 3);
249 
250   // Automatic cleanup.
251   unloadNanoapp(appId);
252   EXPECT_EQ(memManager.getTotalAllocatedBytes(), 0);
253   EXPECT_EQ(memManager.getAllocationCount(), 0);
254 }
255 
256 }  // namespace
257 }  // namespace chre