memory_pool_impl.h revision 4927ee586656424c827920876673228fbdcf27c3
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 CHRE_UTIL_MEMORY_POOL_IMPL_H_ 18#define CHRE_UTIL_MEMORY_POOL_IMPL_H_ 19 20#include "chre/util/memory_pool.h" 21 22#include <utility> 23 24/* 25 * TODO: needs to be thread safe (or there needs to be a thread safe version) 26 */ 27 28namespace chre { 29 30template<typename ElementType, size_t kSize> 31MemoryPool<ElementType, kSize>::MemoryPool() { 32 // Initialize the free block list. The initial condition is such that each 33 // block points to the next as being empty. The mFreeBlockCount is used to 34 // ensure that we never allocate out of bounds so we don't need to worry about 35 // the last block referring to one that is non-existent. 36 for (size_t i = 0; i < kSize; i++) { 37 mBlocks.emplace_back(i + 1); 38 } 39} 40 41template<typename ElementType, size_t kSize> 42template<typename... Args> 43ElementType *MemoryPool<ElementType, kSize>::allocate(Args&&... args) { 44 if (mFreeBlockCount == 0) { 45 return nullptr; 46 } 47 48 size_t blockIndex = mNextFreeBlockIndex; 49 mNextFreeBlockIndex = mBlocks[blockIndex].mNextFreeBlockIndex; 50 mFreeBlockCount--; 51 52 return new (&mBlocks[blockIndex].mElement) 53 ElementType(std::forward<Args>(args)...); 54} 55 56template<typename ElementType, size_t kSize> 57void MemoryPool<ElementType, kSize>::deallocate(ElementType *element) { 58 uintptr_t elementAddress = reinterpret_cast<uintptr_t>(element); 59 uintptr_t baseAddress = reinterpret_cast<uintptr_t>(&mBlocks[0].mElement); 60 size_t blockIndex = (elementAddress - baseAddress) / sizeof(MemoryPoolBlock); 61 62 mBlocks[blockIndex].mElement.~ElementType(); 63 mBlocks[blockIndex].mNextFreeBlockIndex = mNextFreeBlockIndex; 64 mNextFreeBlockIndex = blockIndex; 65 mFreeBlockCount++; 66} 67 68template<typename ElementType, size_t kSize> 69MemoryPool<ElementType, kSize>::MemoryPoolBlock::MemoryPoolBlock( 70 size_t nextFreeBlockIndex) : mNextFreeBlockIndex(nextFreeBlockIndex) {} 71 72} // namespace chre 73 74#endif // CHRE_UTIL_MEMORY_POOL_IMPL_H_ 75