StackAllocatorBuilder.h 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. // Copyright (C) 2009-present, 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. /// PtrSize getInitialChunkSize();
  21. /// F64 getNextChunkGrowScale();
  22. /// PtrSize getNextChunkGrowBias();
  23. /// PtrSize getMaxChunkSize();
  24. /// Bool ignoreDeallocationErrors();
  25. /// Error allocateChunk(PtrSize size, TChunk*& out);
  26. /// void freeChunk(TChunk* chunk);
  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. {
  40. destroy();
  41. }
  42. /// Manual destroy. The destructor calls that as well.
  43. /// @note It's not thread safe.
  44. void destroy();
  45. /// Allocate memory.
  46. /// @param size The size to allocate.
  47. /// @param alignment The alignment of the returned address. Can be anything, not only a power of two.
  48. /// @param[out] chunk The chunk that the memory belongs to.
  49. /// @param[out] offset The offset inside the chunk.
  50. /// @note This is thread safe with itself.
  51. Error allocate(PtrSize size, PtrSize alignment, TChunk*& chunk, PtrSize& offset);
  52. /// Free memory. Doesn't do something special, only some bookkeeping.
  53. void free();
  54. /// Reset all the memory chunks.
  55. /// @note Not thread safe. Don't call it while calling allocate.
  56. void reset();
  57. /// Access the interface.
  58. /// @note Not thread safe. Don't call it while calling allocate.
  59. TInterface& getInterface()
  60. {
  61. return m_interface;
  62. }
  63. /// Access the interface.
  64. /// @note Not thread safe. Don't call it while calling allocate.
  65. const TInterface& getInterface() const
  66. {
  67. return m_interface;
  68. }
  69. /// Get the total memory comsumed by the chunks.
  70. /// @note Not thread safe. Don't call it while calling allocate.
  71. PtrSize getMemoryCapacity() const
  72. {
  73. return m_memoryCapacity;
  74. }
  75. private:
  76. /// The current chunk. Chose the more strict memory order to avoid compiler re-ordering of instructions
  77. Atomic<TChunk*, AtomicMemoryOrder::kSeqCst> m_crntChunk = {nullptr};
  78. /// The beginning of the chunk list.
  79. TChunk* m_chunksListHead = nullptr;
  80. /// The memory allocated by all chunks.
  81. PtrSize m_memoryCapacity = 0;
  82. /// Number of chunks currently in use.
  83. U32 m_chunksInUse = 0;
  84. /// The interface as decribed in the class docs.
  85. TInterface m_interface;
  86. /// An optional lock.
  87. TLock m_lock;
  88. };
  89. /// @}
  90. } // end namespace anki
  91. #include <AnKi/Util/StackAllocatorBuilder.inl.h>