Allocator.cpp 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. #include "anki/util/Allocator.h"
  2. #include <iostream>
  3. namespace anki {
  4. //==============================================================================
  5. // Allocator =
  6. //==============================================================================
  7. namespace detail {
  8. //==============================================================================
  9. PtrSize AllocatorStatic::allocatedSize = 0;
  10. //==============================================================================
  11. void AllocatorStatic::dump()
  12. {
  13. #if ANKI_DEBUG_ALLOCATORS
  14. if(allocatedSize > 0)
  15. {
  16. std::cerr << "You have memory leak of " << allocatedSize
  17. << " bytes" << std::endl;
  18. }
  19. #endif
  20. }
  21. //==============================================================================
  22. void* AllocatorStatic::malloc(PtrSize size)
  23. {
  24. void* out = std::malloc(size);
  25. if(out != nullptr)
  26. {
  27. // Zero the buffer
  28. memset(out, 0, size);
  29. #if ANKI_DEBUG_ALLOCATORS
  30. allocatedSize += size;
  31. #endif
  32. }
  33. else
  34. {
  35. throw ANKI_EXCEPTION("malloc() failed");
  36. }
  37. return out;
  38. }
  39. //==============================================================================
  40. void AllocatorStatic::free(void* p, PtrSize size)
  41. {
  42. std::free(p);
  43. if(p)
  44. {
  45. #if ANKI_DEBUG_ALLOCATORS
  46. allocatedSize -= size;
  47. #else
  48. (void)size; // Make static the analyzer happy
  49. #endif
  50. }
  51. }
  52. } // end namespace detail
  53. //==============================================================================
  54. // StackAllocatorInternal =
  55. //==============================================================================
  56. namespace detail {
  57. //==============================================================================
  58. void StackAllocatorInternal::init(const PtrSize size)
  59. {
  60. mpool = new detail::MemoryPool;
  61. if(mpool != nullptr)
  62. {
  63. mpool->memory = (U8*)::malloc(size);
  64. if(mpool->memory != nullptr)
  65. {
  66. mpool->size = size;
  67. mpool->ptr = mpool->memory;
  68. // Memory pool's refcounter is 1
  69. #if ANKI_PRINT_ALLOCATOR_MESSAGES
  70. std::cout << "New MemoryPool created: Address: " << mpool
  71. << ", size: " << size
  72. << ", pool address: " << mpool->memory << std::endl;
  73. #endif
  74. return;
  75. }
  76. }
  77. // Errors happened
  78. if(mpool->memory)
  79. {
  80. ::free(mpool->memory);
  81. }
  82. if(mpool)
  83. {
  84. delete mpool;
  85. }
  86. std::cerr << "Stack allocator constuctor failed. I will cannot "
  87. "throw but I have to exit" << std::endl;
  88. exit(0);
  89. }
  90. //==============================================================================
  91. void StackAllocatorInternal::deinit()
  92. {
  93. int refCounter = mpool->refCounter.fetch_sub(1);
  94. if(mpool && (refCounter - 1) == 0)
  95. {
  96. #if ANKI_PRINT_ALLOCATOR_MESSAGES
  97. std::cout << "Deleting MemoryPool " << mpool << std::endl;
  98. #endif
  99. // It is safe to delete the memory pool
  100. ANKI_ASSERT(mpool->refCounter == 0);
  101. ::free(mpool->memory);
  102. delete mpool;
  103. }
  104. }
  105. } // end namespace detail
  106. } // end namespace anki