StackAllocatorBuilder.h 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. // Copyright (C) 2009-2022, 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/Atomic.h>
  7. #include <AnKi/Util/Common.h>
  8. namespace anki {
  9. /// @addtogroup util_memory
  10. /// @{
  11. /// This is a convenience class used to build stack memory allocators.
  12. /// @tparam TChunk This is the type of the internally allocated chunks. This should be having the following members:
  13. /// @code
  14. /// TChunk* m_nextChunk;
  15. /// Atomic<PtrSize> m_offsetInChunk;
  16. /// PtrSize m_chunkSize;
  17. /// @endcode
  18. /// @tparam TInterface This is the type of the interface that contains various info. Should have the following members:
  19. /// @code
  20. /// U32 getMaxAlignment();
  21. /// PtrSize getInitialChunkSize();
  22. /// F64 getNextChunkGrowScale();
  23. /// PtrSize getNextChunkGrowBias();
  24. /// Bool ignoreDeallocationErrors();
  25. /// Error allocateChunk(PtrSize size, TChunk*& out);
  26. /// void freeChunk(TChunk* out);
  27. /// void recycleChunk(TChunk& out);
  28. /// Atomic<U32>* getAllocationCount(); // It's optional
  29. /// @endcode
  30. /// @tparam TLock This an optional lock. Can be a Mutex or SpinLock or some dummy class.
  31. template<typename TChunk, typename TInterface, typename TLock>
  32. class StackAllocatorBuilder
  33. {
  34. public:
  35. /// Create.
  36. StackAllocatorBuilder() = default;
  37. /// Destroy.
  38. ~StackAllocatorBuilder();
  39. /// Allocate memory.
  40. /// @param size The size to allocate.
  41. /// @param alignment The alignment of the returned address.
  42. /// @param[out] chunk The chunk that the memory belongs to.
  43. /// @param[out] offset The offset inside the chunk.
  44. /// @note This is thread safe with itself.
  45. Error allocate(PtrSize size, PtrSize alignment, TChunk*& chunk, PtrSize& offset);
  46. /// Free memory. Doesn't do something special, only some bookkeeping.
  47. void free();
  48. /// Reset all the memory chunks.
  49. /// @note Not thread safe. Don't call it while calling allocate.
  50. void reset();
  51. /// Access the interface.
  52. /// @note Not thread safe. Don't call it while calling allocate.
  53. TInterface& getInterface()
  54. {
  55. return m_interface;
  56. }
  57. /// Access the interface.
  58. /// @note Not thread safe. Don't call it while calling allocate.
  59. const TInterface& getInterface() const
  60. {
  61. return m_interface;
  62. }
  63. /// Get the total memory comsumed by the chunks.
  64. /// @note Not thread safe. Don't call it while calling allocate.
  65. PtrSize getMemoryCapacity() const
  66. {
  67. return m_memoryCapacity;
  68. }
  69. private:
  70. /// The current chunk. Chose the more strict memory order to avoid compiler re-ordering of instructions
  71. Atomic<TChunk*, AtomicMemoryOrder::SEQ_CST> m_crntChunk = {nullptr};
  72. /// The beginning of the chunk list.
  73. TChunk* m_chunksListHead = nullptr;
  74. /// The memory allocated by all chunks.
  75. PtrSize m_memoryCapacity = 0;
  76. /// Number of chunks allocated.
  77. U32 m_chunkCount = 0;
  78. /// The interface as decribed in the class docs.
  79. TInterface m_interface;
  80. /// An optional lock.
  81. TLock m_lock;
  82. };
  83. /// @}
  84. } // end namespace anki
  85. #include <AnKi/Util/StackAllocatorBuilder.inl.h>