BsFrameAlloc.h 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. #pragma once
  2. #include "BsPrerequisitesUtil.h"
  3. namespace BansheeEngine
  4. {
  5. /**
  6. * @brief Frame allocator. Performs very fast allocations but can only free all of its memory at once.
  7. * Perfect for allocations that last just a single frame.
  8. *
  9. * @note Not thread safe with an exception. "alloc" and "clear" methods need to be called from the same thread.
  10. * "dealloc" is thread safe and can be called from any thread.
  11. */
  12. class BS_UTILITY_EXPORT FrameAlloc
  13. {
  14. private:
  15. class MemBlock
  16. {
  17. public:
  18. MemBlock(UINT32 size);
  19. ~MemBlock();
  20. UINT8* alloc(UINT8 amount);
  21. void clear();
  22. UINT8* mData;
  23. UINT32 mFreePtr;
  24. UINT32 mSize;
  25. };
  26. public:
  27. FrameAlloc(UINT32 blockSize = 1024 * 1024);
  28. ~FrameAlloc();
  29. /**
  30. * @brief Allocates a new block of memory of the specified size.
  31. *
  32. * @param amount Amount of memory to allocate, in bytes.
  33. *
  34. * @note Not thread safe.
  35. */
  36. UINT8* alloc(UINT32 amount);
  37. /**
  38. * @brief Deallocates a previously allocated block of memory.
  39. *
  40. * @note No deallocation is actually done here. This method is only used for debug purposes
  41. * so it is easier to track down memory leaks and corruption.
  42. *
  43. * Thread safe.
  44. */
  45. void dealloc(UINT8* data);
  46. /**
  47. * @brief Deallocates all allocated memory.
  48. *
  49. * @note Not thread safe.
  50. */
  51. void clear();
  52. private:
  53. UINT32 mBlockSize;
  54. Vector<MemBlock*> mBlocks;
  55. MemBlock* mFreeBlock;
  56. std::atomic<UINT32> mTotalAllocBytes;
  57. MemBlock* allocBlock(UINT32 wantedSize);
  58. void deallocBlock(MemBlock* block);
  59. };
  60. /**
  61. * @brief Allocator for the standard library that internally uses a
  62. * frame allocator.
  63. */
  64. template <class T>
  65. class StdFrameAlloc
  66. {
  67. public:
  68. // Type definitions
  69. typedef T value_type;
  70. typedef T* pointer;
  71. typedef const T* const_pointer;
  72. typedef T& reference;
  73. typedef const T& const_reference;
  74. typedef std::size_t size_type;
  75. typedef std::ptrdiff_t difference_type;
  76. /**
  77. * @brief Rebind allocator to type U
  78. */
  79. template <class U>
  80. struct rebind
  81. {
  82. typedef StdFrameAlloc<U> other;
  83. };
  84. StdFrameAlloc() throw()
  85. :mFrameAlloc(nullptr)
  86. { }
  87. StdFrameAlloc(FrameAlloc* frameAlloc) throw()
  88. :mFrameAlloc(frameAlloc)
  89. { }
  90. StdFrameAlloc(const StdFrameAlloc&) throw()
  91. { }
  92. template <class U>
  93. StdFrameAlloc(const StdFrameAlloc<U>&) throw()
  94. { }
  95. ~StdFrameAlloc() throw()
  96. { }
  97. /**
  98. * @brief Return address of value.
  99. */
  100. pointer address(reference value) const
  101. {
  102. return &value;
  103. }
  104. /**
  105. * @brief Return address of value.
  106. */
  107. const_pointer address(const_reference value) const
  108. {
  109. return &value;
  110. }
  111. /**
  112. * @brief Return maximum number of elements that can be allocated.
  113. */
  114. size_type max_size() const throw()
  115. {
  116. return std::numeric_limits<std::size_t>::max() / sizeof(T);
  117. }
  118. /**
  119. * @brief Allocate but don't initialize number elements of type T.
  120. */
  121. pointer allocate(size_type num, const void* = 0)
  122. {
  123. pointer ret = (pointer)(mFrameAlloc->alloc((UINT32)num*sizeof(T)));
  124. return ret;
  125. }
  126. /**
  127. * @brief Initialize elements of allocated storage p with value "value".
  128. */
  129. void construct(pointer p, const T& value)
  130. {
  131. new((void*)p)T(value);
  132. }
  133. /**
  134. * @brief Destroy elements of initialized storage p.
  135. */
  136. void destroy(pointer p)
  137. {
  138. p->~T();
  139. }
  140. /**
  141. * @brief Deallocate storage p of deleted elements.
  142. */
  143. void deallocate(pointer p, size_type num)
  144. {
  145. mFrameAlloc->dealloc((UINT8*)p);
  146. }
  147. private:
  148. FrameAlloc* mFrameAlloc;
  149. };
  150. /**
  151. * @brief Return that all specializations of this allocator are interchangeable.
  152. */
  153. template <class T1, class T2>
  154. bool operator== (const StdFrameAlloc<T1>&,
  155. const StdFrameAlloc<T2>&) throw() {
  156. return true;
  157. }
  158. /**
  159. * @brief Return that all specializations of this allocator are interchangeable.
  160. */
  161. template <class T1, class T2>
  162. bool operator!= (const StdFrameAlloc<T1>&,
  163. const StdFrameAlloc<T2>&) throw() {
  164. return false;
  165. }
  166. }