Merge "Remove uniform hash" into devel/master
[platform/core/uifw/dali-core.git] / dali / internal / common / memory-pool-object-allocator.h
1 #ifndef DALI_INTERNAL_MEMORY_POOL_OBJECT_ALLOCATOR_H
2 #define DALI_INTERNAL_MEMORY_POOL_OBJECT_ALLOCATOR_H
3
4 /*
5  * Copyright (c) 2023 Samsung Electronics Co., Ltd.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  */
20
21 // INTERNAL INCLUDES
22 #include <dali/internal/common/fixed-size-memory-pool.h>
23
24 namespace Dali
25 {
26 namespace Internal
27 {
28 /**
29  * @brief Helper for allocating/deallocating objects using a memory pool.
30  *
31  * This is a helper class for creating and destroying objects of a single given type.
32  * The type may be a class or POD.
33  *
34  */
35 template<typename T>
36 class MemoryPoolObjectAllocator
37 {
38 public:
39   /**
40    * Constant for use with FixedSizePool. We allow the fixed size pools to grow from 32
41    * to 1M entries per block, but maxing the blocks at 27 allows for many millions of
42    * elements to be quickly indexed using a 32 bit key.
43    */
44   const uint32_t POOL_MAX_BLOCK_COUNT = 27;
45
46   /**
47    * @brief Constructor
48    */
49   MemoryPoolObjectAllocator()
50   : mPool(nullptr)
51   {
52     ResetMemoryPool();
53   }
54
55   /**
56    * @brief Destructor
57    */
58   ~MemoryPoolObjectAllocator()
59   {
60     delete mPool;
61   }
62
63   /**
64    * @brief Allocate a block of memory from the memory pool of the appropriate size to
65    *        store an object of type T. This is usually so the memory can be used in a
66    *        placement new for an object of type T with a constructor that takes multiple
67    *        parameters.
68    *
69    * @return Return the allocated memory block
70    */
71   void* AllocateRaw()
72   {
73     return mPool->Allocate();
74   }
75
76   /**
77    * @brief Thread-safe version of AllocateRaw()
78    *
79    * @return Return the allocated memory block
80    */
81   void* AllocateRawThreadSafe()
82   {
83     return mPool->AllocateThreadSafe();
84   }
85
86   /**
87    * @brief Return the object to the memory pool
88    * Note: This performs a deallocation only, if the object has a destructor and is not
89    * freed from within an overloaded delete operator, Destroy() must be used instead.
90    *
91    * @param object Pointer to the object to delete
92    */
93   void Free(T* object)
94   {
95     mPool->Free(object);
96   }
97
98   /**
99    * @brief Thread-safe version of Free()
100    * Note: This performs a deallocation only, if the object has a destructor and is not
101    * freed from within an overloaded delete operator, DestroyThreadSafe() must be used instead.
102    *
103    * @param object Pointer to the object to delete
104    */
105   void FreeThreadSafe(T* object)
106   {
107     mPool->FreeThreadSafe(object);
108   }
109
110   /**
111    * @brief Return the object to the memory pool after destructing it.
112    * Note: Do not call this from an overloaded delete operator, as this will already have called the objects destructor.
113    *
114    * @param object Pointer to the object to delete
115    */
116   void Destroy(T* object)
117   {
118     object->~T();
119     mPool->Free(object);
120   }
121
122   /**
123    * @brief Thread-safe version of Destroy()
124    * Note: Do not call this from an overloaded delete operator, as this will already have called the objects destructor.
125    *
126    * @param object Pointer to the object to delete
127    */
128   void DestroyThreadSafe(T* object)
129   {
130     object->~T();
131     mPool->FreeThreadSafe(object);
132   }
133
134   /**
135    * @brief Reset the memory pool, unloading all block memory previously allocated
136    */
137   void ResetMemoryPool()
138   {
139     delete mPool;
140
141     mPool = new FixedSizeMemoryPool(TypeSizeWithAlignment<T>::size, 32, 1024 * 1024, POOL_MAX_BLOCK_COUNT);
142   }
143
144   /**
145    * Get a pointer to the keyed item.
146    *
147    * Key must be valid.
148    * @param[in] key 32 bit value indexing block/entry
149    * @return ptr to the memory of item, or nullptr if key is invalid
150    *
151    * @note on 32 bit systems, there is zero overhead, key is a raw ptr,
152    * and this method will return it's argument.
153    */
154   T* GetPtrFromKey(FixedSizeMemoryPool::KeyType key)
155   {
156     return static_cast<T*>(mPool->GetPtrFromKey(key));
157   }
158
159   /**
160    * Get a key to the pointed at item
161    * @param[in] ptr Pointer to an item in the memory pool
162    * @return key of the item, or -1 if not found.
163    *
164    * @note on 32 bit systems, there is zero overhead, key is a raw ptr,
165    * and this method will return it's argument.
166    */
167   FixedSizeMemoryPool::KeyType GetKeyFromPtr(T* ptr)
168   {
169     return mPool->GetKeyFromPtr(ptr);
170   }
171
172   /**
173    * @brief Get the capacity of the memory pool
174    */
175   uint32_t GetCapacity() const
176   {
177     return mPool->GetCapacity();
178   }
179
180 private:
181   // Undefined
182   MemoryPoolObjectAllocator(const MemoryPoolObjectAllocator& memoryPoolObjectAllocator);
183
184   // Undefined
185   MemoryPoolObjectAllocator& operator=(const MemoryPoolObjectAllocator& memoryPoolObjectAllocator);
186
187 private:
188   FixedSizeMemoryPool* mPool; ///< Memory pool from which allocations are made
189 };
190
191 } // namespace Internal
192
193 } // namespace Dali
194
195 #endif // DALI_INTERNAL_MEMORY_POOL_OBJECT_ALLOCATOR_H