1 /* 2 * Copyright (C) 2016 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 #ifndef _GTS_NANOAPPS_SHARED_DUMB_ALLOCATOR_H_ 18 #define _GTS_NANOAPPS_SHARED_DUMB_ALLOCATOR_H_ 19 20 #include <cstddef> 21 #include <cstdint> 22 23 namespace nanoapp_testing { 24 25 // Implementation Note: We chose the pattern of having DumbAllocatorBase to 26 // reduce the code duplication from multiple instances of DumbAllocator with 27 // different template parameters. 28 // See DumbAllocator below for usage and API documentation. 29 class DumbAllocatorBase { 30 protected: 31 DumbAllocatorBase(size_t allocSize, size_t slotCount, uint8_t *rawMemory); 32 33 void *alloc(size_t bytes); 34 bool free(void *ptr); 35 bool contains(const void *ptr) const; 36 MaxSlotCount()37 static constexpr size_t MaxSlotCount() { 38 // Our mAllocatedSlots is treated as a bit array, so we get 8 slots for 39 // each byte it has. 40 return (sizeof(mAllocatedSlots) * 8); 41 } 42 43 private: 44 const size_t mAllocSize; 45 const size_t mSlotCount; 46 uint8_t * const mRawMemory; 47 uint32_t mAllocatedSlots; 48 49 bool getSlot(const void *ptr, size_t *slot) const; 50 }; 51 52 53 /** 54 * This dumb allocator is designed to allow us to easily get chunks of 55 * memory without needing to go through heap allocation. The idea is to 56 * reduce our dependency on CHRE for some aspects of our tests. 57 * 58 * This allocator is non-reentrant. It's also inefficient and a bad idea 59 * for shipping code, but useful for reducing dependencies during testing. 60 * 61 * This will allow up to kSlotCount allocations of up to kAllocSize bytes 62 * each, and costs (kSlotCount * kAllocSize) bytes of underlying storage. 63 */ 64 template<size_t kAllocSize, size_t kSlotCount> 65 class DumbAllocator : DumbAllocatorBase { 66 public: DumbAllocator()67 DumbAllocator() 68 : DumbAllocatorBase(kAllocSize, kSlotCount, mRawMemoryArray) {} 69 70 /** 71 * If "bytes" <= kAllocSize, and there are less than kSlotCount allocations, 72 * return a valid pointer. Otherwise, nullptr. 73 * 74 * Reminder this is non-reentrant. 75 */ alloc(size_t bytes)76 void *alloc(size_t bytes) { 77 return DumbAllocatorBase::alloc(bytes); 78 } 79 80 /** 81 * If contains(ptr) is true, free the allocation and return true. 82 * Otherwise, do nothing and return false. 83 * 84 * Reminder this is non-reentrant. 85 */ free(void * ptr)86 bool free(void *ptr) { 87 return DumbAllocatorBase::free(ptr); 88 } 89 90 /** 91 * If "ptr" was a non-null pointer returned from alloc() on this instance, 92 * return true. Otherwise, do nothing and return false. 93 */ contains(const void * ptr)94 bool contains(const void *ptr) const { 95 return DumbAllocatorBase::contains(ptr); 96 } 97 98 private: 99 uint8_t mRawMemoryArray[kAllocSize * kSlotCount]; 100 101 static_assert(kSlotCount <= MaxSlotCount(), "kSlotCount is too high"); 102 }; 103 104 105 } // namespace nanoapp_testing 106 107 #endif // _GTS_NANOAPPS_SHARED_DUMB_ALLOCATOR_H_ 108