Home | History | Annotate | Download | only in shared
      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/dumb_allocator.h>
     18 
     19 #include <shared/nano_string.h>
     20 
     21 namespace nanoapp_testing {
     22 
     23 DumbAllocatorBase::DumbAllocatorBase(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 
     36 void *DumbAllocatorBase::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 
     56 bool DumbAllocatorBase::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 
     65 bool DumbAllocatorBase::contains(const void *pointer) const {
     66   size_t slot;
     67   return getSlot(pointer, &slot);
     68 }
     69 
     70 bool DumbAllocatorBase::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 
     86 }  // namespace nanoapp_testing
     87