14d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro/* 24d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro * Copyright (C) 2016 The Android Open Source Project 34d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro * 44d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro * Licensed under the Apache License, Version 2.0 (the "License"); 54d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro * you may not use this file except in compliance with the License. 64d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro * You may obtain a copy of the License at 74d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro * 84d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro * http://www.apache.org/licenses/LICENSE-2.0 94d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro * 104d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro * Unless required by applicable law or agreed to in writing, software 114d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro * distributed under the License is distributed on an "AS IS" BASIS, 124d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 134d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro * See the License for the specific language governing permissions and 144d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro * limitations under the License. 154d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro */ 164d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro 174d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro#include <general_test/simple_heap_alloc_test.h> 184d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro 194d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro#include <cstddef> 204d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro 214d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro#include <general_test/test_names.h> 224d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro#include <shared/abort.h> 234d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro#include <shared/array_length.h> 244d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro#include <shared/nano_string.h> 254d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro#include <shared/send_message.h> 264d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro 274d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro#include <chre.h> 284d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro 294d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishigurousing nanoapp_testing::MessageType; 304d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishigurousing nanoapp_testing::sendFatalFailureToHost; 314d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishigurousing nanoapp_testing::sendMessageToHost; 324d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishigurousing nanoapp_testing::sendSuccessToHost; 334d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro 344d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguronamespace general_test { 354d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro 364d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro// For most platforms, we expect that what the compiler toolchain claims 374d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro// is the maximum alignment needed for any type is accurate. However, we 384d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro// do support one CHRE implementation where it is configured for a lower 394d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro// max alignment than what the toolchain claims. 404d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro// To support this, we allow for a compiler define set for building this 414d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro// test. For the most part, we need to just trust the CHRE implementation 424d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro// that this number is correct. However, we make a basic sanity check of 434d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro// this in testMaxAlignment(). 444d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro 454d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguroconstexpr size_t kMaxAlignment = 464d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro#ifdef CHRE_CUSTOM_MAX_ALIGNMENT 474d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro CHRE_CUSTOM_MAX_ALIGNMENT; 484d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro#else 494d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro alignof(max_align_t); 504d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro#endif // else CHRE_CUSTOM_MAX_ALIGNMENT 514d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro 524d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro#ifdef CHRE_CUSTOM_MAX_ALIGNMENT 534d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro// We only test this when a CHRE implementation claims a custom max aligment. 544d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro// We use an argument here to try to keep the compiler from performing any 554d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro// of these calculations at compile-time, so they're forced to happen at 564d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro// runtime. We do a mixture of multiplication and division, to force 574d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro// various instructions which might have alignment constraints. 584d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishigurostatic void testMaxAlignment(uint32_t zero) { 594d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro // It's not sufficient to use alignas(kMaxAlignment). Say kMaxAlignment 604d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro // is 4. Then alignas(4) could legally give something aligned on 32 bytes, 614d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro // and we wouldn't be testing what we hoped to test. So we ask for double 624d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro // the alignment (alignas(8), in our example), and then offset into that 634d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro // to assure that we're at exactly kMaxAlignment, and no more. 644d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro 654d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro#ifdef CHRE_NO_DOUBLE_SUPPORT 664d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro typedef float MyFloat; 674d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro#define FLOAT_C(value) value##f 684d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro#else 694d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro typedef long double myFloat; 704d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro#define FLOAT_C(value) value 714d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro#endif 724d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro 734d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro alignas(kMaxAlignment * 2) uint8_t 744d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro myFloatMemory[sizeof(MyFloat) * 3 + kMaxAlignment]; 754d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro MyFloat *mfArray = 764d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro reinterpret_cast<MyFloat*>(myFloatMemory + kMaxAlignment); 774d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro mfArray[0] = static_cast<MyFloat>(zero) + FLOAT_C(1.0); 784d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro mfArray[1] = static_cast<MyFloat>(zero) + FLOAT_C(3.0); 794d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro mfArray[2] = mfArray[0] / mfArray[1]; 804d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro if ((mfArray[0] * mfArray[1] + mfArray[2]) / FLOAT_C(3.0) == FLOAT_C(1.0)) { 814d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro sendFatalFailureToHost("Float math is wrong"); 824d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro } 834d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro 844d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro constexpr size_t kUllSize = sizeof(unsigned long long); 854d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro static_assert(kUllSize >= 8, "Size of long long violates spec"); 864d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro alignas(kMaxAlignment * 2) uint8_t 874d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro longlongMemory[kUllSize * 3 + kMaxAlignment]; 884d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro unsigned long long *ullArray = 894d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro reinterpret_cast<unsigned long long*>(longlongMemory + kMaxAlignment); 904d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro ullArray[0] = static_cast<unsigned long long>(zero) + 914d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro (1ULL << (kUllSize * 8 - 4)); 924d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro ullArray[1] = static_cast<unsigned long long>(zero) + (1ULL << 3); 934d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro ullArray[2] = ullArray[0] * ullArray[1]; 944d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro constexpr unsigned long long kExpected = 747134227367742ULL; 954d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro unsigned long long result = ullArray[2] / 12345ULL; 964d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro if (((kUllSize == 8) && (result != kExpected)) || 974d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro ((kUllSize > 8) && (result <= kExpected))) { 984d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro sendFatalFailureToHost("Long long math is wrong"); 994d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro } 1004d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro} 1014d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro#endif // CHRE_CUSTOM_MAX_ALIGNMENT 1024d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro 1034d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro 1044d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur IshiguroSimpleHeapAllocTest::SimpleHeapAllocTest() 1054d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro : Test(CHRE_API_VERSION_1_0), mHasFreed(false) { 1064d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro} 1074d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro 1084d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishigurovoid SimpleHeapAllocTest::setUp(uint32_t messageSize, 1094d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro const void * /* message */) { 1104d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro nanoapp_testing::memset(mPtrs, 0, sizeof(mPtrs)); 1114d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro 1124d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro if (messageSize != 0) { 1134d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro sendFatalFailureToHost( 1144d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro "SimpleHeapAlloc message expects 0 additional bytes, got ", 1154d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro &messageSize); 1164d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro } 1174d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro 1184d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro // Allocate random small-ish sizes. 1194d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro static constexpr size_t kSizes[5] = { 1204d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro 16, 53, 2, 32, 40 }; 1214d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro 1224d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro mPtrs[0] = chreHeapAlloc(kSizes[0]); 1234d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro mPtrs[1] = chreHeapAlloc(kSizes[1]); 1244d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro // For mPtrs[2] we do _not_ use kSizes[2], because we're going to free 1254d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro // this in a moment, and intentionally want a different size. 1264d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro mPtrs[2] = chreHeapAlloc(23); 1274d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro mPtrs[3] = chreHeapAlloc(kSizes[3]); 1284d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro // We want to mix in a free among the allocs, just to make sure there 1294d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro // isn't some issue there. 1304d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro if (mPtrs[2] == nullptr) { 1314d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro sendFatalFailureToHost("Failed first allocation of mPtrs[2]"); 1324d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro } else { 1334d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro chreHeapFree(mPtrs[2]); 1344d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro } 1354d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro mPtrs[4] = chreHeapAlloc(kSizes[4]); 1364d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro mPtrs[2] = chreHeapAlloc(kSizes[2]); 1374d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro 1384d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro for (uint32_t i = 0; i < arrayLength(mPtrs); i++) { 1394d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro if (mPtrs[i] == nullptr) { 1404d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro // If we're getting this failure, but convinced the CHRE is 1414d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro // correct, make sure that we're actually performing an allocation 1424d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro // for each element of mPtrs. 1434d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro sendFatalFailureToHost("Failed to allocate index ", &i); 1444d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro } 1454d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro const uintptr_t ptrValue = reinterpret_cast<uintptr_t>(mPtrs[i]); 1464d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro if ((ptrValue & (kMaxAlignment - 1)) != 0) { 1474d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro sendFatalFailureToHost("Misaligned allocation at index ", &i); 1484d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro } 1494d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro // Make sure all of the bytes are addressable. Our assumption 1504d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro // is we'll crash here if that's not the case. Not the most 1514d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro // friendly test, but it's better than allowing a bad CHRE. 1524d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro // TODO: If we convince ourselves that chreLog() should be 1534d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro // safe enough to use here, we could log an 'info' message 1544d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro // prior to each memset attempt. 1554d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro nanoapp_testing::memset(mPtrs[i], 0xFF, kSizes[i]); 1564d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro } 1574d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro#ifdef CHRE_CUSTOM_MAX_ALIGNMENT 1584d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro testMaxAlignment(messageSize); 1594d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro#endif // CHRE_CUSTOM_MAX_ALIGNMENT 1604d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro sendMessageToHost(MessageType::kContinue); 1614d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro} 1624d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro 1634d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishigurovoid SimpleHeapAllocTest::handleEvent(uint32_t senderInstanceId, 1644d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro uint16_t eventType, 1654d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro const void* eventData) { 1664d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro // We ignore the return value, since we expect no data. 1674d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro getMessageDataFromHostEvent(senderInstanceId, eventType, eventData, 1684d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro MessageType::kContinue, 0); 1694d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro if (mHasFreed) { 1704d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro sendFatalFailureToHost("Multiple kContinue messages sent"); 1714d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro } 1724d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro 1734d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro chreHeapFree(mPtrs[3]); 1744d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro chreHeapFree(mPtrs[1]); 1754d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro chreHeapFree(mPtrs[2]); 1764d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro chreHeapFree(mPtrs[0]); 1774d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro chreHeapFree(mPtrs[4]); 1784d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro mHasFreed = true; 1794d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro 1804d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro sendSuccessToHost(); 1814d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro} 1824d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro 1834d04a937b1bf7a949dfb00650b2640a9ed0c8acaArthur Ishiguro} // namespace general_test 184