memory.cpp 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. /*
  2. * Copyright (c) 2012-2014 Daniele Bartolini and individual contributors.
  3. * License: https://github.com/taylor001/crown/blob/master/LICENSE
  4. */
  5. #include "memory.h"
  6. #include "allocator.h"
  7. #include "mutex.h"
  8. // void* operator new(size_t) throw (std::bad_alloc)
  9. // {
  10. // CE_ASSERT(false, "operator new forbidden");
  11. // return NULL;
  12. // }
  13. // void* operator new[](size_t) throw (std::bad_alloc)
  14. // {
  15. // CE_ASSERT(false, "operator new[] forbidden");
  16. // return NULL;
  17. // }
  18. // void operator delete(void*) throw ()
  19. // {
  20. // CE_ASSERT(false, "operator delete forbidden");
  21. // }
  22. // void operator delete[](void*) throw ()
  23. // {
  24. // CE_ASSERT(false, "operator delete[] forbidden");
  25. // }
  26. namespace crown
  27. {
  28. namespace memory
  29. {
  30. /// Allocator based on C malloc().
  31. class HeapAllocator : public Allocator
  32. {
  33. public:
  34. HeapAllocator()
  35. : _allocated_size(0)
  36. , _allocation_count(0)
  37. {
  38. }
  39. ~HeapAllocator()
  40. {
  41. CE_ASSERT(_allocation_count == 0 && allocated_size() == 0,
  42. "Missing %d deallocations causing a leak of %ld bytes", _allocation_count, allocated_size());
  43. }
  44. /// @copydoc Allocator::allocate()
  45. void* allocate(size_t size, size_t align = Allocator::DEFAULT_ALIGN)
  46. {
  47. ScopedMutex sm(_mutex);
  48. size_t actual_size = actual_allocation_size(size, align);
  49. Header* h = (Header*)malloc(actual_size);
  50. h->size = actual_size;
  51. void* data = memory::align_top(h + 1, align);
  52. pad(h, data);
  53. _allocated_size += actual_size;
  54. _allocation_count++;
  55. return data;
  56. }
  57. /// @copydoc Allocator::deallocate()
  58. void deallocate(void* data)
  59. {
  60. ScopedMutex sm(_mutex);
  61. if (!data)
  62. return;
  63. Header* h = header(data);
  64. _allocated_size -= h->size;
  65. _allocation_count--;
  66. free(h);
  67. }
  68. /// @copydoc Allocator::allocated_size()
  69. size_t allocated_size()
  70. {
  71. ScopedMutex sm(_mutex);
  72. return _allocated_size;
  73. }
  74. /// Returns the size in bytes of the block of memory pointed by @a data
  75. size_t get_size(void* data)
  76. {
  77. ScopedMutex sm(_mutex);
  78. Header* h = header(data);
  79. return h->size;
  80. }
  81. private:
  82. // Holds the number of bytes of an allocation
  83. struct Header
  84. {
  85. uint32_t size;
  86. };
  87. size_t actual_allocation_size(size_t size, size_t align)
  88. {
  89. return size + align + sizeof(Header);
  90. }
  91. Header* header(void* data)
  92. {
  93. uint32_t* ptr = (uint32_t*)data;
  94. ptr--;
  95. while (*ptr == memory::PADDING_VALUE)
  96. {
  97. ptr--;
  98. }
  99. return (Header*)ptr;
  100. }
  101. void* data(Header* header, size_t align)
  102. {
  103. return memory::align_top(header + 1, align);
  104. }
  105. void pad(Header* header, void* data)
  106. {
  107. uint32_t* p = (uint32_t*)(header + 1);
  108. while (p != data)
  109. {
  110. *p = memory::PADDING_VALUE;
  111. p++;
  112. }
  113. }
  114. private:
  115. Mutex _mutex;
  116. size_t _allocated_size;
  117. uint32_t _allocation_count;
  118. };
  119. } // namespace memory
  120. namespace memory_globals
  121. {
  122. using namespace memory;
  123. // Create default allocators
  124. char _buffer[1024];
  125. HeapAllocator* _default_allocator = NULL;
  126. void init()
  127. {
  128. _default_allocator = new (_buffer) HeapAllocator();
  129. }
  130. void shutdown()
  131. {
  132. _default_allocator->~HeapAllocator();
  133. }
  134. } // namespace memory_globals
  135. Allocator& default_allocator()
  136. {
  137. return *memory_globals::_default_allocator;
  138. }
  139. } // namespace crown