• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
getNanoappByAppId(uint64_t id)36 Nanoapp *getNanoappByAppId(uint64_t id) {
37   uint16_t instanceId;
38   EXPECT_TRUE(EventLoopManagerSingleton::get()
39                   ->getEventLoop()
40                   .findNanoappInstanceIdByAppId(id, &instanceId));
41   Nanoapp *nanoapp =
42       EventLoopManagerSingleton::get()->getEventLoop().findNanoappByInstanceId(
43           instanceId);
44   EXPECT_NE(nanoapp, nullptr);
45   return nanoapp;
46 }
47 
TEST_F(TestBase,MemoryAllocateAndFree)48 TEST_F(TestBase, MemoryAllocateAndFree) {
49   CREATE_CHRE_TEST_EVENT(ALLOCATE, 0);
50   CREATE_CHRE_TEST_EVENT(FREE, 1);
51 
52   struct App : public TestNanoapp {
53     void (*handleEvent)(uint32_t, uint16_t, const void *) =
54         [](uint32_t, uint16_t eventType, const void *eventData) {
55           switch (eventType) {
56             case CHRE_EVENT_TEST_EVENT: {
57               auto event = static_cast<const TestEvent *>(eventData);
58               switch (event->type) {
59                 case ALLOCATE: {
60                   auto bytes = static_cast<const uint32_t *>(event->data);
61                   void *ptr = chreHeapAlloc(*bytes);
62                   TestEventQueueSingleton::get()->pushEvent(ALLOCATE, ptr);
63                   break;
64                 }
65                 case FREE: {
66                   auto ptr = static_cast<void **>(event->data);
67                   chreHeapFree(*ptr);
68                   TestEventQueueSingleton::get()->pushEvent(FREE);
69                   break;
70                 }
71               }
72             }
73           }
74         };
75   };
76 
77   auto app = loadNanoapp<App>();
78 
79   MemoryManager &memManager =
80       EventLoopManagerSingleton::get()->getMemoryManager();
81   Nanoapp *nanoapp = getNanoappByAppId(app.id);
82 
83   EXPECT_EQ(nanoapp->getTotalAllocatedBytes(), 0);
84   EXPECT_EQ(memManager.getTotalAllocatedBytes(), 0);
85   EXPECT_EQ(memManager.getAllocationCount(), 0);
86 
87   void *ptr1;
88   sendEventToNanoapp(app, ALLOCATE, 100);
89   waitForEvent(ALLOCATE, &ptr1);
90   EXPECT_NE(ptr1, nullptr);
91   EXPECT_EQ(nanoapp->getTotalAllocatedBytes(), 100);
92   EXPECT_EQ(memManager.getTotalAllocatedBytes(), 100);
93   EXPECT_EQ(memManager.getAllocationCount(), 1);
94 
95   void *ptr2;
96   sendEventToNanoapp(app, ALLOCATE, 200);
97   waitForEvent(ALLOCATE, &ptr2);
98   EXPECT_NE(ptr2, nullptr);
99   EXPECT_EQ(nanoapp->getTotalAllocatedBytes(), 100 + 200);
100   EXPECT_EQ(memManager.getTotalAllocatedBytes(), 100 + 200);
101   EXPECT_EQ(memManager.getAllocationCount(), 2);
102 
103   sendEventToNanoapp(app, FREE, ptr1);
104   waitForEvent(FREE);
105   EXPECT_EQ(nanoapp->getTotalAllocatedBytes(), 200);
106   EXPECT_EQ(memManager.getTotalAllocatedBytes(), 200);
107   EXPECT_EQ(memManager.getAllocationCount(), 1);
108 
109   sendEventToNanoapp(app, FREE, ptr2);
110   waitForEvent(FREE);
111   EXPECT_EQ(nanoapp->getTotalAllocatedBytes(), 0);
112   EXPECT_EQ(memManager.getTotalAllocatedBytes(), 0);
113   EXPECT_EQ(memManager.getAllocationCount(), 0);
114 }
115 
TEST_F(TestBase,MemoryFreeOnNanoappUnload)116 TEST_F(TestBase, MemoryFreeOnNanoappUnload) {
117   CREATE_CHRE_TEST_EVENT(ALLOCATE, 0);
118 
119   struct App : public TestNanoapp {
120     void (*handleEvent)(uint32_t, uint16_t, const void *) =
121         [](uint32_t, uint16_t eventType, const void *eventData) {
122           switch (eventType) {
123             case CHRE_EVENT_TEST_EVENT: {
124               auto event = static_cast<const TestEvent *>(eventData);
125               switch (event->type) {
126                 case ALLOCATE: {
127                   auto bytes = static_cast<const uint32_t *>(event->data);
128                   void *ptr = chreHeapAlloc(*bytes);
129                   TestEventQueueSingleton::get()->pushEvent(ALLOCATE, ptr);
130                   break;
131                 }
132               }
133             }
134           }
135         };
136   };
137 
138   auto app = loadNanoapp<App>();
139 
140   MemoryManager &memManager =
141       EventLoopManagerSingleton::get()->getMemoryManager();
142   Nanoapp *nanoapp = getNanoappByAppId(app.id);
143 
144   EXPECT_EQ(nanoapp->getTotalAllocatedBytes(), 0);
145   EXPECT_EQ(memManager.getTotalAllocatedBytes(), 0);
146   EXPECT_EQ(memManager.getAllocationCount(), 0);
147 
148   void *ptr1;
149   sendEventToNanoapp(app, ALLOCATE, 100);
150   waitForEvent(ALLOCATE, &ptr1);
151   EXPECT_NE(ptr1, nullptr);
152   EXPECT_EQ(nanoapp->getTotalAllocatedBytes(), 100);
153   EXPECT_EQ(memManager.getTotalAllocatedBytes(), 100);
154   EXPECT_EQ(memManager.getAllocationCount(), 1);
155 
156   void *ptr2;
157   sendEventToNanoapp(app, ALLOCATE, 200);
158   waitForEvent(ALLOCATE, &ptr2);
159   EXPECT_NE(ptr2, nullptr);
160   EXPECT_EQ(nanoapp->getTotalAllocatedBytes(), 100 + 200);
161   EXPECT_EQ(memManager.getTotalAllocatedBytes(), 100 + 200);
162   EXPECT_EQ(memManager.getAllocationCount(), 2);
163 
164   unloadNanoapp(app);
165   EXPECT_EQ(memManager.getTotalAllocatedBytes(), 0);
166   EXPECT_EQ(memManager.getAllocationCount(), 0);
167 }
168 
TEST_F(TestBase,MemoryStressTestShouldNotTriggerErrors)169 TEST_F(TestBase, MemoryStressTestShouldNotTriggerErrors) {
170   CREATE_CHRE_TEST_EVENT(ALLOCATE, 0);
171   CREATE_CHRE_TEST_EVENT(FREE, 1);
172 
173   struct App : public TestNanoapp {
174     void (*handleEvent)(uint32_t, uint16_t, const void *) =
175         [](uint32_t, uint16_t eventType, const void *eventData) {
176           switch (eventType) {
177             case CHRE_EVENT_TEST_EVENT: {
178               auto event = static_cast<const TestEvent *>(eventData);
179               switch (event->type) {
180                 case ALLOCATE: {
181                   auto bytes = static_cast<const uint32_t *>(event->data);
182                   void *ptr = chreHeapAlloc(*bytes);
183                   TestEventQueueSingleton::get()->pushEvent(ALLOCATE, ptr);
184                   break;
185                 }
186                 case FREE: {
187                   auto ptr = static_cast<void **>(event->data);
188                   chreHeapFree(*ptr);
189                   TestEventQueueSingleton::get()->pushEvent(FREE);
190                   break;
191                 }
192               }
193             }
194           }
195         };
196   };
197 
198   MemoryManager &memManager =
199       EventLoopManagerSingleton::get()->getMemoryManager();
200 
201   auto app = loadNanoapp<App>();
202 
203   EXPECT_EQ(memManager.getTotalAllocatedBytes(), 0);
204   EXPECT_EQ(memManager.getAllocationCount(), 0);
205 
206   void *ptr1;
207   void *ptr2;
208   void *ptr3;
209 
210   sendEventToNanoapp(app, ALLOCATE, 100);
211   waitForEvent(ALLOCATE, &ptr1);
212   sendEventToNanoapp(app, ALLOCATE, 200);
213   waitForEvent(ALLOCATE, &ptr2);
214   sendEventToNanoapp(app, ALLOCATE, 300);
215   waitForEvent(ALLOCATE, &ptr3);
216   EXPECT_EQ(memManager.getTotalAllocatedBytes(), 100 + 200 + 300);
217   EXPECT_EQ(memManager.getAllocationCount(), 3);
218 
219   // Free middle, last, and first blocks.
220   sendEventToNanoapp(app, FREE, ptr2);
221   waitForEvent(FREE);
222   sendEventToNanoapp(app, FREE, ptr3);
223   waitForEvent(FREE);
224   sendEventToNanoapp(app, FREE, ptr1);
225   waitForEvent(FREE);
226   EXPECT_EQ(memManager.getTotalAllocatedBytes(), 0);
227   EXPECT_EQ(memManager.getAllocationCount(), 0);
228 
229   sendEventToNanoapp(app, ALLOCATE, 100);
230   waitForEvent(ALLOCATE, &ptr1);
231   sendEventToNanoapp(app, ALLOCATE, 200);
232   waitForEvent(ALLOCATE, &ptr2);
233   sendEventToNanoapp(app, ALLOCATE, 300);
234   waitForEvent(ALLOCATE, &ptr3);
235   EXPECT_EQ(memManager.getTotalAllocatedBytes(), 100 + 200 + 300);
236   EXPECT_EQ(memManager.getAllocationCount(), 3);
237 
238   // Free last, last and last blocks.
239   sendEventToNanoapp(app, FREE, ptr3);
240   waitForEvent(FREE);
241   sendEventToNanoapp(app, FREE, ptr2);
242   waitForEvent(FREE);
243   sendEventToNanoapp(app, FREE, ptr1);
244   waitForEvent(FREE);
245   EXPECT_EQ(memManager.getTotalAllocatedBytes(), 0);
246   EXPECT_EQ(memManager.getAllocationCount(), 0);
247 
248   sendEventToNanoapp(app, ALLOCATE, 100);
249   waitForEvent(ALLOCATE, &ptr1);
250   sendEventToNanoapp(app, ALLOCATE, 200);
251   waitForEvent(ALLOCATE, &ptr2);
252   sendEventToNanoapp(app, ALLOCATE, 300);
253   waitForEvent(ALLOCATE, &ptr3);
254   EXPECT_EQ(memManager.getTotalAllocatedBytes(), 100 + 200 + 300);
255   EXPECT_EQ(memManager.getAllocationCount(), 3);
256 
257   // Automatic cleanup.
258   unloadNanoapp(app);
259   EXPECT_EQ(memManager.getTotalAllocatedBytes(), 0);
260   EXPECT_EQ(memManager.getAllocationCount(), 0);
261 }
262 
263 }  // namespace
264 }  // namespace chre