• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2018 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 #pragma once
15 
16 #include "aemu/base/AlignedBuf.h"
17 #include "aemu/base/Allocator.h"
18 
19 #include <vector>
20 #include <unordered_set>
21 
22 #include <inttypes.h>
23 
24 namespace android {
25 namespace base {
26 
27 // Class to make it easier to set up memory regions where it is fast
28 // to allocate buffers AND we don't care about freeing individual pieces,
29 // BUT it's necessary to preserve previous pointer values in between the first
30 // alloc() after a freeAll(), and the freeAll() itself, allowing some sloppy use of
31 // malloc in the first pass while we find out how much data was needed.
32 class BumpPool : public Allocator {
33 public:
34     BumpPool(size_t startingBytes = 4096) : mStorage(startingBytes / sizeof(uint64_t))  { }
35     // All memory allocated by this pool
36     // is automatically deleted when the pool
37     // is deconstructed.
~BumpPool()38     ~BumpPool() { }
39 
alloc(size_t wantedSize)40     void* alloc(size_t wantedSize) override {
41         size_t wantedSizeRoundedUp =
42             sizeof(uint64_t) * ((wantedSize + sizeof(uint64_t) - 1) / (sizeof(uint64_t)));
43 
44         mTotalWantedThisGeneration += wantedSizeRoundedUp;
45         if (mAllocPos + wantedSizeRoundedUp > mStorage.size() * sizeof(uint64_t)) {
46             mNeedRealloc = true;
47             void* fallbackPtr = malloc(wantedSizeRoundedUp);
48             mFallbackPtrs.insert(fallbackPtr);
49             return fallbackPtr;
50         }
51         size_t avail = mStorage.size() * sizeof(uint64_t) - mAllocPos;
52         void* allocPtr = (void*)(((unsigned char*)mStorage.data()) + mAllocPos);
53         mAllocPos += wantedSizeRoundedUp;
54         return allocPtr;
55     }
56 
freeAll()57     void freeAll() {
58         mAllocPos = 0;
59         if (mNeedRealloc) {
60             mStorage.resize((mTotalWantedThisGeneration * 2) / sizeof(uint64_t));
61             mNeedRealloc = false;
62             for (auto ptr : mFallbackPtrs) {
63                 free(ptr);
64             }
65             mFallbackPtrs.clear();
66         }
67         mTotalWantedThisGeneration = 0;
68     }
69 private:
70     AlignedBuf<uint64_t, 8> mStorage;
71     std::unordered_set<void*> mFallbackPtrs;
72     size_t mAllocPos = 0;
73     size_t mTotalWantedThisGeneration = 0;
74     bool mNeedRealloc = false;
75 };
76 
77 } // namespace base
78 } // namespace android
79