1 /*
2  * Copyright (C) 2017 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_PLATFORM_MEMORY_MANAGER_H_
18 #define CHRE_PLATFORM_MEMORY_MANAGER_H_
19 
20 #include <cstddef>
21 #include <cstdint>
22 
23 #include "chre/core/nanoapp.h"
24 #include "chre/util/non_copyable.h"
25 #include "chre/util/system/debug_dump.h"
26 
27 // This default value can be overridden in the variant-specific makefile.
28 #ifndef CHRE_MAX_ALLOCATION_BYTES
29 #define CHRE_MAX_ALLOCATION_BYTES 262144  // 256 * 1024
30 #endif
31 
32 namespace chre {
33 
34 /**
35  * The MemoryManager keeps track of heap memory allocated/deallocated by all
36  * nanoapps.
37  *
38  * TODO: Free memory space when nanoapps are unloaded.
39  */
40 class MemoryManager : public NonCopyable {
41  public:
42   /**
43    * Allocate heap memory in CHRE.
44    *
45    * @param app The pointer to the nanoapp requesting memory.
46    * @param bytes The size in bytes to allocate.
47    * @return the allocated memory pointer. nullptr if the allocation fails.
48    */
49   void *nanoappAlloc(Nanoapp *app, uint32_t bytes);
50 
51   /**
52    * Free heap memory in CHRE.
53    *
54    * @param app The pointer to the nanoapp requesting memory free.
55    * @param ptr The pointer to the memory to deallocate.
56    */
57   void nanoappFree(Nanoapp *app, void *ptr);
58 
59   /**
60    * @return current total allocated memory in bytes.
61    */
getTotalAllocatedBytes()62   size_t getTotalAllocatedBytes() const {
63     return mTotalAllocatedBytes;
64   }
65 
66   /**
67    * @return peak total allocated memory in bytes.
68    */
getPeakAllocatedBytes()69   size_t getPeakAllocatedBytes() const {
70     return mPeakAllocatedBytes;
71   }
72 
73   /**
74    * @return current count of allocated memory spaces.
75    */
getAllocationCount()76   size_t getAllocationCount() const {
77     return mAllocationCount;
78   }
79 
80   /**
81    * @return max total allocatable memory in bytes.
82    */
getMaxAllocationBytes()83   size_t getMaxAllocationBytes() const {
84     return kMaxAllocationBytes;
85   }
86 
87   /**
88    * @return max allocatable memory counts.
89    */
getMaxAllocationCount()90   size_t getMaxAllocationCount() const {
91     return kMaxAllocationCount;
92   }
93 
94   /**
95    * Prints state in a string buffer. Must only be called from the context of
96    * the main CHRE thread.
97    *
98    * @param debugDump The debug dump wrapper where a string can be printed into
99    *    one of the buffers.
100    */
101   void logStateToBuffer(DebugDumpWrapper &debugDump) const;
102 
103  private:
104   /**
105    * Header to store allocation details for tracking.
106    * We use a union to ensure proper memory alignment.
107    */
108   union AllocHeader {
109     struct {
110       //! The amount of memory in bytes allocated (not including header).
111       uint32_t bytes;
112 
113       //! The ID of nanoapp requesting memory allocation.
114       uint32_t instanceId;
115     } data;
116 
117     //! Makes sure header is a multiple of the size of max_align_t
118     max_align_t aligner;
119   };
120 
121   //! The total allocated memory in bytes (not including header).
122   size_t mTotalAllocatedBytes = 0;
123 
124   //! The peak allocated memory in bytes (not including header).
125   size_t mPeakAllocatedBytes = 0;
126 
127   //! Stores total number of allocated memory spaces.
128   size_t mAllocationCount = 0;
129 
130   //! The maximum allowable total allocated memory in bytes for all nanoapps.
131   static constexpr size_t kMaxAllocationBytes = CHRE_MAX_ALLOCATION_BYTES;
132 
133   //! The maximum allowable count of memory allocations for all nanoapps.
134   static constexpr size_t kMaxAllocationCount = (8 * 1024);
135 
136   /**
137    * Called by nanoappAlloc to perform the appropriate call to memory alloc.
138    *
139    * The semantics are the same as nanoappAlloc.
140    */
141   void *doAlloc(Nanoapp *app, uint32_t size);
142 
143   /**
144    * Called by nanoappFree to perform the appropriate call to memory free.
145    *
146    * The sematics are the same as nanoappFree.
147    */
148   void doFree(Nanoapp *app, void *ptr);
149 };
150 
151 }  // namespace chre
152 
153 #endif  // CHRE_PLATFORM_MEMORY_MANAGER_H_
154