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 #include <shared/chunk_allocator.h>
18
19 #include <shared/nano_string.h>
20
21 namespace nanoapp_testing {
22
ChunkAllocatorBase(size_t allocSize,size_t slotCount,uint8_t * rawMemory)23 ChunkAllocatorBase::ChunkAllocatorBase(size_t allocSize, size_t slotCount,
24 uint8_t *rawMemory)
25 : mAllocSize(allocSize),
26 mSlotCount(slotCount),
27 mRawMemory(rawMemory),
28 mAllocatedSlots(0) {
29 // We're not worried about runtime efficiency, since this is testing
30 // code. In case of an issue within the tests, though, we do want
31 // to have consistent behavior. Thus, we initialize this memory to
32 // aid tracking problems.
33 memset(mRawMemory, 0xCD, mSlotCount * mAllocSize);
34 }
35
alloc(size_t bytes)36 void *ChunkAllocatorBase::alloc(size_t bytes) {
37 if (bytes > mAllocSize) {
38 // Oversized for our allocator.
39 return nullptr;
40 }
41 size_t slot = 0;
42 for (uint32_t mask = 1; slot < mSlotCount; slot++, mask <<= 1) {
43 if ((mAllocatedSlots & mask) == 0) {
44 // This space is available, let's claim it.
45 mAllocatedSlots |= mask;
46 break;
47 }
48 }
49 if (slot == mSlotCount) {
50 // We're out of space.
51 return nullptr;
52 }
53 return mRawMemory + (slot * mAllocSize);
54 }
55
free(void * pointer)56 bool ChunkAllocatorBase::free(void *pointer) {
57 size_t slot;
58 if (!getSlot(pointer, &slot)) {
59 return false;
60 }
61 mAllocatedSlots &= ~(1 << slot);
62 return true;
63 }
64
contains(const void * pointer) const65 bool ChunkAllocatorBase::contains(const void *pointer) const {
66 size_t slot;
67 return getSlot(pointer, &slot);
68 }
69
getSlot(const void * pointer,size_t * slot) const70 bool ChunkAllocatorBase::getSlot(const void *pointer, size_t *slot) const {
71 const uint8_t *ptr = static_cast<const uint8_t *>(pointer);
72 if (ptr < mRawMemory) {
73 // Out of range.
74 return false;
75 }
76 *slot = static_cast<size_t>(ptr - mRawMemory) / mAllocSize;
77 if (*slot >= mSlotCount) {
78 // Out of range.
79 return false;
80 }
81 // Also confirm alignment.
82 return ((mRawMemory + (*slot * mAllocSize)) == ptr);
83 }
84
85 } // namespace nanoapp_testing
86