BsGlobalFrameAlloc.h 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #pragma once
  4. #include "BsStdHeaders.h"
  5. #include "BsThreadDefines.h"
  6. namespace bs
  7. {
  8. /** @addtogroup Memory
  9. * @{
  10. */
  11. class FrameAlloc;
  12. /**
  13. * Returns a global, application wide FrameAlloc. Each thread gets its own frame allocator.
  14. *
  15. * @note Thread safe.
  16. */
  17. BS_UTILITY_EXPORT FrameAlloc& gFrameAlloc();
  18. /**
  19. * Allocates some memory using the global frame allocator.
  20. *
  21. * @param[in] numBytes Number of bytes to allocate.
  22. */
  23. BS_UTILITY_EXPORT UINT8* bs_frame_alloc(UINT32 numBytes);
  24. /**
  25. * Allocates the specified number of bytes aligned to the provided boundary, using the global frame allocator. Boundary
  26. * is in bytes and must be a power of two.
  27. */
  28. BS_UTILITY_EXPORT UINT8* bs_frame_alloc_aligned(UINT32 count, UINT32 align);
  29. /**
  30. * Deallocates memory allocated with the global frame allocator.
  31. *
  32. * @note Must be called on the same thread the memory was allocated on.
  33. */
  34. BS_UTILITY_EXPORT void bs_frame_free(void* data);
  35. /**
  36. * Frees memory previously allocated with bs_frame_alloc_aligned().
  37. *
  38. * @note Must be called on the same thread the memory was allocated on.
  39. */
  40. BS_UTILITY_EXPORT void bs_frame_free_aligned(void* data);
  41. /**
  42. * Allocates enough memory to hold the object of specified type using the global frame allocator, but does not
  43. * construct the object.
  44. */
  45. template<class T>
  46. T* bs_frame_alloc()
  47. {
  48. return (T*)bs_frame_alloc(sizeof(T));
  49. }
  50. /**
  51. * Allocates enough memory to hold N objects of specified type using the global frame allocator, but does not
  52. * construct the object.
  53. */
  54. template<class T>
  55. T* bs_frame_alloc(UINT32 count)
  56. {
  57. return (T*)bs_frame_alloc(sizeof(T) * count);
  58. }
  59. /**
  60. * Allocates enough memory to hold the object(s) of specified type using the global frame allocator,
  61. * and constructs them.
  62. */
  63. template<class T>
  64. T* bs_frame_new(UINT32 count = 0)
  65. {
  66. T* data = bs_frame_alloc<T>(count);
  67. for(unsigned int i = 0; i < count; i++)
  68. new ((void*)&data[i]) T;
  69. return data;
  70. }
  71. /**
  72. * Allocates enough memory to hold the object(s) of specified type using the global frame allocator, and constructs them.
  73. */
  74. template<class T, class... Args>
  75. T* bs_frame_new(Args &&...args, UINT32 count = 0)
  76. {
  77. T* data = bs_frame_alloc<T>(count);
  78. for(unsigned int i = 0; i < count; i++)
  79. new ((void*)&data[i]) T(std::forward<Args>(args)...);
  80. return data;
  81. }
  82. /**
  83. * Destructs and deallocates an object allocated with the global frame allocator.
  84. *
  85. * @note Must be called on the same thread the memory was allocated on.
  86. */
  87. template<class T>
  88. void bs_frame_delete(T* data)
  89. {
  90. data->~T();
  91. bs_frame_free((UINT8*)data);
  92. }
  93. /**
  94. * Destructs and deallocates an array of objects allocated with the global frame allocator.
  95. *
  96. * @note Must be called on the same thread the memory was allocated on.
  97. */
  98. template<class T>
  99. void bs_frame_delete(T* data, UINT32 count)
  100. {
  101. for(unsigned int i = 0; i < count; i++)
  102. data[i].~T();
  103. bs_frame_free((UINT8*)data);
  104. }
  105. /** @copydoc FrameAlloc::markFrame */
  106. inline BS_UTILITY_EXPORT void bs_frame_mark();
  107. /** @copydoc FrameAlloc::clear */
  108. inline BS_UTILITY_EXPORT void bs_frame_clear();
  109. /** String allocated with a frame allocator. */
  110. typedef std::basic_string<char, std::char_traits<char>, StdAlloc<char, FrameAlloc>> FrameString;
  111. /** WString allocated with a frame allocator. */
  112. typedef std::basic_string<wchar_t, std::char_traits<wchar_t>, StdAlloc<wchar_t, FrameAlloc>> FrameWString;
  113. /** Vector allocated with a frame allocator. */
  114. template <typename T, typename A = StdAlloc<T, FrameAlloc>>
  115. using FrameVector = std::vector < T, A > ;
  116. /** Stack allocated with a frame allocator. */
  117. template <typename T, typename A = StdAlloc<T, FrameAlloc>>
  118. using FrameStack = std::stack < T, std::deque<T, A> > ;
  119. /** Queue allocated with a frame allocator. */
  120. template <typename T, typename A = StdAlloc<T, FrameAlloc>>
  121. using FrameQueue = std::queue<T, std::deque<T, A>>;
  122. /** Set allocated with a frame allocator. */
  123. template <typename T, typename P = std::less<T>, typename A = StdAlloc<T, FrameAlloc>>
  124. using FrameSet = std::set < T, P, A > ;
  125. /** Map allocated with a frame allocator. */
  126. template <typename K, typename V, typename P = std::less<K>, typename A = StdAlloc<std::pair<const K, V>, FrameAlloc>>
  127. using FrameMap = std::map < K, V, P, A >;
  128. /** UnorderedSet allocated with a frame allocator. */
  129. template <typename T, typename H = std::hash<T>, typename C = std::equal_to<T>, typename A = StdAlloc<T, FrameAlloc>>
  130. using FrameUnorderedSet = std::unordered_set < T, H, C, A >;
  131. /** UnorderedMap allocated with a frame allocator. */
  132. template <typename K, typename V, typename H = std::hash<K>, typename C = std::equal_to<K>, typename A = StdAlloc<std::pair<const K, V>, FrameAlloc>>
  133. using FrameUnorderedMap = std::unordered_map < K, V, H, C, A >;
  134. /** @} */
  135. /** @addtogroup Internal-Utility
  136. * @{
  137. */
  138. /** @addtogroup Memory-Internal
  139. * @{
  140. */
  141. extern BS_THREADLOCAL FrameAlloc* _GlobalFrameAlloc;
  142. /**
  143. * Specialized memory allocator implementations that allows use of a global frame allocator in normal
  144. * new/delete/free/dealloc operators.
  145. */
  146. template<>
  147. class MemoryAllocator<FrameAlloc> : public MemoryAllocatorBase
  148. {
  149. public:
  150. /** @copydoc MemoryAllocator::allocate */
  151. static void* allocate(size_t bytes)
  152. {
  153. return bs_frame_alloc((UINT32)bytes);
  154. }
  155. /** @copydoc MemoryAllocator::allocateAligned */
  156. static void* allocateAligned(size_t bytes, size_t alignment)
  157. {
  158. #if BS_PROFILING_ENABLED
  159. incAllocCount();
  160. #endif
  161. return bs_frame_alloc_aligned((UINT32)bytes, (UINT32)alignment);
  162. }
  163. /** @copydoc MemoryAllocator::allocateAligned16 */
  164. static void* allocateAligned16(size_t bytes)
  165. {
  166. #if BS_PROFILING_ENABLED
  167. incAllocCount();
  168. #endif
  169. return bs_frame_alloc_aligned((UINT32)bytes, 16);
  170. }
  171. /** @copydoc MemoryAllocator::free */
  172. static void free(void* ptr)
  173. {
  174. bs_frame_free(ptr);
  175. }
  176. /** @copydoc MemoryAllocator::freeAligned */
  177. static void freeAligned(void* ptr)
  178. {
  179. #if BS_PROFILING_ENABLED
  180. incFreeCount();
  181. #endif
  182. bs_frame_free_aligned(ptr);
  183. }
  184. /** @copydoc MemoryAllocator::freeAligned16 */
  185. static void freeAligned16(void* ptr)
  186. {
  187. #if BS_PROFILING_ENABLED
  188. incFreeCount();
  189. #endif
  190. bs_frame_free_aligned(ptr);
  191. }
  192. };
  193. /** @} */
  194. /** @} */
  195. }