ObjectAllocator.h 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. // Copyright (C) 2009-2021, Panagiotis Christopoulos Charitos and contributors.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. #pragma once
  6. #include <AnKi/Util/Array.h>
  7. namespace anki {
  8. /// @addtogroup util_containers
  9. /// @{
  10. /// A simple allocator for objects of similar types.
  11. /// @tparam T_OBJECT_SIZE The maximum size of the objects.
  12. /// @tparam T_OBJECT_ALIGNMENT The maximum alignment of the objects.
  13. /// @tparam T_OBJECTS_PER_CHUNK How much memory (in objects) will be allocated at once.
  14. /// @tparam TIndexType If T_OBJECTS_PER_CHUNK>0xFF make it U16. If T_OBJECTS_PER_CHUNK>0xFFFF make it U32.
  15. template<PtrSize T_OBJECT_SIZE, U32 T_OBJECT_ALIGNMENT, U32 T_OBJECTS_PER_CHUNK = 64, typename TIndexType = U8>
  16. class ObjectAllocator
  17. {
  18. public:
  19. static constexpr PtrSize OBJECT_SIZE = T_OBJECT_SIZE;
  20. static constexpr U32 OBJECT_ALIGNMENT = T_OBJECT_ALIGNMENT;
  21. static constexpr U32 OBJECTS_PER_CHUNK = T_OBJECTS_PER_CHUNK;
  22. ObjectAllocator()
  23. {
  24. }
  25. ~ObjectAllocator()
  26. {
  27. ANKI_ASSERT(m_chunksHead == nullptr && m_chunksTail == nullptr && "Forgot to deallocate");
  28. }
  29. /// Allocate and construct a new object instance.
  30. /// @note Not thread-safe.
  31. template<typename T, typename TAlloc, typename... TArgs>
  32. T* newInstance(TAlloc& alloc, TArgs&&... args);
  33. /// Delete an object.
  34. /// @note Not thread-safe.
  35. template<typename T, typename TAlloc>
  36. void deleteInstance(TAlloc& alloc, T* obj);
  37. private:
  38. /// Storage with equal properties as the object.
  39. struct alignas(OBJECT_ALIGNMENT) Object
  40. {
  41. U8 m_storage[OBJECT_SIZE];
  42. };
  43. /// A single allocation.
  44. class Chunk
  45. {
  46. public:
  47. Array<Object, OBJECTS_PER_CHUNK> m_objects;
  48. Array<U32, OBJECTS_PER_CHUNK> m_unusedStack;
  49. U32 m_unusedCount;
  50. Chunk* m_next = nullptr;
  51. Chunk* m_prev = nullptr;
  52. };
  53. Chunk* m_chunksHead = nullptr;
  54. Chunk* m_chunksTail = nullptr;
  55. };
  56. /// Convenience wrapper for ObjectAllocator.
  57. template<typename T, U32 T_OBJECTS_PER_CHUNK = 64, typename TIndexType = U8>
  58. class ObjectAllocatorSameType : public ObjectAllocator<sizeof(T), U32(alignof(T)), T_OBJECTS_PER_CHUNK, TIndexType>
  59. {
  60. public:
  61. using Base = ObjectAllocator<sizeof(T), U32(alignof(T)), T_OBJECTS_PER_CHUNK, TIndexType>;
  62. /// Allocate and construct a new object instance.
  63. /// @note Not thread-safe.
  64. template<typename TAlloc, typename... TArgs>
  65. T* newInstance(TAlloc& alloc, TArgs&&... args)
  66. {
  67. return Base::template newInstance<T>(alloc, std::forward(args)...);
  68. }
  69. /// Delete an object.
  70. /// @note Not thread-safe.
  71. template<typename TAlloc>
  72. void deleteInstance(TAlloc& alloc, T* obj)
  73. {
  74. Base::deleteInstance(alloc, obj);
  75. }
  76. };
  77. /// @}
  78. } // end namespace anki
  79. #include <AnKi/Util/ObjectAllocator.inl.h>