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